{"id":"8cfdfe3e462d549b","repo":"vitejs/vite","slug":"terser-not-found-since-vite-v3-terser-has-become","errorCode":null,"errorMessage":"terser not found. Since Vite v3, terser has become an optional dependency. You need to install it.","messagePattern":"terser not found\\. Since Vite v3, terser has become an optional dependency\\. You need to install it\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/plugins/terser.ts","lineNumber":33,"sourceCode":"   * when minifying files with terser.\n   *\n   * @default number of CPUs minus 1\n   */\n  maxWorkers?: number\n}\n\nlet terserPath: string | undefined\nfunction loadTerserPath(root: string) {\n  if (terserPath) return terserPath\n\n  // Try resolve from project root first, then the current vite installation path\n  const resolved =\n    nodeResolveWithVite('terser', undefined, { root }) ??\n    nodeResolveWithVite('terser', _dirname, { root })\n  if (resolved) return (terserPath = resolved)\n\n  // Error if we can't find the package\n  throw new Error(\n    'terser not found. Since Vite v3, terser has become an optional dependency. You need to install it.',\n  )\n}\n\nexport function terserPlugin(config: ResolvedConfig): Plugin {\n  const { maxWorkers, ...terserOptions } = config.build.terserOptions\n\n  const makeWorker = () =>\n    new WorkerWithFallback(\n      () =>\n        async (\n          terserPath: string,\n          code: string,\n          options: TerserMinifyOptions,\n        ) => {\n          const terser: typeof import('terser') = await import(terserPath)\n          try {\n            return (await terser.minify(code, options)) as TerserMinifyOutput","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/plugins/terser.ts#L15-L51","documentation":"Since Vite v3 terser is an optional peer dependency and is loaded lazily by the terser plugin at packages/vite/src/node/plugins/terser.ts:33. If build.minify === 'terser' (or @vitejs/plugin-legacy needs it) and neither the user's project root nor Vite's own install directory can resolve 'terser', loadTerserPath throws. esbuild (the default) does not need terser.","triggerScenarios":"Setting build.minify: 'terser' in vite.config; using @vitejs/plugin-legacy which forces the terser plugin via applyToEnvironment; running a build in a fresh install where terser was pruned as an optional dep; a corrupted node_modules where terser's package.json exists but its main file is missing.","commonSituations":"Copying a vite.config from a v2 project (terser was the default then) into a v3+ project without adding terser; CI caching node_modules with --omit=optional discarding terser; monorepo hoisting leaving terser only in a sibling workspace so it resolves from project root but not from Vite's install dir.","solutions":["Run `npm i -D terser` (or pnpm/yarn add -D terser) in the project root so nodeResolveWithVite finds it.","If you did not intend to use terser, set build.minify: 'esbuild' (the default) and remove any terserOptions config.","For CI with optional deps stripped, install with --include=optional or add terser as a direct devDependency so it is never pruned.","In a monorepo, ensure terser is installed in the same workspace that runs the build, or set Vite's resolve to look in the workspace root."],"exampleFix":"// before\nexport default defineConfig({ build: { minify: 'terser' } })\n\n// after (option A: keep terser)\n//   npm i -D terser\n// after (option B: drop terser)\nexport default defineConfig({ build: { minify: 'esbuild' } })","handlingStrategy":"validation","validationCode":"import { createRequire } from 'node:module'\nfunction terserAvailable(): boolean {\n  try { createRequire(process.cwd() + '/package.json').resolve('terser'); return true }\n  catch { return false }\n}\nif (config.build?.minify === 'terser' && !terserAvailable()) {\n  throw new Error('terser minify requested but terser is not installed; run `npm i -D terser`')\n}","typeGuard":"function hasTerser(cwd = process.cwd()): boolean {\n  try { createRequire(cwd + '/package.json').resolve('terser'); return true }\n  catch { return false }\n}","tryCatchPattern":null,"preventionTips":["Add terser to devDependencies whenever build.minify is 'terser' or @vitejs/plugin-legacy is used.","In CI install without stripping optional deps, or pin terser as a direct devDependency.","Default to minify: 'esbuild' unless you specifically need terser."],"tags":["build","terser","minify","optional-dependency","dependency"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}