package.json exports Field Guide
The exports field is how modern npm packages support both CommonJS and ESM consumers. Use the generator above with the 'exports field' option to see how it works.
Basic Info
Module Config
{
"name": "my-nextjs-app",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "index.js",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^15.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"typescript": "^5.7.0",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"eslint": "^9.0.0",
"eslint-config-next": "^15.0.0"
},
"license": "MIT"
}4
Scripts
3
Deps
6
DevDeps
Press Ctrl+Enter to copy
Why exports matters
The exports field replaces main/module/types as the primary entry point mechanism. It provides encapsulation (consumers can only import exported paths), conditional resolution (different code for import vs require), and subpath exports (import 'pkg/utils'). Node.js 12.7+ and all modern bundlers support it.
Conditional exports for dual packages
A dual CJS/ESM package uses conditional exports to serve different files. 'import' condition serves ESM (.mjs or .js with type:module), 'require' serves CJS (.cjs or .js with type:commonjs), and 'types' serves TypeScript declarations. Build tools like tsup generate both formats automatically.
Common patterns
Single entry: { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs" } }. Subpath exports: { "./utils": { "import": "./dist/utils.mjs" } }. Wildcard: { "./*": "./dist/*.js" }. Always list 'types' first — TypeScript resolves top-to-bottom.
Migration from main/module
Keep main and module alongside exports for backwards compatibility with older Node.js versions and bundlers. exports takes priority when supported. Set types at the top level too for older TypeScript versions. Once you drop Node.js <12.7 support, exports alone is sufficient.
Frequently Asked Questions
Do I need both main and exports?
For maximum compatibility, yes. exports is used by Node.js 12.7+ and modern bundlers, while main is the fallback for older environments. If you only target modern Node.js (16+), exports alone is fine.
What order should conditions be in?
TypeScript types should come first, then import, then require, then default. Node.js resolves conditions top-to-bottom and uses the first match. Putting types first ensures TypeScript picks up declarations before runtime conditions.
Can I use exports to hide internal files?
Yes. Once you add an exports field, only the explicitly exported paths are accessible to consumers. Trying to import an unexported path throws ERR_PACKAGE_PATH_NOT_EXPORTED. This is a key advantage over main/module which exposes the entire package.
Related Generate Tools
MCP Config Builder
Build MCP configuration files visually for Claude Desktop, Cursor, VS Code, Windsurf, and Claude Code with 16 server templates
JWT Builder
Build and sign JSON Web Tokens with HMAC, RSA, and ECDSA algorithms — visual payload editor with expiration presets
tsconfig.json Builder
Build TypeScript tsconfig.json visually with framework presets, explanations for every option, and one-click download
Security Headers Generator
Generate HTTP security headers for Nginx, Apache, Vercel, Netlify, and Cloudflare with presets, security scoring, and multi-format output