vitejs/vite · error · Error
@vitejs/plugin-legacy does not support library mode.
Error message
@vitejs/plugin-legacy does not support library mode.
What it means
Thrown in configResolved when config.build.lib is truthy. plugin-legacy works by injecting <script> tags into HTML entry files and generating dual modern/legacy bundles tied to HTML entries. Library mode (build.lib) produces JS/CSS consumable by other bundlers, not HTML, so plugin-legacy's entire HTML-centric pipeline is incompatible. This is a hard, by-design limitation.
Source
Thrown at packages/plugin-legacy/src/index.ts:462
'es2015',
)
}
},
}
const legacyPostPlugin: Plugin = {
name: 'vite:legacy-post-process',
enforce: 'post',
apply: 'build',
renderStart(opts) {
// Empty the nested map for this output
outputToChunkFileNameToPolyfills.set(opts, null)
},
configResolved(_config) {
if (_config.build.lib) {
throw new Error('@vitejs/plugin-legacy does not support library mode.')
}
config = _config
const viteVersion = this.meta.viteVersion
supportsLegacyOxcMinification =
!!viteVersion &&
isVersionGte(viteVersion, legacyOxcMinificationSupportedVersion)
if (!supportsLegacyOxcMinification && config.build.minify === 'oxc') {
config.logger.warn(
colors.yellow(
`'oxc' minifier is not supported for legacy chunks by Vite version ${viteVersion}. ` +
`Please upgrade to Vite version ${legacyOxcMinificationSupportedVersion} or later.`,
),
)
}
if (isDebug) {View on GitHub (pinned to 89620f09af)
Solutions
- Remove @vitejs/plugin-legacy from plugins when using build.lib; instead configure build.target to legacy browsers directly (e.g., build.target: 'es2015').
- If you need both a library build and a legacy app build, use separate vite configs or conditional plugin inclusion: `...(isLibBuild ? [] : [legacy()])`.
- For library consumers needing legacy support, have consumers add plugin-legacy in their own app build rather than in the library build.
Example fix
// before
plugins: [legacy()],
build: { lib: { entry: 'src/lib.ts', name: 'MyLib' } }
// after
plugins: [],
build: {
lib: { entry: 'src/lib.ts', name: 'MyLib' },
target: 'es2015' // transpile for older browsers directly
} Defensive patterns
Strategy: validation
Validate before calling
// Check for library mode before adding the plugin
function getPlugins(config) {
const plugins = []
if (!config.build?.lib) {
plugins.push(legacy())
} else {
console.warn('plugin-legacy skipped: library mode is not supported')
}
return plugins
} Type guard
function isLibraryMode(config: UserConfig): boolean {
return !!(config.build?.lib)
}
// usage
const plugins = isLibraryMode(config)
? []
: [legacy()] Try / catch
try {
if (config.build?.lib) {
throw new Error('Cannot use plugin-legacy with build.lib')
}
} catch (e) {
console.warn(e.message, '— omitting plugin-legacy')
} Prevention
- Conditionally include plugin-legacy only for app builds, not library builds.
- Use separate vite config files for lib vs app builds (e.g., vite.config.lib.ts).
- Add a pre-build check script that validates config compatibility.
When it happens
Trigger: Configuring build.lib in vite.config (e.g., { build: { lib: { entry: 'src/lib.ts', formats: ['es'] } } }) while simultaneously including the legacy plugin in the plugins array.
Common situations: A developer building a component library or SDK wants to support legacy browsers and adds @vitejs/plugin-legacy, not realizing it only works for app builds (HTML entries). Common when migrating an app to a library build without removing the plugin.
Related errors
- { runtime: "${result.runtime}" } is not supported for assets
- `renderLegacyChunks` and `renderModernChunks` cannot be both
- Either "build.lib.entry" or the top-level "input" option is
- Option "build.lib.name" is required when output formats incl
- Entries in "build.rolldownOptions.output" must specify "name
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/134b22b3698f1efd.json.
Report an issue: GitHub.