Documentation · Installation
Prepare to install OpenMOM
A pnpm workspace of TypeScript packages against a PostgreSQL database with row-level security. The public repository and local installation open in January 2027.
Prerequisites
- Node.js 22+ — the workspace engines require
node >=22. - pnpm 10 — the repo pins
pnpm@10.33.0viapackageManager; runcorepack enableand it activates automatically. - Docker + Docker Compose — used to run the PostgreSQL 16 container. No other services are required.
Repository access
The repository will open as soon as OpenMOM is fully tested, reaches 100% parity with MOM 10, and delivers improvements beyond the legacy system. The remaining steps document the launch setup.
Start Postgres
pnpm db:up # docker compose up -d postgres
The compose file runs postgres:16-alpine with a named
volume and a health check, published on 127.0.0.1:5434. The host
port is deliberately 5434 — development machines often already run Postgres instances on
5432 and 5433, and a second Postgres silently failing to bind is a classic time sink.
One subtlety worth knowing: the container publishes on IPv4 only, so
localhost can intermittently resolve to
::1 first and fail with
ECONNREFUSED. The example connection strings pin
127.0.0.1 instead of localhost —
keep that.
Configure the environment
Copy .env.example to .env
at the repository root. The defaults match the compose file exactly:
| Variable | Example | Purpose |
|---|---|---|
| DATABASE_URL | postgres://openmom:openmom@127.0.0.1:5434/openmom | Migrations, CLI, and platform-side tooling. Connects as the openmom superuser. |
| OPENMOM_APP_URL | postgres://openmom_app:openmom@127.0.0.1:5434/openmom | All application traffic. Connects as the restricted openmom_app role. |
| OPENMOM_TEST_URL | postgres://openmom:openmom@127.0.0.1:5434/openmom_test | Test database used by the test suites. |
| OPENMOM_TEST_APP_URL | postgres://openmom_app:openmom@127.0.0.1:5434/openmom_test | App-role connection for the test database. |
OpenMOM's tooling resolves configuration through
projectEnvValue()
(packages/schema/src/env.ts), which reads the
repo-root .env first, then the ambient
environment, then falls back to a local default. The repo-root file deliberately beats a
shell-exported DATABASE_URL — your shell may export
one for an unrelated project, and pointing migrations at the wrong database is not a
recoverable mistake.
The app role and row-level security
Migration 0017 creates openmom_app with
NOSUPERUSER and
NOBYPASSRLS. Every tenant-scoped table carries a
tenant_id and runs with
ENABLE + FORCE ROW LEVEL SECURITY;
the API sets app.tenant_id per transaction, and Postgres itself
refuses to return another tenant's rows. The openmom superuser
bypasses RLS entirely, which is why the API's pool requires
OPENMOM_APP_URL and fails hard without it — a superuser
connection would silently disable tenant isolation.
Run the migrations
pnpm migrate # OSS schema stream (tracker: schema_migrations)
pnpm migrate:cloud # OSS stream + commercial stream (self-hosters: not needed)
The schema lives in packages/schema/migrations/ as
numbered SQL files applied in order and tracked in
schema_migrations. Migrations are additive — upgrades
never rewrite history. The commercial stream (billing, usage metering, platform RBAC) is
only used by the managed cloud edition; self-hosted deployments only need
pnpm migrate.
Verify
pnpm typecheck # TypeScript across the workspace
pnpm test:oss # OSS test suites (uses OPENMOM_TEST_URL)
When the tests can connect to the test database, you're set. Next: seed the demo company and start the apps →