Node.js "Cannot find package" via Imports Map - Fix #-Aliases
Node resolves #-prefixed specifiers through the "imports" field in package.json (subpath imports / import maps). When that map has no entry for the specifier, or its target file is missing, resolution fails with "Cannot find package".
What this error means
An import like import x from "#utils" fails with Cannot find package '#utils' even though the file exists, because the "imports" map in package.json does not declare that key - or maps it to a path that is not built yet in CI.
node:internal/modules/esm/resolve:... Error [ERR_MODULE_NOT_FOUND]:
Cannot find package '#utils' imported from /app/src/app.mjsCommon causes
Missing "imports" entry for the specifier
A #-prefixed import only resolves if package.json has a matching key in "imports". A typo, a missing pattern (#*), or no "imports" field at all breaks it.
The mapped target does not exist in CI
The map points at a build output (e.g. ./dist/utils.js) that exists locally but has not been compiled in the CI step, so resolution lands on a missing file.
How to fix it
Declare the subpath in "imports"
Add the alias to the "imports" map. Internal aliases must start with #, and conditions/patterns must point at real files.
{
"imports": {
"#utils": "./src/utils.js",
"#lib/*": "./src/lib/*.js"
}
}Build before resolving mapped outputs
- If the target is compiled, run the build step before the step that imports it.
- Point dev-time imports at source and prod imports at
distvia"conditions"if needed. - Confirm the resolved path exists with
node --input-type=module -e "import('#utils')".
How to prevent it
- Keep every
#-import declared inpackage.json"imports". - Ensure mapped targets are built before steps that import them.
- Prefer subpath imports over deep relative paths so the map is the single source of truth.