Production-ready TypeScript boilerplate.
Nebula ships with authentication, observability, background infrastructure, and developer tooling pre-wired, so you can skip the setup grind and start building features on day one.
- Stack Overview
- Dependency Injection Container
- Email Templates
- Getting Started
- Environment Setup
- Database Commands
- Testing & Validation
- Monitoring
- Port Map
- Quick Start Summary
| Layer | Technology |
|---|---|
| Language | TypeScript |
| Runtime | Node.js |
| Framework | Express |
| Database | PostgreSQL |
| ORM | Drizzle |
| Cache / Queue / Sessions | Redis |
| Validation | Zod |
| Auth | JWT + Cookies + Google OAuth |
| Email Delivery | Resend + @repo/emails (react-email) |
| SMS | Twilio |
| Logging | Pino + request logger middleware, Winston (for Loki) |
| Rate Limiting | express-rate-limit + Redis-backed store |
| Testing | Vitest + Supertest |
| Dev Tooling | Husky, Commitlint, Prettier, ESLint |
| Containers | Docker + Docker Compose |
| Monitoring | Prometheus + Grafana + Loki |
The project uses a central container to wire application dependencies together:
createContainer()
createServices()
createRepositories()
createValidators()
createMiddlewares()
createControllers()
@repo/emails ships with 4 pre-built react-email templates, designed off real Dribbble references - not the usual bare-bones "Welcome to X" placeholder. Ready to send from day one:
- signup confirmation
- Password reset / OTP
- Order confirmation
pnpm installFor local, non-Docker development:
cp .env.example .envFor Docker-based local/production-like setup, create a Docker environment file:
cp .env.example .env.production.localImportant: The Docker Compose setup reads
./.env.production.localfor the app service (env_file: ./.env.production.local).
pnpm devThis starts the app with tsx --watch ./src/index.ts and listens on the configured PORT value from .env (default: 3000).
Build the app:
pnpm buildRun the compiled server:
PORT=3000 node dist/index.mjsOr, with a .env file loaded automatically from your shell environment:
node dist/index.mjsStart the full stack (API + Postgres + Redis + RedisInsight + Prometheus + Grafana + Loki):
docker compose up --buildRun in detached mode:
docker compose up -dStop everything:
docker compose downCopy the example environment file and configure your secrets:
cp .env.example .envKey values include:
| Variable | Purpose |
|---|---|
PORT |
App server port |
NODE_ENV |
Runtime environment |
DATABASE_URL |
PostgreSQL connection string |
REDIS_HOST / REDIS_PORT |
Redis connection |
JWT_ACCESS_TOKEN_SECRET |
JWT access token signing secret |
JWT_REFRESH_TOKEN_SECRET |
JWT refresh token signing secret |
RESEND_API_KEY |
Email delivery via Resend |
GOOGLE_CLIENT_ID |
Google OAuth |
GOOGLE_CLIENT_SECRET |
Google OAuth |
GOOGLE_AUTH_REDIRECT_URI |
Google OAuth redirect |
TWILIO_ACCOUNT_SID |
SMS via Twilio |
TWILIO_AUTH_TOKEN |
SMS via Twilio |
Generate Drizzle schema artifacts:
pnpm db:generateApply migrations:
pnpm db:migratePush schema directly:
pnpm db:pushSeed data:
pnpm db:seedpnpm test
pnpm check:types
pnpm check:lint- Ensure Grafana, Prometheus, and Loki are running — Docker Compose brings them up on the ports listed below.
- From the
terraform/folder, run:
cd terraform
terraform init
terraform plan
terraform apply -auto-approveNote: The Terraform provider used is the Grafana provider, and the modules rely on JSON dashboard templates in the repo. Terraform creates the dashboard resources in the target Grafana instance.
This boilerplate wires Prometheus and Grafana together, so you get metrics and logs out of the box when running the Docker stack.
Default Docker Compose UI ports:
| Service | URL | Notes |
|---|---|---|
| Grafana | http://localhost:3005 | Dashboards created by Terraform live here. Default credentials: admin:admin (included Docker image) |
| Prometheus | http://localhost:9090 | Explore metrics, run ad-hoc queries |
| Loki | http://localhost:3100 | Log aggregation |
| RedisInsight | http://localhost:5540 | Inspect Redis data |
| Service | Address |
|---|---|
| App server | http://localhost:3000 |
| ↳ Health check | http://localhost:3000/health |
| ↳ Metrics | http://localhost:3000/metrics |
| PostgreSQL | localhost:5432 |
| Redis | localhost:6379 |
| RedisInsight | http://localhost:5540 |
| Prometheus | http://localhost:9090 |
| Grafana | http://localhost:3005 |
| Loki | http://localhost:3100 |
Shortest path to running the project locally:
pnpm install
pnpm --filter emails run build:package
cp .env.example .env
pnpm devShortest path to the full Docker stack:
cp .env.example .env.production.local
docker compose up