How to fix Re-exports require an export specifier in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025· 105 views

This TypeScript error occurs when you try to re-export everything from a module using 'export * from' syntax without specifying what to export. The fix involves using named exports, namespace exports, or adjusting your module structure to properly re-export the desired content.

Quick fix

Fixes TS1205

// WRONG - missing export specifier
export * from './utils';

// CORRECT - export everything as a namespace
export * as utils from './utils';

// CORRECT - export specific named exports
export { functionA, functionB } from './utils';

// CORRECT - export default
export { default } from './utils';

// CORRECT - export everything (valid in some contexts)
export * from './utils/*';  // Note: this exports from multiple files
  1. Fix invalid 'export * from' syntax
  2. Create proper barrel files with named exports
  3. Handle CommonJS to ES module migration
  4. Configure TypeScript for proper module resolution
typescript — error
// WRONG - missing export specifier
export * from './utils';
// CORRECT - export everything as a namespace
export * as utils from './utils';
// CORRECT - export specific named exports
export { functionA, functionB } from './utils';
// CORRECT - export default
export { default } from './utils';
// CORRECT - export everything (valid in some contexts)
export * from './utils/*'; // Note: this exports from multiple files
Re-exports require an export specifier

What this error means

The "Re-exports require an export specifier" error (TS1205) appears when TypeScript encounters invalid re-export syntax. Re-exports allow you to export items from another module as if they were defined in the current module, but they must follow specific syntax rules. In TypeScript/ES modules, you can re-export in several ways: 1. **Named re-exports**: `export { name } from './module'` 2. **Namespace re-exports**: `export * as namespace from './module'` 3. **Default re-exports**: `export { default } from './module'` The error typically occurs when you try to use `export * from './module'` without any specifier, which is invalid syntax. You need to either export specific named exports or use the namespace export syntax. This error is common when refactoring code, creating barrel files (index.ts files that export from multiple modules), or when migrating from CommonJS to ES modules.

Typical symptoms

  • Compilation fails with 'Re-exports require an export specifier' error
  • Error code TS1205 appears in compiler output
  • IDE shows red underlines on export statements
  • Build process fails when using barrel files or re-export patterns
  • Error occurs specifically on lines with 'export * from' syntax
  • Module bundlers (webpack, Vite) may also report the error

Common causes

  1. Using 'export * from' without any export specifier (invalid syntax)
  2. Attempting to re-export everything from a module without proper syntax
  3. Confusion between ES module re-export syntax and CommonJS patterns
  4. Missing or incorrect TypeScript configuration for module resolution
  5. Trying to create a barrel file with incorrect export syntax
  6. Mixing ES module and CommonJS syntax in the same project
  7. Using outdated TypeScript version that doesn't support certain re-export patterns

How to fix "Re-exports require an export specifier"

1Fix invalid 'export * from' syntax

The most common cause is using export * from without proper syntax. Here's how to fix it:

typescript
// WRONG - missing export specifier
export * from './utils';

// CORRECT - export everything as a namespace
export * as utils from './utils';

// CORRECT - export specific named exports
export { functionA, functionB } from './utils';

// CORRECT - export default
export { default } from './utils';

// CORRECT - export everything (valid in some contexts)
export * from './utils/*';  // Note: this exports from multiple files

If you want to export everything from a module, you have two options:
1. Use namespace export: export * as moduleName from './module'
2. Export specific items: export { item1, item2, default } from './module'

After fixing the syntax, compile again:

bash
npx tsc
# or
npm run build
2Create proper barrel files with named exports

Barrel files (index.ts files that export from multiple modules) need proper syntax:

typescript
// WRONG barrel file
export * from './button';
export * from './input';
export * from './form';

// CORRECT barrel file - export specific items
export { Button, ButtonProps } from './button';
export { Input, InputProps } from './input';
export { Form, FormProps } from './form';

