Skip to content

Installation

  • Node.js >= 20
  • PostgreSQL 16+ (with uuid-ossp and ltree extensions)
  • npm >= 10

Stratum offers two ways to integrate. Pick the one that fits your architecture.

Embed Stratum directly in your application. No HTTP server, no network overhead.

npm install @stratum-hq/lib pg

Best for: Node.js apps, serverless functions, scripts, maximum performance.

Run the Stratum control plane as a standalone service and connect from any language using the SDK.

npm install @stratum-hq/sdk

Best for: polyglot stacks, service-oriented architectures, React admin UIs.

The fastest way to start. Generates a complete project with Docker, migrations, and framework-specific starter code:

npx @stratum-hq/create my-app
# Supports --template express | fastify | nextjs

Install these as needed:

# Database adapters (RLS, Prisma, Sequelize integration)
npm install @stratum-hq/db-adapters pg
# NestJS integration (guard, @Tenant() decorator, DI module)
npm install @stratum-hq/nestjs
# React components (provider, tenant tree, config editor)
npm install @stratum-hq/react react react-dom
# CLI tools (project init, DB migration, scaffolding)
npm install -g @stratum-hq/cli
# or use without installing:
npx @stratum-hq/cli init

The fastest way to get PostgreSQL running with the required extensions:

docker run -d \
--name stratum-db \
-e POSTGRES_USER=stratum \
-e POSTGRES_PASSWORD=stratum_dev \
-e POSTGRES_DB=stratum \
-p 5432:5432 \
postgres:16

Then enable extensions:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "ltree";
# macOS
brew install postgresql@16
brew services start postgresql@16
createdb stratum
# Ubuntu/Debian
sudo apt install postgresql-16
sudo -u postgres createdb stratum

Enable extensions in your database:

psql -d stratum -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";'
psql -d stratum -c 'CREATE EXTENSION IF NOT EXISTS "ltree";'

If you cloned the Stratum repository, use the included docker-compose.yml:

docker compose up db -d

This starts PostgreSQL 16 with all extensions pre-configured and creates three roles: stratum_app for the application, stratum_admin for the control plane’s migrations and cross-tenant work, and the NOLOGIN control role stratum_control. See Hardening: separate admin and app roles.

The roles are created only when the database volume is created. If your volume is from before 1.8, recreate it with docker compose down -v (this deletes its data), or start the stack with DATABASE_ADMIN_URL= to keep the single-pool mode.

Set your database connection string:

export DATABASE_URL="postgres://stratum:stratum_dev@localhost:5432/stratum"

For production, you should also set:

Variable Description
DATABASE_ADMIN_URL Optional in 1.x: a separate admin login for Stratum’s own cross-tenant work, a member of the control role. The control plane and the CLI read it; with the library, pass it as adminPool. See Hardening: separate admin and app roles
JWT_SECRET JWT signing secret (required whenever NODE_ENV is not development or test; at least 32 bytes, and not a placeholder such as change-me-in-production)
JWT_AUDIENCE Required aud claim for Bearer tokens, for example stratum-control-plane
STRATUM_ENCRYPTION_KEY AES-256-GCM key for field-level encryption (required, at least 32 bytes, whenever NODE_ENV is not development or test; an unset NODE_ENV counts as development)
STRATUM_HKDF_SALT Hex-encoded HKDF salt for the encryption key (required whenever NODE_ENV is not development or test)
STRATUM_API_KEY_HMAC_SECRET HMAC secret for API key hashing (optional; when set, at least 32 bytes whenever NODE_ENV is not development or test)
ALLOWED_ORIGINS CORS origins (comma-separated)

The control plane reads more variables, such as PORT, the rate limits and REDIS_URL. See the configuration table in its README. The CLI’s variables are on the CLI page.

import { Pool } from "pg";
import { Stratum } from "@stratum-hq/lib";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const stratum = new Stratum({ pool });
// If this resolves without error, you're connected
const tenants = await stratum.listTenants({ limit: 1 });
console.log("Connected! Tenants:", tenants.data.length);
  • Follow the Quick Start to create your first tenant
  • Read Concepts to understand the data model
  • Explore Guides for in-depth feature walkthroughs