emotion-js/emotion · error · Error
@emotion/babel-plugin-jsx-pragmatic: You must specify `modul
Error message
@emotion/babel-plugin-jsx-pragmatic: You must specify `module` and `import`
What it means
@emotion/babel-plugin-jsx-pragmatic requires both a `module` and an `import` option to know which module to import the JSX pragma from and which binding to use. The plugin's `pre` hook runs before compilation and throws if either option is missing. Without both, the plugin cannot rewrite JSX pragma comments.
Source
Thrown at packages/babel-plugin-jsx-pragmatic/src/index.ts:60
],
t.stringLiteral(state.opts.module)
)
const targetPath = findLast(path.get('body'), p => p.isImportDeclaration())
if (targetPath) {
targetPath.insertAfter([importDeclar])
} else {
// Apparently it's now safe to do this even if Program begins with directives.
path.unshiftContainer('body', importDeclar)
}
}
return {
inherits: syntaxJsx,
pre: function () {
if (!(this.opts.module && this.opts.import)) {
throw new Error(
'@emotion/babel-plugin-jsx-pragmatic: You must specify `module` and `import`'
)
}
},
visitor: {
Program: {
exit: function (path, state) {
if (!state.get('jsxDetected')) return
addPragmaImport(path, state)
}
},
JSXElement: function (path, state) {
state.set('jsxDetected', true)
},
JSXFragment: function (path, state) {
state.set('jsxDetected', true)
}View on GitHub (pinned to b882bcba85)
Solutions
- Add both `module` and `import` options to the plugin config, e.g. { module: '@emotion/react', import: 'jsx,css' }
- If you don't need pragma rewriting, remove the plugin from your Babel config entirely
- Verify options reach the plugin (a preset wrapper may strip them); log plugin options in a pre step to confirm
Example fix
// before
['@emotion/babel-plugin-jsx-pragmatic', { module: '@emotion/react' }]
// after
['@emotion/babel-plugin-jsx-pragmatic', { module: '@emotion/react', import: 'jsx,css' }] Defensive patterns
Strategy: validation
Validate before calling
const opts = { module: '@emotion/react', import: 'jsx,css' };
if (!opts.module || !opts.import) throw new Error('jsx-pragmatic needs both module and import'); Type guard
const hasPragmaOpts = (o) => typeof o === 'object' && o !== null && typeof o.module === 'string' && o.module.length > 0 && typeof o.import === 'string' && o.import.length > 0;
Prevention
- Always set both module and import options when adding the plugin
- Copy plugin config from official emotion docs, not blog posts
- Add a build-time smoke test that runs babel on a fixture file to catch config errors early
When it happens
Trigger: Using @emotion/babel-plugin-jsx-pragmatic in a Babel config with only one of `module` or `import` set, or with neither (e.g. `['@emotion/babel-plugin-jsx-pragmatic', { module: '@emotion/react/jsx-runtime' }]` missing `import`).
Common situations: Copy-pasting a partial plugin config from docs, migrating Babel configs where options were dropped, or configuring the plugin inside a preset that forwards incomplete options.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- You have specified that '${importSource}' re-exports '${reex
- The 'autoLabel' option must be undefined, or one of the foll
- The `runtime` option has been removed. If you want to config
- There is no transformer for the export '${exportName}' in '$
- You have to configure `key` for your cache. Please make sure
AI-assisted analysis of emotion-js/emotion@b882bcba85 (2026-09-02).
Data as JSON: /api/errors/ffbf9f807a229b69.
Report an issue: GitHub.