Named exports used for tree-shaking
Why it matters
A package that only exports a single default namespace object forces bundlers to include the entire package in every consumer's bundle, regardless of which methods they actually use. ISO 25010 resource-utilization degrades linearly with how much dead code consumers are forced to carry. Tools like webpack, Rollup, and Vite perform tree-shaking on named exports but cannot eliminate unused properties of a default export object. For frontend consumers, this directly inflates page weight and Lighthouse scores.
Severity rationale
High because default-only exports defeat tree-shaking across all major bundlers, forcing consumers to ship your entire API surface even when they use one function.
Remediation
Replace or supplement a default namespace export with named exports from src/index.ts.
// Before — single default object, not tree-shakeable:
const sdk = { createClient: () => {}, parseResponse: () => {} }
export default sdk
// After — named exports, each independently shakeable:
export function createClient() {}
export function parseResponse() {}
export function formatError() {}
A default export alongside named exports is acceptable if the class or factory function is the natural primary API. The key requirement: import { specificFunction } from 'your-package' must work without importing the rest.
Detection
-
ID:
named-exports -
Severity:
high -
What to look for: List all exports from the SDK entry point. For each export, check the main entry point and any sub-path exports for their export style. Look for:
- Named exports (
export function,export class,export const,export { ... }) - Versus default-only exports (
export default bigObjectwith all API methods on one object) - Whether a large namespace object or class is the only export (prevents tree-shaking)
- Re-exports using
export * from(acceptable if the re-exported modules use named exports)
- Named exports (
-
Pass criteria: The package primarily uses named exports. Consumers can import only what they need:
import { specificFunction } from 'your-package'. A default export alongside named exports is acceptable — at least 80% of public API should use named exports rather than default exports. Report: "X named exports found." -
Fail criteria: The package only exports a single default object or namespace that contains all functionality. Consumers must import everything to use anything:
import SDK from 'your-package'; SDK.specificFunction(). This defeats tree-shaking. -
Skip (N/A) when: The package has a single primary export by design (e.g., a single class like
StripeorPrismathat is the entire API surface). Also skip for Go (no default exports concept) and Rust (module system handles this differently). -
Do NOT pass when: The package uses only
export defaultfor its entire public API — this breaks tree-shaking and auto-import. -
Detail on fail:
"The entry point only has 'export default' with a single object containing 15 methods. Consumers cannot tree-shake unused methods. Use named exports: export { method1, method2 } to enable tree-shaking." -
Remediation: Named exports let bundlers eliminate unused code. This matters for packages used in browser bundles.
// Before — single default object (not tree-shakeable): const sdk = { createClient: () => {}, parseResponse: () => {}, formatError: () => {}, } export default sdk // After — named exports (tree-shakeable): export function createClient() {} export function parseResponse() {} export function formatError() {}If your API is a class instance, you can still export the class as a named export alongside utility functions.
External references
- iso-25010:2011 · performance-efficiency.resource-utilization — Resource utilisation — tree-shaking reduces bundle size
- iso-25010:2011 · maintainability.modifiability — Modifiability — named exports make API surface explicit
Taxons
History
- 2026-04-18·v1.0.0·Initial import from sdk-package-quality·automated