Architecture
How the Elmo monorepo is structured and how the pieces fit together.
Monorepo Structure
Elmo is a pnpm monorepo managed by Turborepo. The codebase is split into apps (deployable) and packages (shared libraries).
.
├── apps/
│ ├── web/ # Main dashboard (TanStack Start)
│ ├── worker/ # Background job runner (pg-boss)
│ ├── cli/ # @elmohq/cli npm package
│ └── www/ # Marketing site (this site)
│
├── packages/
│ ├── ui/ # Shared UI components (shadcn/ui)
│ ├── lib/ # Shared business logic, DB schema, AI providers
│ ├── config/ # Deployment configuration types
│ ├── deployment/ # Deployment mode resolution
│ ├── demo/ # Demo mode implementation
│ ├── local/ # Local development mode
│ ├── whitelabel/ # White-label mode
│ ├── og/ # Shared OG image generation
│ └── api-spec/ # OpenAPI specification
│
├── docker/ # Dockerfile (multi-stage)
├── e2e/ # End-to-end tests
├── biome.json # Linting and formatting
├── turbo.json # Task pipeline configuration
└── pnpm-workspace.yamlTech Stack
| Layer | Technology |
|---|---|
| Language | TypeScript 5.x |
| Framework | TanStack Start (App Router, SSR) |
| Styling | Tailwind CSS v4 |
| Components | shadcn/ui (new-york style) |
| Data Fetching | SWR |
| Database | PostgreSQL with Drizzle ORM |
| Job Queue | pg-boss (Postgres-based) |
| Testing | Vitest |
| Linting | Biome |
| Monorepo | Turborepo + pnpm workspaces |
How the Apps Connect
┌─────────────┐ ┌──────────────┐
│ Web App │──────▶│ PostgreSQL │◀──────│ Worker │
│ (TanStack) │ │ (Drizzle) │ │ (pg-boss) │
└─────────────┘ └──────────────┘ └─────────────┘
│ │
│ ┌──────────────┐ │
└─────────────▶│ packages/ │◀─────────────┘
│ lib/ │
│ config/ │
│ ui/ │
└──────────────┘- The Web App serves the dashboard UI and the REST API (
/api/v1) - The Worker processes background jobs — querying AI models, running evaluations
- Both import shared code from
packages/lib(database schema, AI provider config) andpackages/config(deployment types) - The CLI generates Docker Compose configurations and manages the deployment lifecycle
Deployment Modes
Each deployment mode is implemented as a separate package in packages/:
| Package | Mode | Description |
|---|---|---|
packages/local | local | Single-org, email/password auth |
packages/demo | demo | Read-only demonstration |
packages/whitelabel | whitelabel | Multi-org with Auth0 SSO |
The packages/deployment package resolves the active mode at runtime based on DEPLOYMENT_MODE and provides the correct implementation.
Database
The database schema is defined with Drizzle ORM in packages/lib/src/db/. Key tables include:
- brands — Brand profiles with name, website, domains, aliases
- prompts — Tracking prompts associated with brands
- evaluations — Results from querying AI models
- citations — URLs cited by AI models in their responses
Migrations are generated with drizzle-kit generate and applied with drizzle-kit migrate.
Was this page helpful?