Skip to main content
BunShip uses a configuration-driven architecture. Instead of hunting through source code, you control most behavior by editing four files in the packages/config/src/ directory.

Config Package Overview

The @bunship/config package exports all shared configuration used across the monorepo. Import any config value from the package:

Application Config

The appConfig object in packages/config/src/app.ts defines your application identity and server behavior.
Start by changing name, description, and company to match your product. These values propagate to email templates, API docs, and error messages.

Environment Variables

All environment-specific values are read from .env. Copy .env.example to get started:

Required Variables

Optional Variables

Stripe Price IDs

Each billing plan needs corresponding Stripe price IDs:

Feature Flags

The featuresConfig object in packages/config/src/features.ts controls which features are active and how they behave.

Authentication

Organizations

Disabling Features

Set enabled: false on any feature block to turn it off entirely:
Disabling features removes their routes from the API. Existing data in the database is not affected, but the endpoints will return 404.

CORS Settings

CORS origins are configured in two places. The config file sets defaults, while the CORS_ORIGINS environment variable overrides them at runtime.
For production, set the environment variable with your actual domains:
To disable CORS entirely (not recommended for browser-facing APIs):

Rate Limiting

BunShip applies rate limiting at two levels.

Global Rate Limit

Defined in appConfig.api.rateLimit, this applies to all routes:

Route-Level Rate Limit

Sensitive routes like authentication have tighter limits applied directly in the route definition using the elysia-rate-limit plugin:

API Key Rate Limits

API keys have their own rate limit defined in the features config:

Billing Configuration

Edit packages/config/src/billing.ts to define your pricing tiers. Each plan specifies a price, Stripe price IDs, usage limits, and feature descriptions.
After modifying plans in code, you must create matching products and prices in your Stripe Dashboard and update the stripePriceIds with the generated price IDs.

Helper Functions

The billing config exports utility functions for checking limits:

Permissions

The permission system is defined in packages/config/src/permissions.ts. Permissions follow a resource:action pattern with wildcard support.

Assigning Permissions to Roles

Role-permission mappings live in featuresConfig.organizations.permissions:

Wildcard Rules

  • "*" grants all permissions (used for the owner role)
  • "resource:*" grants all actions on a resource (e.g., "members:*" grants members:read, members:invite, members:update, members:remove)

Adding Custom Permissions

To add permissions for a new resource:
1

Define the permissions

Add entries to packages/config/src/permissions.ts:
2

Assign to roles

Update the role mappings in packages/config/src/features.ts:
3

Enforce in routes

Use the requirePermission middleware:

Next Steps

Adding Routes

Create new API endpoints with Elysia

Database Schema

Modify and extend the database with Drizzle ORM