Skip to content

Work / canon / Wiki / Decisions

stack

Decisionverified 2026-10-27

Stack

Decision

babul's stack, in a Turborepo with pnpm on Node 24.

  • apps/web, one Next.js 16 app (React 19, TypeScript, Tailwind 4 with packages/ui tokens, lucide): the public site, docs, app, API, GitHub webhooks and MCP at /mcp (OAuth, as babul).
  • API: tRPC 11 for the screens, route handlers for webhooks.
  • Sign-in and tenants: better-auth: organization plugin for companies, members and roles; SSO plugin for SAML and OIDC; GitHub sign-in.
  • Data: Postgres and Prisma 7. Every company read goes through one helper that names the tenant (babul's withMember).
  • GitHub: a GitHub App through @octokit/app. Checks: zod 4, vitest, Playwright. Hosting: Vercel; the Postgres host is chosen at schema review.
  • Community Edition: the same app run by canon ui, read from disk, no backend, Cloud screens locked.

Why

babul already solves the same problems (tenants, roles, public site and docs, CLI and MCP over one API) in one Next app. One way of working across the estate. better-auth covers SSO, so nothing is bought before the first customer.

Rejected

  • NestJS + GraphQL + Apollo (learning-platform, scrvio): two servers and codegen, no gain at this size.
  • Firebase (chitragupt): no relational tenancy or row policies; SAML costs extra.
  • WorkOS or Auth0: the first plan; the fallback if a customer needs SCIM.

Impact

Packages today: site, ui, typescript-config, eslint-config, and db (schema). github and env come with the features that need them; none is created empty. New code is TypeScript. Lint is ESLint 10 with the Babel parser, because typescript-eslint does not support TypeScript 7; apps/web keeps TypeScript 6 for eslint-config-next.