Architecture
How Nebutra is built — monorepo structure, request flow, and the key layers of the platform.
Overview
Nebutra is a Turborepo monorepo with multiple apps and shared packages: design system, type-safe API contract, and runtime tokens. Components are independently deployable.
Browser / Mobile Client
│
▼
┌─────────────────────────────┐
│ Cloudflare DNS + CDN/WAF │
└─────────────┬───────────────┘
│
┌──────────┼──────────┬──────────────┐
▼ ▼ ▼ ▼
landing docs web + auth API gateway
(Vercel) (Vercel) (ECS Next) (ECS Hono)
nebutra.com docs. app. + auth. api.nebutra.com
nebutra.com
│
│ REST / cookies (.nebutra.com)
▼
┌──────────────────┐
│ backends/gateway │ @nebutra/gateway
│ auth, RBAC, S2S │
└────────┬─────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
PostgreSQL Redis/KV AI / workersApps
| App | URL | Framework | Steady-state host |
|---|---|---|---|
landing | nebutra.com | Next.js 16 | Vercel |
sailor-docs | nebutra.com/docs | Next.js + Fumadocs | Vercel |
web | app.nebutra.com | Next.js 16 | ECS (Next standalone) |
auth | auth.nebutra.com | Next.js 16 | ECS login center |
backends/gateway | api.nebutra.com | Hono + Node | ECS (@nebutra/gateway) |
idp | sso.nebutra.com | Next.js | ECS OIDC issuer |
studio | studio.nebutra.com | Sanity | Vercel / optional |
design-docs | internal | Fumadocs | optional |
storybook | internal | Storybook | optional |
Core packages
| Package | Description |
|---|---|
@nebutra/ui | Component library — Radix + Nebutra primitives |
@nebutra/tokens | Runtime CSS design tokens |
@nebutra/auth | Provider adapters + JWT S2S (signServiceToken) |
@nebutra/permissions | RBAC — CASL or OpenFGA |
@nebutra/db | Prisma client + multi-tenant helpers |
@nebutra/queue | QStash or BullMQ |
@nebutra/metering | Usage metering → ClickHouse |
@nebutra/webhooks | Outbound webhooks (HMAC signing for delivery, not S2S) |
@nebutra/tenant | Tenant context + RLS helpers |
Request flow
Request
│
├─ 1. Cloudflare (DNS, CDN, WAF)
│
├─ 2. App origin
│ ├─ Marketing/docs → Vercel
│ └─ app / auth / api → ECS PM2
│
├─ 3. Gateway middleware (api.*)
│ ├─ CORS
│ ├─ Auth (session / Better Auth JWT, or S2S service JWT)
│ ├─ Tenant (org context)
│ ├─ RBAC
│ └─ Rate limit
│
└─ 4. Route handler → JSON envelope { success, data, error }Service-to-service calls use short-lived HS256 JWTs in x-service-token
(not legacy hex-HMAC).
Database isolation
| Strategy | Isolation | Recommended for |
|---|---|---|
| Shared schema | RLS via tenant_id | Most SaaS (default) |
| Separate schema | Schema per tenant | Mid-market residency |
| Separate database | DB per tenant | Strict compliance |
AI layer
Gateway AI surfaces (authenticated, tenant-scoped), for example:
POST /api/v1/ai/chatPOST /api/v1/ai/embeddingsGET /api/v1/ai/models
Usage feeds the metering pipeline for quotas and billing.
Provider swap pattern
# Auth (production default)
AUTH_PROVIDER=better-auth
NEXT_PUBLIC_AUTH_PROVIDER=better-auth
# Alternatives: clerk | next-auth | supabase | devAlign AUTH_PROVIDER and NEXT_PUBLIC_AUTH_PROVIDER across auth center, web, and landing.
How is this guide?
Edit on GitHub
Last updated on