How to fix 'X' cannot be imported, as it is not exported from 'Y' in TypeScript
This TypeScript error occurs when you try to import something that hasn't been exported from the source module. The fix involves either adding the missing export declaration in the source file or using the correct import syntax (named vs default export).
Quick fix
Fixes TS2305
// In module Y.ts - CHECK THIS FILE
// ❌ WRONG - missing export keyword
const someValue = 42;
function helper() { return "help"; }
type MyType = { id: string };
// ✅ CORRECT - add export keyword
export const someValue = 42;
export function helper() { return "help"; }
export type MyType = { id: string };
// ✅ CORRECT - export at the end
const someValue = 42;
function helper() { return "help"; }
type MyType = { id: string };
export { someValue, helper, type MyType };- Check if the item is actually exported
- Fix named vs default import confusion
- Use correct type-only imports for types
- Check package.json exports restrictions
// In module Y.ts - CHECK THIS FILE// ❌ WRONG - missing export keywordconst someValue = 42;function helper() { return "help"; }type MyType = { id: string };// ✅ CORRECT - add export keywordexport const someValue = 42;export function helper() { return "help"; }export type MyType = { id: string };// ✅ CORRECT - export at the endconst someValue = 42;function helper() { return "help"; }type MyType = { id: string };export { someValue, helper, type MyType };'X' cannot be imported, as it is not exported from 'Y'
What this error means
The "'X' cannot be imported, as it is not exported from 'Y'" error (TS2305) appears when TypeScript's type checker detects that you're trying to import an identifier that isn't actually exported from the module you're importing from. TypeScript follows ES Module standards where every file containing top-level import or export statements is considered a module, and items must be explicitly exported to be imported elsewhere. This error prevents runtime errors by catching missing exports at compile time. Common scenarios include: 1. **Missing export keyword**: You declared a variable, function, or type but forgot to add `export` before it 2. **Wrong import syntax**: Using named import syntax `{ X }` for a default export, or vice versa 3. **Type-only imports**: Using `import type { X }` for a value that needs runtime access 4. **Module format confusion**: Mixing ES modules and CommonJS export patterns 5. **Package.json exports restrictions**: The package restricts which subpaths can be imported
Typical symptoms
- Compilation fails with 'X cannot be imported, as it is not exported from Y'
- IDE shows red underlines on import statements
- Error code TS2305 appears in compiler output
- Code works in plain JavaScript but fails in TypeScript
- Import works for some items from a module but not others
- Recently added exports show as unresolved in importing files
Common causes
- Missing export keyword on the identifier in the source module
- Using named import syntax for a default export (or vice versa)
- Trying to import a type as a value when it's only exported as a type
- The module doesn't export anything (file lacks export statements)
- Package.json exports field restricts which subpaths can be imported
- Case sensitivity mismatch between import and export names
- Using import type for runtime values that need to be executed
- Mixing ES modules and CommonJS in the same project without proper configuration
How to fix "'X' cannot be imported, as it is not exported from 'Y'"
First, verify that the item you're trying to import is actually exported from the source module:
// In module Y.ts - CHECK THIS FILE
// ❌ WRONG - missing export keyword
const someValue = 42;
function helper() { return "help"; }
type MyType = { id: string };
// ✅ CORRECT - add export keyword
export const someValue = 42;
export function helper() { return "help"; }
export type MyType = { id: string };
// ✅ CORRECT - export at the end
const someValue = 42;
function helper() { return "help"; }
type MyType = { id: string };
export { someValue, helper, type MyType };Open the source file (Y.ts in the error message) and look for the identifier. If it's not exported, add the export keyword before it or add it to an export list.
Ensure you're using the correct import syntax for how the item is exported:
// In module Y.ts
export default function mainFunction() { /* ... */ } // Default export
export const helper = () => { /* ... */ }; // Named export
// In importing file
// ❌ WRONG - using named import for default export
import { mainFunction } from "./Y";
// ✅ CORRECT - default import for default export
import mainFunction from "./Y";
// ✅ CORRECT - named import for named export
import { helper } from "./Y";
// ✅ CORRECT - mixed imports
import mainFunction, { helper } from "./Y";Check the source module to see if it uses export default (default export) or export const/function/class (named export).
If you're importing a type, ensure you're using the correct syntax:
// In module Y.ts
export type User = { id: string; name: string }; // Type export
export const createUser = () => ({ id: "1", name: "Alice" }); // Value export
// In importing file
// ✅ CORRECT - import type for types
import type { User } from "./Y";
// ✅ CORRECT - regular import for values
import { createUser } from "./Y";
// ✅ CORRECT - mixed import
import { createUser, type User } from "./Y";
// ❌ WRONG - trying to use type as value
import type { User } from "./Y";
const user: User = createUser(); // ✅ OK - type position
console.log(User); // ❌ Error - value positionRemember: import type imports can only be used in type positions, not as runtime values.
If importing from an npm package, check if the package.json has an "exports" field that restricts imports:
// In the package's package.json
{
"name": "some-package",
"exports": {
".": "./dist/index.js",
"./utils": "./dist/utils.js" // Only these paths are allowed
}
}// ✅ These will work
import { something } from "some-package";
import { util } from "some-package/utils";
// ❌ These may fail if not in exports field
import { internal } from "some-package/dist/internal.js";
import { secret } from "some-package/src/secret.ts";Solution: Only import from paths listed in the "exports" field, or contact the package maintainer to add the export.
TypeScript files without any import or export statements are treated as scripts, not modules. Add an export statement:
// In Y.ts - currently a script (no imports/exports)
const value = 42;
function helper() { return "help"; }
// ❌ This file won't allow imports because it's not a module
// ✅ Add any export to make it a module
export const value = 42;
function helper() { return "help"; }
// OR add an empty export
const value = 42;
function helper() { return "help"; }
export {}; // Makes file a module while not exporting anythingFiles need at least one top-level import or export to be considered ES modules.
Module imports are case-sensitive. Check for typos:
// In module Y.ts
export const myValue = 42;
export const MyComponent = () => <div>Hello</div>;
// In importing file
// ❌ WRONG - case mismatch
import { myvalue } from "./Y"; // Should be myValue
import { mycomponent } from "./Y"; // Should be MyComponent
// ❌ WRONG - typo
import { myVal } from "./Y"; // Should be myValue
// ✅ CORRECT - exact match
import { myValue, MyComponent } from "./Y";Use your IDE's autocomplete to avoid typos. Most editors will suggest available exports as you type.
Advanced notes
### Re-exporting (Barrel Files)
You can create barrel files that re-export from multiple modules:
// In index.ts (barrel file)
export { User } from "./models/User";
export { Product } from "./models/Product";
export { formatDate } from "./utils/date";
export { logger } from "./utils/logger";
// Now you can import from the barrel
import { User, formatDate } from "./index";### Namespace Imports for Type-Only Access
When using namespace imports, TypeScript-specific declarations are only accessible in type positions:
import * as mod from "./module.js";
// ❌ Error - trying to access type as value
console.log(mod.SomeType);
// ✅ OK - using type in type position
const x: mod.SomeType = { /* ... */ };
// ✅ Better - import type directly
import type { SomeType } from "./module.js";### Dynamic Imports
Dynamic imports (import()) have different error behavior:
// Static import - fails at compile time
import { missing } from "./module"; // ❌ TS2305
// Dynamic import - fails at runtime
const module = await import("./module");
module.missing(); // ❌ Runtime error, not compile error### CommonJS Interoperability
When importing from CommonJS modules in ES modules:
// CommonJS module (module.cjs or .js with module.exports)
module.exports = { hello: "world" };
// ES module import
// ❌ May fail - CommonJS doesn't have named exports
import { hello } from "./module.cjs";
// ✅ Use default import
import mod from "./module.cjs";
console.log(mod.hello);
// ✅ Or use require() in .cjs/.mjs files
const mod = require("./module.cjs");Configure esModuleInterop in tsconfig.json for better CommonJS compatibility.
### Checking What's Exported
Use TypeScript's language server to see available exports:
# In VS Code, hover over import to see available exports
import { /* hover here */ } from "./module";
# Or check with tsc
npx tsc --noEmit --listFiles | grep "module.ts"### Export Maps for Conditional Exports
Modern packages use export maps for different environments:
{
"exports": {
".": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"types": "./dist/types/index.d.ts"
},
"./utils": {
"import": "./dist/esm/utils.js",
"require": "./dist/cjs/utils.js"
}
}
}TypeScript will use the "types" entry when available.
Frequently asked questions
- What does "TS2305" mean?
- The "'X' cannot be imported, as it is not exported from 'Y'" error (TS2305) appears when TypeScript's type checker detects that you're trying to import an identifier that isn't actually exported from the module you're importing from. TypeScript follows ES Module standards where every file containing top-level import or export statements is considered a module, and items must be explicitly exported to be imported elsewhere. This error prevents runtime errors by catching missing exports at compile time.
- How do I fix "TS2305"?
- This TypeScript error occurs when you try to import something that hasn't been exported from the source module. The fix involves either adding the missing export declaration in the source file or using the correct import syntax (named vs default export).
- What causes "TS2305"?
- Missing export keyword on the identifier in the source module Using named import syntax for a default export (or vice versa) Trying to import a type as a value when it's only exported as a type
- Is the "TS2305" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚TypeScript Official Documentation
- 📖TypeScript Handbook - Modules(Official Docs)
- 📖TypeScript Handbook - Modules Reference(Official Docs)
- 📖TypeScript TSConfig - Module(Official Docs)
- 🐙