Fixing 'SyntaxError: ambiguous indirect export: default' Error
The SyntaxError: ambiguous indirect export: default
error occurs when JavaScript modules encounter conflicts between expected exports. It typically happens when there's a mismatch between how modules are exported and how they're imported. Understanding module systems is key to resolving this issue.
Problem Statement
When importing custom classes or libraries into JavaScript projects (like Vue, React, or modern JavaScript applications), you may encounter:
SyntaxError: ambiguous indirect export: default
This indicates a conflict between:
- How a module exports its values
- How another module tries to import those values
The error frequently occurs in these situations:
- Mixing named exports with default imports
- Conflicting module formats (ESM vs CommonJS)
- Unintentional dual exports
- Importing TypeScript types incorrectly
- Using incorrect file extensions
Solutions to Resolve the Error
1. Correct Export/Import Matching Issues (Most Common)
The root cause is usually a mismatch between export and import styles:
// Named export (recommended)
export class FormValidator {}
// ❌ Incorrect: Using default import for named export
import FormValidator from './export.js' // "ambiguous indirect export" error
// ✅ Correct: Named import for named export
import { FormValidator } from './export.js'
// ✅ Also correct: Renaming with alias
import { FormValidator as Validation } from './export.js'
For default exports:
// Default export
export default class {}
// ✅ Correct: Default import for default export
import Validator from './export.js'
WARNING
Naming doesn't matter in default exports (except internally). The export name is irrelevant. Only default
matters.
2. Use Aliases for Renamed Imports
When renaming imports/exports, explicitly manage aliases:
export class FormValidator {}
// Original name
import { FormValidator } from './export.js'
// With alias
import { FormValidator as MyValidator } from './export.js'
// Default export alias
import Validator from '../../export.js'
3. Resolve Module Format Conflicts
Incompatibilities between ECMAScript Modules (ESM) and CommonJS cause errors:
Uncaught SyntaxError: The requested module does not provide an export named 'default'
Check package.json:
{
"main": "./dist/index.js", // CommonJS if .cjs or requires module.exports
"module": "./dist/index.mjs" // Explicit ESM export
}
Solutions:
- Update conflicting packages (
npm update package-name
) - Use dynamic import workaround:js
import * as axios from 'axios' const axiosInstance = axios.default // Access the default export
- Configure build tools to handle both formats (Vite does this automatically)
4. Handle TypeScript-Specific Cases
Type issues cause similar errors:
export type TUser = { ... }
// ❌ Incorrect
import { TUser } from '../models'
// ✅ Use 'import type' for types
import type { TUser } from '../models'
5. Clear Cache During Development
Browser caches can retain outdated module references:
- Hard refresh browser (Ctrl/Cmd + Shift + R)
- Clear application data in DevTools
- Delete build artifacts (
node_modules/.vite
for Vite)
6. Fix File Extension Conflicts
In TypeScript projects, watch for duplicate files (.js
/.ts
):
- Ensure files don't exist in both
.js
and.ts
formats - Configure tooling to prioritize source extensions
- Check build output directories for stray files
7. Configure Monorepo Build Systems
For workspace packages, explicitly define formats:
{
"name": "shared-ui",
"main": "./dist/index.js",
"module": "./dist/index.mjs", // ESM format
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsup src/index.tsx --format esm,cjs", // Build both formats
}
}
Preventing Future Occurrences
- Consistent exports: Use either named exports or default exports consistently
- TypeScript rules: Enable strict compiler options:json
{ "compilerOptions": { "isolatedModules": true, "preserveValueImports": true } }
- IDE verification: Use VSCode with ESLint integration
- Modern dependencies: Keep libraries updated (ESM compatibility)
- Clear separation: Avoid mixing
.js
and.ts
files in source directories
DANGER
Never mix export types in the same module:
// ❌ Ambiguous export: default AND named
export class Validator {}
export default Validator // Avoid this pattern!
The ambiguous indirect export
error stems from module system conflicts. By maintaining consistent exports/imports and handling TypeScript types properly, you can eliminate this error. Tools like Vite automatically handle most format issues — ensure dependencies and your own code follow consistent standards.