{"record":{"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/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/node/plugins/terser.ts#L15-L51","documentation":"terserPlugin lazily resolves the 'terser' module from the project root, then from Vite's own install dir. If neither resolves, it throws because terser was made an optional peer dependency in Vite v3. The throw happens the first time build.minify === 'terser' triggers terser code path.","triggerScenarios":"Setting build.minify to 'terser' (or letting a config/plugin select it) without having terser in node_modules. loadTerserPath is called when the terser plugin initializes its worker.","commonSituations":"Pre-v3 projects upgrading to Vite 3+ where terser was previously bundled; CI caches that dropped the optional dep; or copy-pasted configs that set minify: 'terser' without installing it.","solutions":["Install terser: `npm install --save-dev terser`.","Or switch to the default esbuild minifier (build.minify: 'esbuild') which needs no extra install.","Verify the install lands in the project root node_modules so nodeResolveWithVite finds it.","Pin a terser version compatible with your Vite if a newer terser breaks output."],"exampleFix":"// before (vite.config.ts)\nbuild: { minify: 'terser' }\n// after — option A: install it\n// npm i -D terser\n// option B: use the built-in\nbuild: { minify: 'esbuild' }","handlingStrategy":"validation","validationCode":"import { createRequire } from 'node:module'\nfunction terserAvailable(root) {\n  const require = createRequire(`${root}/`)\n  try { require.resolve('terser'); return true } catch { return false }\n}\nif (config.build?.minify === 'terser' && !terserAvailable(process.cwd())) {\n  throw new Error('Install terser: npm i -D terser')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `npm i -D terser` whenever you set minify: 'terser'.","Prefer the default esbuild minifier unless you need terser-specific output.","Document the optional terser dependency in your project README."],"tags":["terser","minify","build","dependencies"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}