Shared Packages
Govern reusable packages for UI, contracts, configuration, and domain logic.
Key takeaways
- Shared packages create leverage only when contracts are stable; without ownership and release rules they become a hidden dependency network.
- Package types (UI, config, API contracts, domain logic, utilities) each carry a distinct governance need, from accessibility review to backward compatibility.
- Export public APIs from a clear entry point, never force consumers to import internal files, and document breaking changes with migration steps.
- Initialize database, Redis, and service SDK clients lazily inside getters so Next.js builds do not evaluate runtime-only clients too early.
- Match versioning to reach: workspace deps for internal-only, CI compatibility checks across consuming apps, and semantic versioning for external distribution.
Shared packages create leverage only when their contracts are stable. Without ownership and release rules, shared code becomes a hidden dependency network that slows every team.
Package Types
| Package type | Example purpose | Governance need |
|---|---|---|
| UI | Components, tokens, layouts | Design and accessibility review |
| Config | TypeScript, lint, test, formatter presets | Platform ownership |
| API contracts | Schemas, clients, generated types | Backward compatibility |
| Domain logic | Pricing, permissions, validation | Product and engineering approval |
| Utilities | Narrow reusable helpers | Strict scope and naming |
Contract Rules
- Export public APIs from a clear entry point.
- Do not make consumers import internal files.
- Document breaking changes and migration steps.
- Keep package dependencies smaller than app dependencies.
- Add tests at package boundaries, not only inside consuming apps.
- Initialize database, Redis, and service SDK clients lazily inside getters so Next.js builds do not evaluate runtime-only clients too early.
Versioning Approach
| Situation | Recommended action |
|---|---|
| Internal-only package | Use workspace dependency and changelog notes |
| Multiple consuming apps | Require compatibility checks in CI |
| External distribution | Use semantic versioning and release notes |
| Breaking contract | Provide migration guide or codemod when possible |
Review Checklist
- Is this package solving a repeated need?
- Is the API smaller than the implementation?
- Can the package be tested without a full app?
- Who owns support when consumers break?
- Does the package avoid module-scope runtime client initialization?