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.