Package Layers
Tulip packages are grouped by architectural role, not just by package size.
Tulip packages are grouped by architectural role, not just by package size.
Atoms
Atoms are foundational packages that provide plain, reusable primitives. They have a single responsibility, avoid product-specific behavior, and do not care which Tulip module consumes them.
Atoms are allowed to be boring. They should be stable, reusable, and generic.
Current Atoms
@tulip-systems/core@tulip-systems/ui@tulip-systems/query@tulip-systems/storage@tulip-systems/auth
Modules
Modules are higher-level capability packages. They compose atoms into opinionated workflows, product surfaces, or domain features.
A module may be split into multiple packages when it needs separate providers, adapters, or integrations.
Current Modules
@tulip-systems/app@tulip-systems/ai@tulip-systems/commands@tulip-systems/data-tables@tulip-systems/drive@tulip-systems/editor@tulip-systems/inline
Package Families
Some modules are represented by a family of packages that share a prefix.
Drive
@tulip-systems/drive@tulip-systems/drive-local@tulip-systems/drive-google
Editor
@tulip-systems/editor@tulip-systems/editor-storage
Dependency Direction
Preferred dependency direction:
tooling -> modules -> atomsRules:
- Atoms should not depend on modules.
- Modules may depend on atoms.
- Modules should avoid depending on unrelated modules unless they are intentionally composing them.
- Provider and adapter packages should stay inside the module family they support.
Example
If we build a notification system:
eventswould be an atom.notificationswould be a module.notifications-emailwould be a provider or facet of the notifications module.