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.
Critical because a misconfigured entry point means the primary import path resolves to nothing, causing immediate runtime failures for every consumer of the package.
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.
ID: sdk-package-quality.api-surface.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, or module points to — typically src/index.ts). Check that:
import { thing } from 'your-package')your-package/dist/lib/utils/helperPass criteria: The package's main entry point (exports["."] or main) resolves to a file that exports the primary public API. A consumer can import { 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__.py or lib.rs respectively 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"
}
}