Why multi-app is a first-class idea

Most products are more than one app. What Devora.js does about that, what it costs, and where a monorepo tool or one big app is still the better fit.

A product that has customers usually has more than one front door: a marketing site that should be fast and public, an app people log in to, an admin panel only staff should see, and more and more often an API for a mobile client. These share almost everything underneath — the same users, the same data, the same business rules — and almost nothing on top.

The usual answers are one big app with route groups, or several repos stitched together with a monorepo tool. The first couples things that should be separate (the marketing site redeploys when the admin panel changes; one CSP for everything). The second leaves the shared part — the backend and the login — for you to build.

What Devora.js does instead

One config file lists the apps. This is the whole project in the multi-app example:

export default defineProject({
  apps: [
    { name: "site", dir: "apps/site", domain: "site.example.com", auth: "none" },
    { name: "app",  dir: "apps/app",  domain: "app.example.com",  auth: "shared" },
    { name: "api",  dir: "apps/api",  domain: "api.example.com",  auth: "shared" },
  ],
  shared: { core: "packages/core", backend: "packages/backend", auth: "shared", sessions: { store: "memory" } },
});
  • Separate where it matters. Each app has its own routes, render modes, security headers and domain, and builds and deploys on its own: one Vercel project or Netlify site per app.
  • Shared where it matters. One backend package every app imports directly — a dashboard form and a mobile API call the same function — and one session system. shared apps accept the same login, whether it arrived as a cookie or a Bearer token; an isolated app (an admin panel) has its own; a none app has no sessions and needs no secret.
  • One command per job. devora dev runs every app; devora add <name> adds one; devora build --app=admin builds one.

What it costs

  • Moving between apps is a full page load. They're separate apps; Next.js's Multi-Zones has the same trade-off.
  • A browser only sends a cookie to the host that set it, so one login across app.example.com and admin.example.com needs shared.sessions.cookie.domain.
  • Devora.js isn't a build orchestrator. A large or polyglot repo still wants Turborepo or Nx for caching and task graphs; they can sit alongside it.
  • It's pre-1.0 with a small community. Next.js has more answers online and more libraries; Astro is a strong choice for content sites. The comparison page goes through where each one is ahead.

Why it's in the framework

Because the shared part is where the security mistakes happen. If every app wires its own session handling, CSRF checks and headers, one of them gets it wrong. Here sessions are server-side and revocable, CSRF is checked for cookie requests, and CSP and HSTS are on for every app by default — the same code for every app in the project.

The tutorial builds a three-app project like the one above, step by step.