TypeScript is most valuable when it describes boundaries, not when it decorates every line.
In a multi-site workspace, the boundary is the product. Apps need freedom to express their own content. Shared packages need discipline so one site’s assumption does not leak into another site’s runtime.
Types should name contracts
The most useful types answer questions:
- What does a Note need to render everywhere?
- Which fields are optional presentation details?
- What categories are allowed?
- What can a shared component assume?
These are product questions disguised as engineering questions.
Keep local things local
If a component only belongs to one app, it should stay in that app. Moving it into a shared package too early creates a false promise: that the abstraction is ready for reuse.
Shared code should be earned by repeated use.
Avoid clever data
Stringly data is easy to start and hard to maintain. A fixed category list is less flexible, but it makes navigation, routes, labels, and RSS output easier to reason about.
The goal is not maximum configurability. The goal is fewer surprises when a new note or page is added.
Boring is a feature
Good boundaries are boring. They make the next change feel obvious.
That is what maintainability usually means: the system tells you where the work belongs.
Related Notes
Continue through the same thinking system.