Design Principles
Every feature in Codapult is packaged as a self-contained module with its own directories, routes, components, and database tables. Modules follow three rules:
- Bounded — each module has a defined capability boundary and documented dependencies, so its scope is visible before you change the project.
- Core-dependent only — modules depend on the Core layer (Auth, Database, Rate Limiting, Validation), not on each other, unless explicitly noted.
- CLI-removable where mapped — the interactive setup wizard can remove supported module groups automatically; shared schema and dependencies still require review.
Module Map
| Module | Dependencies | Removable | Env Toggle |
|---|---|---|---|
| Auth | Core (required) | No | |
| Database | Core (required) | No | |
| AI Core and Chat | Auth | Yes | ENABLE_AI_CORE |
| AI Chat | AI Core | Yes | ENABLE_AI_CHAT |
| Billing | None | Yes | |
| Blog | None | Yes | ENABLE_BLOG |
| Teams | Auth | Yes | ENABLE_TEAMS |
| Notifications | Auth | Yes | |
| Feature Flags | DB | Yes | |
| File Uploads | Auth | Yes | |
| Waitlist | Yes | ENABLE_WAITLIST | |
| Welcome Page | Billing, Auth | Yes | |
| API Keys | Auth, DB | Yes | |
| Usage Credits | Auth, DB | Yes | |
| Activity Log | DB | Yes | ENABLE_AUDIT_LOG |
| Webhook Log | DB | Yes | |
| Support Widget | None | Yes | |
| Resend | Yes | ||
| i18n | next-intl | Yes | |
| Analytics (PostHog) | PostHog | Yes | |
| SEO | None | Yes | |
| Sentry | @sentry/nextjs | Yes | |
| GraphQL API | graphql-yoga | Yes | |
| Enterprise SSO | None | Yes | |
| Help Center | None | Yes | ENABLE_HELP_CENTER |
| A/B Testing | DB | Yes | ENABLE_EXPERIMENTS |
| Feature Requests | DB | Yes | ENABLE_FEATURE_REQUESTS |
| Stripe Connect | Stripe | Yes | |
| Event Store | DB | Yes | |
| White-labeling | DB | Yes | ENABLE_BRANDING |
| GDPR | DB | Yes | |
| Outgoing Webhooks | DB | Yes | ENABLE_WEBHOOKS |
| Drip Campaigns | Email, Jobs | Yes | ENABLE_DRIP_CAMPAIGNS |
| Onboarding Tours | DB | Yes | ENABLE_ONBOARDING |
| Analytics (Self-serve) | DB | Yes | ENABLE_ANALYTICS |
| Custom Domains | DB | Yes | |
| Workflows | Yes | ENABLE_WORKFLOWS | |
| Referrals | DB | Yes | ENABLE_REFERRALS |
| Promotions | DB, Payments | Yes | ENABLE_PROMOTIONS |
| OpenTelemetry | @opentelemetry/* | Yes | |
| Changelog Widget | None | Yes | ENABLE_CHANGELOG |
| RAG Pipeline | @ai-sdk/openai | Yes | |
| SCIM Provisioning | Teams | Yes | |
| Chat Memory | AI Chat, DB | Yes | |
| Scheduled Reports | Email, Jobs | Yes | ENABLE_REPORTS |
| API Versioning | None | Yes | |
| Audit Log (User) | Activity Log | Yes |
The Removable column describes whether the capability has a supported removal path. The setup wizard covers a defined set of module groups; capabilities such as Billing, Email, Notifications, File Uploads, and SEO require manual review or configuration. The exact generated diff is the authority for the version you install.
Removal vs. Disabling: Two Different Operations
Codapult has two separate ways to exclude a module from your product. Understanding the difference before setup matters.
Removing a module (CLI or manual): The module's mapped code is deleted from your repository — files, routes, and components covered by the removal scope. Shared schema, imports, and dependencies must be reviewed when they are used by more than one module. Use this path when the capability is outside your product scope; the generated diff gives you a clear review point before you continue. If the product expands later, restore the capability by merging the relevant source from the template and reviewing the resulting diff.
Disabling a module (env var, reversible): If a module is present in the codebase but you are not ready to use it, you can hide it via an environment variable. The code stays in the repo; the feature is invisible to users. Flip the variable to re-enable it at any time, with no code changes.
Practical rule: Remove modules you are confident are outside your product's scope. Keep modules you may introduce later and disable them via env var until the product is ready for them. This keeps the path reversible while you shape the first release.
Removing or disabling a module
Run the interactive setup wizard and deselect the modules you do not need:
npx @codapult/cli setup
The wizard deletes mapped files and applies supported prune markers. Review shared imports, schema tables, environment variables, and dependencies before generating migrations or building the project.
Review the generated change. The wizard deletes mapped files and applies prune markers — it does not just hide the feature. If a capability may return later, leave it in and turn it off with the matching
ENABLE_*environment variable instead (see the Module Map below or Environment Variables).
Dependency Boundaries
Modules form a layered dependency graph. The Core layer is required; everything above it is optional, with removal scope and dependencies documented per module.
┌───────────────────────────────────────────────┐
│ Core Layer │
│ (Auth, Database, Rate Limiting, Validation) │
└─────────────────────┬─────────────────────────┘
│
┌────────────┼────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Billing │ │ Teams │ │ Admin │
└─────────┘ └─────────┘ └─────────┘
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ Usage │ │ RBAC │ │ Feature │
│ Credits │ │ │ │ Flags │
└─────────┘ └─────────┘ └─────────┘
Most modules build on the Core layer, and some also depend on other modules. The Dependencies column is authoritative; for example, SCIM Provisioning depends on Teams and Chat Memory depends on AI Chat.