Prerequisites & Installation
System requirements and detailed installation steps.
This page covers the system requirements for running Raypx and explains each installation step in detail.
System Requirements
| Tool | Version | Purpose |
|---|---|---|
| Node.js | 22.x LTS | JavaScript runtime |
| pnpm | 10.33+ | Package manager (enforced via packageManager in package.json) |
| PostgreSQL | 14+ | Primary database |
| Git | 2.30+ | Version control |
| Docker (optional) | 26+ | Containerized deployment and local PostgreSQL |
Installing pnpm
Raypx uses pnpm as its package manager with a pinned version of 10.33.0. The recommended way to install it is through Corepack, which ships with Node.js:
corepack enable
corepack prepare pnpm@10.33.0 --activateVerify the installation:
pnpm --version
# 10.33.0Corepack automatically uses the version specified in package.json's packageManager field, so you do not need to manage pnpm versions manually.
Setting Up PostgreSQL
You have several options for running PostgreSQL locally.
Option A: Local Installation
Install PostgreSQL via your package manager:
# macOS
brew install postgresql@16
brew services start postgresql@16
# Ubuntu
sudo apt install postgresql-16
sudo systemctl start postgresqlCreate the database:
createdb raypxOption B: Docker
docker run -d \
--name raypx-postgres \
-e POSTGRES_USER=raypx \
-e POSTGRES_PASSWORD=raypx \
-e POSTGRES_DB=raypx \
-p 5432:5432 \
postgres:16-alpineThen set your DATABASE_URL:
DATABASE_URL=postgres://raypx:raypx@localhost:5432/raypxOption C: Cloud Database
Services like Neon, Supabase, or Render offer managed PostgreSQL. Copy the connection string they provide into DATABASE_URL.
Environment Variables
Copy the example file and fill in values:
cp .env.example .envRequired Variables
| Variable | Description | Example |
|---|---|---|
APP_KEY | Random string for application encryption | openssl rand -base64 32 |
DATABASE_URL | PostgreSQL connection string | postgres://user:pass@host:5432/db |
AUTH_SECRET | Better Auth signing secret (min 32 chars) | openssl rand -base64 48 |
Optional Variables
| Variable | Default | Description |
|---|---|---|
VITE_PUBLIC_WEB_URL | http://localhost:3000 | Public-facing URL for OAuth callbacks |
VITE_PUBLIC_PROJECT_NAME | Raypx | Display name used in emails and UI |
ADMIN_EMAILS | (empty) | Comma-separated admin email addresses |
STORAGE_DRIVER | local | Storage backend (local or s3) |
VITE_PUBLIC_DEFAULT_THEME | dark | Default UI theme |
AUTH_RESEND_KEY | (empty) | Resend API key for transactional email |
All variables are validated at startup by @raypx/env using Zod schemas. Invalid or missing required values cause the application to exit with a descriptive error message.
Database Setup: push vs migrate
Raypx supports two ways to apply schema changes:
pnpm run db:pushdb:push reads your Drizzle schema files and applies the diff directly to the database. It does not generate migration files. This is the recommended approach during development because it is fast and does not require you to track migration history.
// turbo.json
"db:push": {
"cache": false
}pnpm run db:generate # creates migration SQL files
pnpm run db:migrate # applies pending migrationsUse db:generate to create versioned migration files in packages/database/src/migrate/. These files are committed to the repository and applied in order during deployment. This is the recommended approach for production because it provides a deterministic, reviewable history of schema changes.
Never use db:push in production. It can drop columns and lose data. Always use db:generate followed by db:migrate when deploying schema changes.
Verifying the Installation
After completing all steps, verify everything is working:
# 1. Check the health endpoint
curl http://localhost:3001/api/health
# Expected response:
# { "status": "ok", "timestamp": "..." }If the health endpoint responds successfully, your database connection and application bootstrap are working correctly.
Next Steps
- Quick Start — the condensed setup guide.
- Project Structure — navigate the repository.