Node.js cannot find the entry point specified in package.json because the 'main' field is either missing or points to a file that doesn't exist. This prevents the module from being loaded when imported or required.
The 'main' field in package.json defines the primary entry point to your module - the file that Node.js should load when someone imports or requires your package. When this field is missing or points to a non-existent file, Node.js cannot resolve the module and throws this error. By default, if the 'main' field is omitted, Node.js attempts to load 'index.js' from the package root. However, if you've specified a custom entry point that doesn't exist, or if the default index.js is also missing, the module resolution fails completely. This error commonly occurs after renaming or moving files, during build processes that generate entry files, or when publishing packages without including all necessary files in the distribution.
Check your package.json and confirm the file exists at the specified path:
{
"name": "my-package",
"main": "dist/index.js" // Check this file exists
}Navigate to your package directory and verify:
ls -la dist/index.js
# or on Windows
dir dist\index.jsIf the file doesn't exist, you need to either create it or update the 'main' field to point to the correct file.
If your package.json doesn't have a 'main' field, add it pointing to your entry file:
{
"name": "my-package",
"version": "1.0.0",
"main": "index.js" // Add this line
}Common entry point locations:
- "main": "index.js" - For packages with source in root
- "main": "dist/index.js" - For TypeScript/compiled packages
- "main": "lib/index.js" - Another common convention
- "main": "src/index.js" - For source-only packages
If using TypeScript or a build tool, make sure the entry file is generated:
For TypeScript, check your tsconfig.json:
{
"compilerOptions": {
"outDir": "./dist" // Must match 'main' path
}
}Run your build command:
npm run build
# or
tscVerify the output file exists:
ls -la dist/index.jsEnsure the entry file is included in your published package. Check the 'files' array in package.json:
{
"name": "my-package",
"main": "dist/index.js",
"files": [
"dist" // Include the directory containing main file
]
}Test locally before publishing:
npm pack
tar -tzf my-package-1.0.0.tgzThis shows exactly what files will be published. Verify your main entry file is included.
If you renamed or moved your entry file, update package.json to match:
Before:
{
"main": "index.js"
}After moving file to src/:
{
"main": "src/index.js"
}Remember: the path is relative to package.json, not an absolute path.
Before publishing, test that your package can be imported:
In your package directory:
npm linkIn a test project:
npm link my-packageTry importing it:
// test.js
const myPackage = require('my-package');
// or
import myPackage from 'my-package';Run the test:
node test.jsThis confirms the 'main' field resolves correctly.
Using the 'exports' field (Node.js 12.7+)
For modern packages, consider using the 'exports' field instead of or alongside 'main':
{
"main": "./dist/index.js", // Fallback for older Node versions
"exports": {
".": {
"import": "./dist/index.mjs", // ESM
"require": "./dist/index.js" // CommonJS
}
}
}The 'exports' field provides more control over what can be imported and supports conditional exports for different environments.
Module resolution order
When Node.js resolves a package, it checks in this order:
1. The 'exports' field (if present and Node.js version supports it)
2. The 'main' field
3. index.js in the package root
4. index.json in the package root
5. index.node in the package root
Dual package hazards
If publishing both CommonJS and ESM versions, be careful about dual package hazards where the same package is loaded twice. Use conditional exports properly to avoid this.
TypeScript considerations
For TypeScript packages, maintain separate 'main' (compiled JS) and 'types' (type definitions):
{
"main": "dist/index.js",
"types": "dist/index.d.ts"
}Never point 'main' directly to .ts files - always reference the compiled output.
Error: EMFILE: too many open files, watch
EMFILE: fs.watch() limit exceeded
Error: Middleware next() called multiple times (next() invoked twice)
Express middleware next() called multiple times
Error: Worker failed to initialize (worker startup error)
Worker failed to initialize in Node.js
Error: EMFILE: too many open files, open 'file.txt'
EMFILE: too many open files
Error: cluster.fork() failed (cannot create child process)
cluster.fork() failed - Cannot create child process