// CORRECT barrel file - namespace exports
export * as Button from './button';
export * as Input from './input';
export * as Form from './form';

// CORRECT barrel file - mixed approach
export { Button, ButtonProps } from './button';
export * as Input from './input';
export { default as Form } from './form';

Best practices for barrel files:
- Export only what's needed (avoid export *)
- Use consistent patterns across your codebase
- Consider using export type for type-only exports
- Document what each barrel file exports

Example of a well-structured barrel file:

typescript
// src/components/index.ts
export { Button, type ButtonProps } from './Button';
export { Input, type InputProps } from './Input';
export { Card, type CardProps } from './Card';
export { default as Modal } from './Modal';
3Handle CommonJS to ES module migration

If you're migrating from CommonJS to ES modules, re-exports work differently:

typescript
// CommonJS style (WRONG in ES modules)
module.exports = require('./utils');

// ES module equivalent (CORRECT)
export * from './utils';  // Still needs fixing!
export * as utils from './utils';  // Better

// CommonJS re-export pattern
exports.foo = require('./foo').foo;
exports.bar = require('./bar').bar;

// ES module equivalent
export { foo } from './foo';
export { bar } from './bar';

// For default exports
const utils = require('./utils');
module.exports = utils;

// ES module equivalent
export { default } from './utils';
// or
import utils from './utils';
export default utils;

Update your package.json to specify module type:

json
{
  "type": "module"
}

And update tsconfig.json:

json
{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "node16"
  }
}
4Configure TypeScript for proper module resolution

Ensure your tsconfig.json supports the re-export patterns you're using:

