MallaDocs

Local development

The monorepo layout, running every Worker locally and the quality gates.

Developer guide

The repository is a pnpm workspace driven by Turborepo. Every app is a Worker you can run locally with Wrangler.

Layout

PathWhatLocal port
apps/webNuxt editor, Panda CSS design system3000
apps/apiHono API4000
apps/realtimeYjs rooms8788
apps/sitesPublished sites, <slug>.localhost:87908790
apps/runnerServer workflows, tables, visitor auth8791
apps/mcpMCP server8792
packages/*Shared libraries, imported from source—
docs/Architecture, deploy guide, agent process—

Set up

  1. Install

    Use the pnpm version pinned in package.json.

    bash
    pnpm install                      # also runs nuxt prepare + panda codegen for web
    cp apps/api/.dev.vars.example apps/api/.dev.vars
    cp apps/sites/.dev.vars.example apps/sites/.dev.vars
    cp apps/realtime/.dev.vars.example apps/realtime/.dev.vars
    cp apps/mcp/.dev.vars.example apps/mcp/.dev.vars
    # fill in DATABASE_URL (a Neon dev branch) and the shared keys
    
  2. Migrate the database

    Apply packages/db/migrations to your dev branch with pnpm --filter @malla/db db:migrate and DATABASE_URL set.

  3. Run

    bash
    pnpm dev                          # every Worker and the editor through turbo
    pnpm --filter web dev             # just the editor
    pnpm --filter api dev             # just one Worker
    

Local sandbox

pnpm sandbox runs the whole stack (Postgres, api, realtime, sites, runner and the editor) with no .dev.vars and no DATABASE_URL to set up. Postgres is PGlite, the migrations in packages/db/migrations are applied on start, and dev-only secrets are generated once. Data persists between runs; press Ctrl+C to stop.

bash
pnpm sandbox                      # start; data persists between runs
pnpm sandbox --reset              # wipe the sandbox data first, then start
ServiceURL
Editorhttp://localhost:3200/login
APIhttp://localhost:4200/health
Realtimews://localhost:8988
Siteshttp://<slug>.localhost:8990 (after publishing)
Runnerhttp://localhost:8991/health
Postgrespostgres://postgres@127.0.0.1:5599/postgres

Sign in as demo@malla.local with the password demo-password-123. The first boot creates that user, its workspace and a site called "Demo site" with the slug demo. The ports stay clear of pnpm dev and the e2e stack, so all three can run at once. The sandbox does not start the MCP Worker, and it has no email or AI keys: it sends no email (so no sign-in links) and the built-in AI is off. Everything it generates lives in scripts/sandbox/.data/; scripts/sandbox/README.md has the port overrides and the details.

Quality gates

bash
pnpm check-types                  # TypeScript across the monorepo
pnpm test                         # Vitest unit tests in every package
pnpm --filter web build           # production build of the editor
pnpm e2e                          # Playwright against the full local stack
graphify update .                 # refresh the code knowledge graph

The e2e suite starts its own stack in a per-checkout state directory, so parallel worktrees never collide, and keeps a screenshot per test in apps/web/e2e/.screenshots/.

Conventions

  • Vue 3 <script setup lang="ts">, strict TypeScript, explicit imports (auto-imports are off).
  • Editor UI is styled with Panda CSS using semantic tokens only; motion goes through app/motion (GSAP).
  • All document changes go through ops and editor.document.transact; never mutate the doc directly.
  • Small Conventional Commits, one logical change each. Full rules in docs/frontend-conventions.md.