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

  1. Delete `jsc.target` from the .swcrc / options and express all target requirements under `env.targets`
  2. Or remove the `env` block entirely and keep only `jsc.target` when you don't need preset-env-style target matrices
  3. If the target came from a CLI flag like `--target es2017`, remove the `env` key from the .swcrc it gets merged with
  4. 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

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


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/f4c1f8f6b37e05ab. Report an issue: GitHub.