The self-hosted, headless waitlist API. Define custom schemas in seconds, own your data, and deploy anywhere.
Lobby is an open-source, developer-first, self-hosted waitlist backend. Traditional waitlist SaaS platforms lock your data behind their subscription models, enforce rigid fields, and limit customizations. Lobby solves this by giving you:
- Complete Data Ownership: Your signups live entirely in your own PostgreSQL database.
- 100% Headless & Customizable: Define your waitlist's name and schema with an interactive wizard, plug it into your custom frontend, and walk away.
- Instant Deployments: Go from a blank terminal to a fully functional, production-ready waitlist API in less than 5 minutes.
- Zero Data Loss Migrations: Safely add, modify, or remove signup fields post-launch using automatically generated SQL migrations.
Lobby is engineered with high-performance, industry-standard modern web technologies:
- Framework: NestJS 11 β reliable, scalable, and highly structured.
- Database Interface: Kysely β ultra-fast, SQL-injection safe, and fully type-safe dynamic SQL compiler.
- Data Layer: PostgreSQL β robust relational database.
- Queuing & Workers: BullMQ & Redis β transactional mail queuing for heavy signup loads.
- Communications: Resend β modern developer-friendly transactional email service.
- CLI Wizard: Clack (
@clack/prompts) β beautiful, interactive console prompts.
sequenceDiagram
autonumber
actor Developer
actor User as Signup Client
participant CLI as Lobby CLI Setup
participant API as Lobby NestJS API
participant DB as PostgreSQL
participant Redis as BullMQ Redis
participant Resend as Resend SDK
Note over Developer, DB: 1. Setup Phase
Developer->>CLI: pnpm run setup
CLI->>Developer: Prompts (Waitlist name, fields, email configs)
CLI->>Developer: Generates lobby.config.json & SQL migration file
Developer->>DB: pnpm run migration:run (Applies schema transactions)
Note over User, Resend: 2. Runtime Phase
User->>API: POST /api/v1/waitlist/join (dynamic data payload)
API->>API: Validates data types against lobby.config.json at runtime
API->>DB: Check for duplicate emails & atomic position assignment (via DB sequence)
DB-->>API: Returns assigned waitlist position
API->>Redis: Enqueues SEND_CONFIRMATION_EMAIL job (if enabled)
API-->>User: Returns 201 Created (ID, position, success message)
Note over Redis, Resend: 3. Background Mail Worker
Redis->>API: BullMQ Processor pulls active mail job
API->>Resend: Dispatches custom email variables
Deploying your waitlist backend is straightforward. Ensure you have Node.js (>=22.0.0) and pnpm (>=10.33.4) installed. (Note: A PostgreSQL database instance is only required starting at Step 4).
git clone https://github.com/josephsystems/lobby.git && cd lobby && pnpm installpnpm run setupThis command generates:
lobby.config.jsonβ the source of truth for your waitlist schema.migrations/{timestamp}_initial_setup.sqlβ a custom SQL migration mapping your fields directly into PostgreSQL.
Copy the template .env.example to .env and configure your credentials:
cp .env.example .envNote
Resend Template Variables: Your Resend template will receive the following variables dynamically:
email: The signup's email address.position: The signup's queue position (integer).- Any custom fields configured in
lobby.config.json(e.g.,first_name,last_name, etc.).
Apply the migration files to construct your custom database tables:
pnpm run migration:runStart the NestJS development server:
pnpm run start:devYour waitlist API is now active at http://localhost:3000/api/v1! π
Submits a signup request. Dynamic fields are added to fields and validated against the schema defined in lobby.config.json.
- Route:
POST /api/v1/waitlist/join - Content-Type:
application/json
{
"email": "developer@example.com",
"fields": {
"first_name": "Ada",
"last_name": "Lovelace",
"phone": "+2348000000000"
}
}{
"status": "success",
"data": {
"id": "2e6b223c-f4e1-456b-be39-2a912bb0e7b8",
"email": "developer@example.com",
"position": 42,
"message": "You're on the list!",
"isNew": true
}
}Submitting the same email again is safe and returns the user's existing queue position:
{
"status": "success",
"data": {
"id": "2e6b223c-f4e1-456b-be39-2a912bb0e7b8",
"email": "developer@example.com",
"position": 42,
"message": "You're already on the list!",
"isNew": false
}
}Retrieves a user's current place in the waitlist queue.
- Route:
GET /api/v1/waitlist/position - Query Parameters:
email(string, required)
GET /api/v1/waitlist/position?email=developer@example.com{
"status": "success",
"data": {
"message": "Successfully retrieved position.",
"email": "developer@example.com",
"position": 42
}
}Lobby is a public-facing API but contains rigorous protection to prevent malicious third parties from spamming your backend from random origins:
- Origin Restriction: Lobby dynamically compiles regular expressions from the
APP_DOMAINenv variable. - CORS Behavior:
- Production (
NODE_ENV=production): Strictly allows requests only fromhttps://yourproduct.comand its HTTPS subdomains. - Staging: Allows standard localhost routes plus your secure production domains.
- Development: Automatically permits localhost ports (
http://localhost:*).
- Production (
To deploy Lobby, you will need a PostgreSQL Database and (optionally) a Redis Instance (required only if email is enabled in lobby.config.json) for BullMQ queues and rate limiting.
Choose one of the following providers:
- Supabase (Free/Managed): Create a project at Supabase. Copy the PostgreSQL transaction/session connection string from Database Settings.
- Neon (Free/Managed): Create a serverless database at Neon, which is excellent for serverless environments.
- Self-Hosted / VPS: Run PostgreSQL natively or via Docker.
Required only if email is enabled in lobby.config.json.
- Upstash (Free/Managed): Serverless Redis with a generous free tier. Create one at Upstash.
- Aiven (Free/Managed): Managed Redis with a free tier. Create one at Aiven.
- Redis (Free/Managed): Managed Redis with a free tier. Create one at Redis.
- Self-Hosted / VPS: Run Redis natively or via Docker.
Railway is a fast way to host your app, PostgreSQL, and Redis in one dashboard.
- Create a new project in Railway.
- Connect the GitHub repository.
- Add PostgreSQL and Redis (if using emails or want Throttle to use redis) database services to your project.
- Link your database and Redis connection details to Lobby's environment variables.
- Deploy! Railway will automatically detect Node.js, run your build script, and expose the application port.
Render is a developer-friendly platform for web services and databases.
- Create a PostgreSQL and Redis (if using emails or want Throttle to use redis) database on Render.
- Create a new Web Service on Render and connect your GitHub repository.
- Set the build and start commands:
- Build Command:
pnpm run build - Start Command:
pnpm run start:prod
- Build Command:
- Configure your environment variables in the Render dashboard.
- Deploy!
Lobby can be deployed as serverless functions on Vercel.
- Connect the repository to Vercel.
- Set up the required environment variables.
- Deploy!
[!NOTE] Ensure you use serverless-compatible database and Redis connections (like Neon and Upstash) that handle connection pooling efficiently.
Perfect if you want full ownership on your own server (DigitalOcean, Hetzner, AWS, etc.).
Lobby includes a docker-compose.yml that configures the API, PostgreSQL, and Redis automatically. To start:
docker-compose up -d --buildLobby will spin up, automatically run pending migrations, and listen on port 3000.
When deploying, ensure the following variables are configured on your host:
| Variable | Description | Required? |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Yes |
APP_DOMAIN |
Frontend application domain (for CORS security, e.g., myapp.com) |
Yes |
NODE_ENV |
Environment mode (production, staging, or development) |
No (defaults to development) |
REDIS_HOST / REDIS_PORT |
Connection details for Redis | Yes if email is enabled in lobby.config.json |
REDIS_PASSWORD / REDIS_USER |
Auth details for Redis | No |
RESEND_API_KEY |
Resend API key for sending emails | Yes if email is enabled in lobby.config.json |
RESEND_CONFIRMATION_TEMPLATE_ID |
Resend template ID for waitlist verification | Yes if email is enabled in lobby.config.json |
DATABASE_SSL |
Enable TLS/SSL connection to PostgreSQL (true/false) |
No (defaults to false) |
DATABASE_CA_CERT_PATH |
Path to CA cert file for SSL verification | Yes if DATABASE_SSL=true |
Lobby's architecture is fully structured, leaving room for expansion in upcoming minor and major releases:
- v0.7.0 (Current): Core dynamic API, setup CLI, BullMQ email dispatchers, dynamic CORS.
- v1.0.0: CLI-based dynamic field modification scripts (
pnpm run fields:add/edit). - v1.1.0: Referral tracking system (generate unique invite links and track signup invite counts).
- v2.0.0: Secure Admin Dashboard endpoints (
/admin/entries) with CSV exports, protected via custom API key middleware.
We welcome contributions of all kinds! Whether you are fixing a bug, adding a feature, or improving documentation, please read our Contributing Guide to get started.
Please also review our Code of Conduct to understand the expectations for participating in this project.
Lobby is open-source software licensed under the MIT License.