swc-project/swc · error
swc does not support module expressions
Error message
swc does not support module expressions
What it means
Swcify in swc_estree_compat maps swc_estree_ast nodes onto swc_ecma_ast. ModuleExpression (the `module { ... }` inline-module proposal) has no SWC AST representation, so the impl declares `Output = Never` and panics. Conversion of an AST containing a module expression is impossible by design.
Source
Thrown at crates/swc_estree_compat/src/swcify/expr.rs:1146
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support record expressions")
}
}
impl Swcify for TupleExpression {
type Output = Never;
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support tuple expressions")
}
}
impl Swcify for ModuleExpression {
type Output = Never;
fn swcify(self, _: &Context) -> Self::Output {
panic!("swc does not support module expressions")
}
}
impl Swcify for TSAsExpression {
type Output = TsAsExpr;
fn swcify(self, ctx: &Context) -> Self::Output {
TsAsExpr {
span: ctx.span(&self.base),
expr: self.expression.swcify(ctx),
type_ann: self.type_annotation.swcify(ctx),
}
}
}
impl Swcify for TSTypeAssertion {
type Output = TsTypeAssertion;
View on GitHub (pinned to 5176682b65)
Solutions
- Turn off the module-blocks syntax plugin in the upstream ESTree parser
- Transform `module { ... }` code into a function/IIFE returning an importable object before conversion
- Parse with swc_ecma_parser directly, avoiding ESTree conversion of proposal syntax
- Pre-scan the ESTree JSON for `type: "ModuleExpression"` and surface a user-facing error
Example fix
// before
let m = module { export default 1; }; // module-blocks syntax
ast.swcify(&ctx); // panics: swc does not support module expressions
// after
let m = (() => ({ default: 1 }))(); // lowered to standard JS
ast.swcify(&ctx); // ok Defensive patterns
Strategy: type-guard
Validate before calling
let mut bad = Vec::new();
find_unsupported(&estree_json, &mut bad); // same walk as error 200
if bad.iter().any(|t| t == "ModuleExpression") {
return Err("module expressions (module { ... }) are not supported by swcify".into());
} Type guard
fn is_unsupported_estree_type(t: &str) -> bool {
matches!(
t,
"ModuleExpression" | "RecordExpression" | "TupleExpression"
| "PipelinePrimaryTopicReference" | "BindExpression" | "DoExpression"
)
} Try / catch
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
estree_expr.swcify(&ctx)
}));
if out.is_err() {
return Err("swcify cannot convert this ESTree tree (module expression present)".into());
} Prevention
- Leave module-blocks syntax plugins off for inputs destined for swcify
- Lower `module { ... }` to standard JS before conversion
- Validate ESTree JSON types against the unsupported-node blocklist
- Use swc_ecma_parser directly for source parsing
When it happens
Trigger: Calling `.swcify(ctx)` on an ESTree tree that includes a ModuleExpression node, i.e. code using `module { ... }` parsed with the module-blocks syntax plugin (babel syntax-plugin-module-blocks or similar) before being converted to SWC.
Common situations: Experimenting with module expressions in a babel pipeline that later hands the AST to SWC; shared parser configs enabling stage-1 syntax; codemod tools that accept arbitrary ESTree and convert it.
Related errors
- swc does not support `PipelinePrimaryTopicReference`
- swc does not support record expressions
- swc does not support tuple expressions
- failed to parse the value of BigIntLiteral
- failed to parse the value of DecimalLiteral
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/ebb41c4fbff361e5.
Report an issue: GitHub.