Skip to content

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:

js
SyntaxError: ambiguous indirect export: default

This indicates a conflict between:

  1. How a module exports its values
  2. 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:

js
// Named export (recommended)
export class FormValidator {}
js
// ❌ Incorrect: Using default import for named export
import FormValidator from './export.js' // "ambiguous indirect export" error
js
// ✅ 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:

js
// Default export
export default class {}
js
// ✅ 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:

js
export class FormValidator {}
js
// 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:

bash
Uncaught SyntaxError: The requested module does not provide an export named 'default'

Check package.json:

json
{
  "main": "./dist/index.js", // CommonJS if .cjs or requires module.exports
  "module": "./dist/index.mjs" // Explicit ESM export
}

Solutions:

  1. Update conflicting packages (npm update package-name)
  2. Use dynamic import workaround:
    js
    import * as axios from 'axios'
    const axiosInstance = axios.default // Access the default export
  3. Configure build tools to handle both formats (Vite does this automatically)

4. Handle TypeScript-Specific Cases ​

Type issues cause similar errors:

ts
export type TUser = { ... }
ts
// ❌ Incorrect
import { TUser } from '../models'
ts
// ✅ Use 'import type' for types
import type { TUser } from '../models'

5. Clear Cache During Development ​

Browser caches can retain outdated module references:

  1. Hard refresh browser (Ctrl/Cmd + Shift + R)
  2. Clear application data in DevTools
  3. Delete build artifacts (node_modules/.vite for Vite)

6. Fix File Extension Conflicts ​

In TypeScript projects, watch for duplicate files (.js/.ts):

  1. Ensure files don't exist in both .js and .ts formats
  2. Configure tooling to prioritize source extensions
  3. Check build output directories for stray files

7. Configure Monorepo Build Systems ​

For workspace packages, explicitly define formats:

json
{
  "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 ​

  1. Consistent exports: Use either named exports or default exports consistently
  2. TypeScript rules: Enable strict compiler options:
    json
    {
      "compilerOptions": {
        "isolatedModules": true,
        "preserveValueImports": true
      }
    }
  3. IDE verification: Use VSCode with ESLint integration
  4. Modern dependencies: Keep libraries updated (ESM compatibility)
  5. Clear separation: Avoid mixing .js and .ts files in source directories

DANGER

Never mix export types in the same module:

js
// ❌ 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.