Production Databases
Slingshot’s adapter model means your business logic never knows which database it’s running against. Every package — auth, community, your own entities — takes a store type. Swap it in one place.
The adapter model
Section titled “The adapter model”In development, you use 'memory' for everything. It’s fast, zero-setup, and resets on restart. For production, you change the adapter name. Nothing else changes.
// Developmentdb: { auth: 'memory', sessions: 'memory' }
// Productiondb: { auth: 'postgres', sessions: 'redis' }SQLite — built into Bun
Section titled “SQLite — built into Bun”SQLite requires no extra dependencies. It’s built into Bun and is a great starting point for small deployments.
export default defineApp({ db: { sqlite: './data/app.db', }, plugins: [ createAuthPlugin({ auth: { roles: ['user'], defaultRole: 'user' }, db: { auth: 'sqlite', sessions: 'sqlite', oauthState: 'sqlite' }, }), ], packages: [createCommunityPackage()],});PostgreSQL
Section titled “PostgreSQL”bun add @lastshotlabs/slingshot-postgresexport default defineApp({ db: { postgres: process.env.DATABASE_URL, }, plugins: [ createAuthPlugin({ auth: { roles: ['user'], defaultRole: 'user' }, db: { auth: 'postgres', sessions: 'postgres', oauthState: 'postgres' }, }), ], packages: [createCommunityPackage()],});MongoDB
Section titled “MongoDB”bun add mongooseexport default defineApp({ db: { mongo: process.env.MONGO_URL, }, plugins: [ createAuthPlugin({ auth: { roles: ['user'], defaultRole: 'user' }, db: { auth: 'mongo', sessions: 'mongo', oauthState: 'mongo' }, }), ], packages: [createCommunityPackage()],});Redis sessions + SQL records
Section titled “Redis sessions + SQL records”A common production setup: durable records in Postgres or SQLite, high-throughput sessions in Redis.
bun add ioredisexport default defineApp({ db: { postgres: process.env.DATABASE_URL, redis: process.env.REDIS_URL, }, plugins: [ createAuthPlugin({ auth: { roles: ['user'], defaultRole: 'user' }, db: { auth: 'postgres', sessions: 'redis', oauthState: 'postgres' }, }), ],});Mixing adapters per concern
Section titled “Mixing adapters per concern”Different parts of your app can use different stores. Each adapter config is independent:
export default defineApp({ db: { sqlite: './data/app.db', redis: process.env.REDIS_URL!, }, plugins: [ createAuthPlugin({ db: { auth: 'sqlite', sessions: 'redis', oauthState: 'memory' }, }), ], packages: [createCommunityPackage()],});Running migrations
Section titled “Running migrations”Slingshot generates database migrations from your entity definitions. Each
migrate generate invocation diffs every entity against its last snapshot
and writes one timestamped .sql file per backend under migrations/.
# Generate a new migration from current entity diffsslingshot migrate generate --name init
# Apply pending migrations to the configured DBslingshot migrate apply
# Show applied vs pending migrations (and detect file drift)slingshot migrate status
# Inner-loop shortcut: generate + apply in one stepslingshot migrate dev --name add_nicknameThe backend is auto-detected from infrastructure.db.postgres,
infrastructure.db.sqlite, or infrastructure.db.mongo in app.config.ts.
Override with --backend postgres|sqlite|mongo, or pass a connection string
with --db-url (Postgres falls back to DATABASE_URL; Mongo to MONGODB_URI
/ MONGO_URL). Applied migrations are tracked in the
_slingshot_entity_migrations table (or collection, for Mongo).
Where to go next
Section titled “Where to go next”- Auth Setup — adapter options for auth
- slingshot-postgres — Postgres-specific config and query helpers
- Deployment — full production deployment with slingshot-infra