swc-project/swc · error
`env` and `jsc.target` cannot be used together
Error message
`env` and `jsc.target` cannot be used together
What it means
SWC rejects options that set both `env` (the babel-preset-env-style transform, configured with `env` / `env.targets`) and `jsc.target` (the single ES version for the core compiler). Both fields drive how far output is downgraded, so combining them makes the target ambiguous. The check runs during option building in crates/swc/src/config/mod.rs before any parsing happens, so it is purely a configuration error and the input file is never read.
Source
Thrown at crates/swc/src/config/mod.rs:332
let loose = loose.into_bool();
let preserve_all_comments = preserve_all_comments.into_bool();
let preserve_symlinks = preserve_symlinks.into_bool();
let keep_class_names = keep_class_names.into_bool();
let external_helpers = external_helpers.into_bool();
let mut assumptions = assumptions.unwrap_or_else(|| {
if loose {
Assumptions::all()
} else {
Assumptions::default()
}
});
let unresolved_mark = self.unresolved_mark.unwrap_or_default();
let top_level_mark = self.top_level_mark.unwrap_or_default();
if target.is_some() && cfg.env.is_some() {
bail!("`env` and `jsc.target` cannot be used together");
}
let es_version = target.unwrap_or_default();
let syntax = syntax.unwrap_or_default();
let (mut program, flow_strip_script_like_module) = parse(syntax, es_version, is_module)?;
let mut transform = transform.into_inner().unwrap_or_default();
#[cfg(feature = "react-compiler")]
if let Some(options) = react_compiler_options(transform.react_compiler.clone(), base) {
let fm = if program.span().is_dummy() {
cm.get_source_file(base)
} else {
cm.try_lookup_byte_offset(program.span().lo)
.ok()
.map(|source| source.sf)View on GitHub (pinned to 5176682b65)
Solutions
- Delete `jsc.target` from the .swcrc / options and express all target requirements under `env.targets`
- Or remove the `env` block entirely and keep only `jsc.target` when you don't need preset-env-style target matrices
- If the target came from a CLI flag like `--target es2017`, remove the `env` key from the .swcrc it gets merged with
- Print the fully merged options reaching swc to find which layer (framework, CLI, config file) injects the conflicting field
Example fix
// before (.swcrc)
{
"env": { "targets": "> 0.25%" },
"jsc": { "target": "es5", "parser": { "syntax": "typescript" } }
}
// after (.swcrc)
{
"env": { "targets": "> 0.25%" },
"jsc": { "parser": { "syntax": "typescript" } }
} Defensive patterns
Strategy: validation
Validate before calling
// TypeScript / @swc/core - run before transform
function assertNoTargetConflict(opts: { env?: unknown; jsc?: { target?: string } }) {
if (opts.env != null && opts.jsc?.target != null) {
throw new Error(
'swc: `env` and `jsc.target` cannot be used together; keep env.targets and drop jsc.target'
);
}
}
assertNoTargetConflict(options); // your swc options object Type guard
type SwcOptions = { env?: object; jsc?: { target?: string } };
const hasTargetConflict = (o: SwcOptions): o is SwcOptions & { env: object; jsc: { target: string } } =>
o.env != null && o.jsc?.target != null; Prevention
- Pick one target mechanism per project: env.targets for preset-env behavior, jsc.target otherwise
- When layering config (framework + .swcrc + CLI flags), log the final merged options in CI
- Add a unit test asserting your generated swc config never contains both keys
When it happens
Trigger: Calling Compiler::process_js_file / process_js_with_custom_pass, or @swc/core transform/transformFile, with options where both `env: { targets: ... }` and `jsc: { target: 'es5' }` are present; also merging a .swcrc that contains an `env` block with a CLI `--target` flag or framework-injected jsc.target.
Common situations: Translating a Babel config (preset-env) to swc's `env` and then also setting jsc.target 'for safety'; older swc versions tolerating both and failing after an upgrade; frameworks (Next.js, jest transformers, Vite plugins) injecting `env` while user config sets jsc.target.
Related errors
- Error occurred while loading config file at ${config}: ${e}
- unknown key: {k}
- {} is not a valid expression
- failed to parse jsx option {}: '{}' is not an expression
- determine_export_name({:?})
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/f4c1f8f6b37e05ab.
Report an issue: GitHub.