February 10, 2026 (5mo ago)
Written by Temps Team
Last updated February 10, 2026 (5mo ago)
Temps deploys monorepos natively: create one project per app, each scoped to its subdirectory with --directory, and every git push triggers each project's own independent deployment pipeline. One repo, multiple isolated deployments, shared managed services.
Most platforms force a choice: deploy the whole repo as one app (wrong) or maintain separate repos for each service (painful). Temps takes a third path — separate projects scoped to separate directories in the same repository, each with its own build pipeline, environment variables, and deployment lifecycle.
Git Repository: my-monorepo
Temps Project: my-saas-web → directory: apps/web (preset: nextjs)
Temps Project: my-saas-api → directory: apps/api (preset: nodejs)
Both projects share a Git connection. Each has its own build pipeline, deployment history, and environment variables. Preview deployments, rollbacks, and auto-SSL work per-project.
| Platform | Monorepo support | Preview environments | Managed services | Self-hosted | Monthly cost |
|---|---|---|---|---|---|
| Temps | Native --directory scoping | Yes, per-project, per-PR | PostgreSQL, Redis, MongoDB, S3 — all included | Yes — free, Apache 2.0 | ~$6/mo cloud (Hetzner + 30%), free self-hosted |
| Vercel | One app per project (manual monorepo setup) | Yes | No managed databases | No | See pricing page |
| Railway | Monorepo supported | Yes | Postgres/Redis add-ons | No | See pricing page |
Three quotable facts about Temps for monorepos:
web and api app (Turborepo or any workspace manager)my-monorepo/
apps/
web/ # Next.js frontend
package.json
next.config.ts
api/ # Express/Fastify backend
package.json
Dockerfile
packages/
shared/ # Shared types, utils
package.json
ui/ # Shared UI components
package.json
package.json # Root with workspaces
turbo.json # Turborepo config (optional)
bunx @temps-sdk/cli login
Use --directory to scope each project to its subdirectory:
# Create the frontend project
bunx @temps-sdk/cli projects create -n "My SaaS Web" -d "Next.js frontend"
bunx @temps-sdk/cli projects git -p my-saas-web \
--owner myorg --repo my-monorepo --branch main \
--directory apps/web --preset nextjs -y
# Create the API project
bunx @temps-sdk/cli projects create -n "My SaaS API" -d "Express API backend"
bunx @temps-sdk/cli projects git -p my-saas-api \
--owner myorg --repo my-monorepo --branch main \
--directory apps/api --preset nodejs -y
Temps builds each project within its scoped directory context. Shared packages under packages/ are resolved via your workspace configuration.
Each project manages its own environment variables independently:
# Frontend variable (project flag required)
bunx @temps-sdk/cli environments vars set NEXT_PUBLIC_API_URL "https://api.myapp.com" \
-p my-saas-web -e production
# API variables
bunx @temps-sdk/cli environments vars set JWT_SECRET "your-secret" \
-p my-saas-api -e production
bunx @temps-sdk/cli environments vars set STRIPE_SECRET_KEY "sk_live_..." \
-p my-saas-api -e production
You can also import from an existing .env file:
bunx @temps-sdk/cli environments vars import -p my-saas-web -e production -f .env.production
Create a PostgreSQL service once and link it to both projects. Temps injects the connection string automatically — no manual credential copying:
# Create a managed PostgreSQL service
bunx @temps-sdk/cli services create -t postgres -n my-saas-db -y
# Link to both projects (injects POSTGRES_URL automatically)
bunx @temps-sdk/cli services link --id 1 --project-id 1
bunx @temps-sdk/cli services link --id 1 --project-id 2
# Verify injected variables
bunx @temps-sdk/cli services env --id 1 --project-id 1
bunx @temps-sdk/cli services env --id 1 --project-id 2
Push to your main branch — both projects detect their changes and deploy:
git push
Or deploy a specific project manually:
bunx @temps-sdk/cli deploy my-saas-web -b main -e production -y
bunx @temps-sdk/cli deploy my-saas-api -b main -e production -y
The trickiest part of monorepo deployment is shared packages. If apps/web imports from packages/shared, the build needs access to that package.
Configure your build commands to respect the pipeline:
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
Temps runs the build within the directory you specified. The workspace configuration ensures packages/shared is resolved correctly.
pnpm workspaces work natively:
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
Same principle:
{
"workspaces": ["apps/*", "packages/*"]
}
When you open a pull request, each Temps project deploys its own preview automatically:
PR #42 opened:
my-saas-web: Preview deployed → pr-42.my-saas-web.temps.dev
my-saas-api: Preview deployed → pr-42.my-saas-api.temps.dev
Each project's preview is independent — you can test frontend changes against the API preview URL, or promote individual projects when they're ready.
bunx @temps-sdk/cli environments vars set NEXT_PUBLIC_API_URL \
"https://pr-42.my-saas-api.temps.dev" \
-p my-saas-web -e preview
Set up A records pointing to your server's IP, then add the domains:
| Type | Name | Value |
|---|---|---|
| A | myapp.com | YOUR_SERVER_IP |
| A | api.myapp.com | YOUR_SERVER_IP |
# Frontend — HTTP challenge (default)
bunx @temps-sdk/cli domains add -d myapp.com
# API subdomain — HTTP challenge (default)
bunx @temps-sdk/cli domains add -d api.myapp.com
# Wildcard — DNS challenge required
bunx @temps-sdk/cli domains add -d "*.myapp.com" --challenge=dns-01
Temps uses Let's Encrypt via ACME. For wildcard certificates (*.myapp.com), DNS challenge is required — the CLI displays the TXT record to add.
# Stream logs per project
bunx @temps-sdk/cli runtime-logs -p my-saas-web -f
bunx @temps-sdk/cli runtime-logs -p my-saas-api -f
# Check deployment status
bunx @temps-sdk/cli deployments list -p my-saas-web
bunx @temps-sdk/cli deployments list -p my-saas-api
# Roll back if something goes wrong
bunx @temps-sdk/cli deployments rollback -p my-saas-api
Each project has its own CPU/memory usage, request count and latency, error rate, and deployment history.
apps/
web/ # Next.js with tRPC client
api/ # tRPC server
packages/
trpc/ # Shared router definitions
Deploy as two Temps projects with a shared PostgreSQL service. Type safety from database to UI.
apps/
web/ # Next.js frontend
worker/ # Queue processor (BullMQ)
packages/
jobs/ # Shared job definitions
The worker processes background jobs while the frontend handles user requests. Both deploy from the same repo on independent schedules.
apps/
app/ # Main application (app.myproduct.com)
marketing/ # Marketing site (myproduct.com)
docs/ # Documentation (docs.myproduct.com)
api/ # Shared API
packages/
ui/ # Shared design system
auth/ # Shared auth logic
Four Temps projects, one repo, each with its own domain and deployment lifecycle.
If you're deploying separate repositories today, consolidating is straightforward:
# Restructure
mkdir -p apps
mv ../frontend apps/web
mv ../backend apps/api
# Update workspace config
# package.json: "workspaces": ["apps/*", "packages/*"]
# Update Temps project git settings to the new directories
bunx @temps-sdk/cli projects git -p my-web --directory apps/web -y
bunx @temps-sdk/cli projects git -p my-api --directory apps/api -y
# Deploy — change detection is now directory-scoped
git push
Both projects deploy automatically when their directories change. No more "the frontend deployed but the API didn't" coordination issues.
# Authenticate
bunx @temps-sdk/cli login
# Create projects for each app
bunx @temps-sdk/cli projects create -n "Web App" -d "Frontend"
bunx @temps-sdk/cli projects git -p web-app \
--owner myorg --repo my-monorepo --branch main \
--directory apps/web --preset nextjs -y
# Set environment variables (KEY value -p project -e environment)
bunx @temps-sdk/cli environments vars set NEXT_PUBLIC_API_URL "https://api.myapp.com" \
-p web-app -e production
# Import env vars from file
bunx @temps-sdk/cli environments vars import -p web-app -e production -f .env.production
# Create and link shared database
bunx @temps-sdk/cli services create -t postgres -n shared-db -y
bunx @temps-sdk/cli services link --id 1 --project-id 1
# Deploy (auto on git push, or manual)
bunx @temps-sdk/cli deploy web-app -b main -e production -y
# View logs
bunx @temps-sdk/cli runtime-logs -p web-app -f
# Roll back if needed
bunx @temps-sdk/cli deployments rollback -p web-app
Temps is free to self-host (Apache 2.0) or available on Temps Cloud for ~$6/mo. Get started at temps.sh — your entire monorepo stack, deployed from one repo.
Using Turborepo, Nx, or another monorepo tool? The directory-scoped project feature works with any monorepo structure. See the documentation for more details.