json
{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "node16",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "resolveJsonModule": true,

    // For namespace exports
    "preserveSymlinks": true,

    // For better re-export support
    "verbatimModuleSyntax": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Key settings:
- module: Use ESNext for modern ES modules
- moduleResolution: node16 or bundler for proper ES module support
- allowSyntheticDefaultImports: Helps with default exports
- esModuleInterop: Improves compatibility with CommonJS modules
- verbatimModuleSyntax: Ensures imports/exports are preserved as written

After updating tsconfig.json, restart your TypeScript server:

bash
# In VS Code: Ctrl/Cmd + Shift + P, then "TypeScript: Restart TS Server"
5Use type-only exports when needed

If you're only exporting types, use type-only exports to avoid runtime issues:

typescript
// WRONG - exports both value and type
export { User, type UserProps } from './types';

// BETTER - separates type and value exports
export { User } from './types';
export type { UserProps } from './types';

// CORRECT - type-only re-export
export type { UserProps } from './types';

// For multiple type exports
export type { UserProps, PostProps, CommentProps } from './types';

// Namespace for types
export type * as Types from './types';

Type-only exports are removed during compilation, so they don't affect the runtime code. This is especially important for:

1. Library authors: Consumers only get the types they need
2. Tree-shaking: Bundlers can remove unused type exports
3. Circular dependencies: Type-only imports don't create runtime dependencies

Check if you need import type instead of regular imports:

typescript
// Regular import (includes runtime code)
import { User } from './types';

// Type-only import (removed during compilation)
import type { UserProps } from './types';
6Update TypeScript version and check compatibility

Some re-export patterns require newer TypeScript versions:

bash
# Check current TypeScript version
npx tsc --version

# Update TypeScript
npm install typescript@latest --save-dev

# Or update to a specific version
npm install typescript@5.0.0 --save-dev

Newer TypeScript versions support:
- export type * syntax (TypeScript 3.8+)
- export * as ns syntax (TypeScript 3.8+)
- Better ES module/CJS interop
- Improved error messages for re-exports

Check your package.json for compatibility:

json
{
  "devDependencies": {
    "typescript": "^5.0.0"
  },
  "engines": {
    "node": ">=16.0.0"
  }
}

After updating, clear any cached files:

bash
# Remove compiled files
rm -rf dist build

# Clear TypeScript cache
rm -rf node_modules/.cache

# Reinstall if needed
npm install

# Compile fresh
npx tsc --build --clean
npx tsc

Advanced notes

### Understanding Re-export Syntax Variations

TypeScript/JavaScript has several re-export patterns with different behaviors:

1. Named re-exports: export { a, b } from './module'
- Re-exports specific named exports
- Can rename: export { a as alpha, b as beta } from './module'
- Type-only: export type { T } from './module'

2. Namespace re-exports: export * as ns from './module' (TS 3.8+)
- Exports everything under a namespace
- Useful for organizing related exports
- Consumers import: import { ns } from './file'

3. Aggregating re-exports: export * from './module'
- Actually valid in some contexts!
- Exports all named exports (except default)
- Cannot be used at module top-level without specifier
- Works in specific patterns: export * from './folder/*'

4. Default re-exports: export { default } from './module'
- Re-exports the default export
- Alternative: import x from './module'; export default x;

### Barrel File Design Patterns

Well-designed barrel files improve developer experience:

typescript
// Pattern 1: Flat exports (simple)
export { Button } from './Button';
export { Input } from './Input';
export { Card } from './Card';

// Pattern 2: Namespaced (organized)
export * as Buttons from './buttons';
export * as Forms from './forms';
export * as Layout from './layout';

// Pattern 3: Mixed with utilities
export { Button, Input, Card } from './components';
export { formatDate, parseCurrency } from './utils';
export type { User, Product } from './types';

// Pattern 4: Lazy exports (for code splitting)
export { lazy } from 'react';
export const LazyButton = lazy(() => import('./Button'));

### Module Resolution and Path Aliases

When using path aliases in tsconfig.json, re-exports need special handling:

json
{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@components/*": ["components/*"],
      "@utils/*": ["utils/*"]
    }
  }
}

Re-exports with aliases:

typescript
// Works in TypeScript
export { Button } from '@components/Button';

// May need runtime resolution
// Use a bundler (webpack, Vite) or module-alias package

### Circular Dependencies and Re-exports

Re-exports can create circular dependencies. TypeScript handles these better than runtime:

typescript
// fileA.ts
export { b } from './fileB';  // Re-export from B

// fileB.ts
export { a } from './fileA';  // Re-export from A (circular!)

// Better: Use type-only imports/exports
export type { AType } from './fileA';

### Tooling Support

Different tools handle re-exports differently:

- Bundlers (webpack, Rollup): May tree-shake unused re-exports
- Test runners (Jest): May need moduleNameMapper for path aliases
- IDEs (VS Code): Use "Go to Definition" on re-exports to find source
- Linters (ESLint): import/no-useless-path-segments rule checks re-exports

### Debugging Re-export Issues

Use TypeScript's compiler hints:

bash
# Show module resolution
npx tsc --traceResolution

# Show all diagnostics
npx tsc --extendedDiagnostics

# Show import/export relationships
npx tsc --listFiles

Check what's actually being exported:

bash
# For Node.js modules
node -e "console.log(Object.keys(require('./dist/index.js')))"

# For ES modules (Node.js with --experimental-modules)
node --loader ts-node/esm ./test-imports.mjs

Frequently asked questions

What does "TS1205" mean?
The "Re-exports require an export specifier" error (TS1205) appears when TypeScript encounters invalid re-export syntax. Re-exports allow you to export items from another module as if they were defined in the current module, but they must follow specific syntax rules. In TypeScript/ES modules, you can re-export in several ways: 1.
How do I fix "TS1205"?
This TypeScript error occurs when you try to re-export everything from a module using 'export * from' syntax without specifying what to export. The fix involves using named exports, namespace exports, or adjusting your module structure to properly re-export the desired content.
What causes "TS1205"?
Using 'export * from' without any export specifier (invalid syntax) Attempting to re-export everything from a module without proper syntax Confusion between ES module re-export syntax and CommonJS patterns
Is the "TS1205" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading