Clear default entry point
Why it matters
A package whose default entry point exports nothing useful forces consumers to discover and import from internal paths — paths that encode your directory structure and break silently when you refactor. ISO 25010 interoperability fails when import { Thing } from 'your-package' returns undefined. This also breaks tree-shaking, IDE autocompletion, and any tool that introspects the package's public API via its declared entry point. The entry point is a contract; an empty or useless one is a broken contract.
Severity rationale
Critical because a misconfigured entry point means the primary import path resolves to nothing, causing immediate runtime failures for every consumer of the package.
Remediation
Ensure src/index.ts (or whatever your exports["."] points to) explicitly re-exports everything that's part of the public API.
// src/index.ts — clean, explicit entry point:
export { ApiClient } from './client'
export { ApiError, RateLimitError } from './errors'
export type { ApiConfig, ApiResponse } from './types'
Consumers should never need to import from your-package/dist/lib/internal. Map any intentional sub-modules in package.json:
{
"exports": {
".": "./dist/index.mjs",
"./utils": "./dist/utils.mjs"
}
}
Test with a fresh install: import { primaryExport } from 'your-package' should resolve and have the expected type.
Detection
-
ID:
clear-entry-point -
Severity:
critical -
What to look for: Count all entry point configurations (main, module, exports, types). For each, examine the main entry point file (whatever
exports["."],main, ormodulepoints to — typicallysrc/index.ts). Check that:- The file exists and exports something meaningful
- The primary API is accessible from the default import path (
import { thing } from 'your-package') - The entry point is not an empty barrel file or a file that only re-exports from deeply nested paths
- Consumers don't need to import from internal paths like
your-package/dist/lib/utils/helper
-
Pass criteria: The package's main entry point (
exports["."]ormain) resolves to a file that exports the primary public API. A consumer canimport { PrimaryClass, mainFunction } from 'your-package'and get the core functionality — at least 1 entry point (main, module, or exports) must resolve to an existing file. Report: "X entry point fields configured." -
Fail criteria: The main entry point doesn't exist, exports nothing useful (empty file), or the primary API is only available through deep internal imports that aren't mapped in
exports. OR the entry point file has no exports and only executes side effects. -
Skip (N/A) when: Go module (package structure IS the entry point). For Python and Rust, check that
__init__.pyorlib.rsrespectively serve as clean entry points. -
Detail on fail:
"src/index.ts exports nothing. The main API class (ApiClient) is only importable via 'your-package/dist/lib/client' — a path that depends on internal directory structure and will break if you reorganize." -
Remediation: Your entry point is the front door to your package. Make the primary API available from the package root:
// src/index.ts — clean entry point: export { ApiClient } from './client' export { ApiError, RateLimitError } from './errors' export type { ApiConfig, ApiResponse } from './types'Consumers should never need to know your internal directory structure. If you have sub-modules, map them in
exports:{ "exports": { ".": "./dist/index.mjs", "./utils": "./dist/utils.mjs" } }
External references
- iso-25010:2011 · maintainability.modifiability — Modifiability — clear entry point enables clean API evolution
- iso-25010:2011 · compatibility.interoperability — Interoperability — entry-point resolution across toolchains
Taxons
History
- 2026-04-18·v1.0.0·Initial import from sdk-package-quality·automated