A Devora.js project with three apps is three Vercel projects that import the same repository. That's not a Devora.js convention; it's how Vercel projects work — one build and one set of domains each. The framework's own example apps run this way (live demos, deployed by the maintainer).
The settings, per app
- Add New → Project, import the repo, and set Root Directory to
apps/<name>. - Leave the build settings alone. Every app has a committed
vercel.json:{ "$schema": "https://openapi.vercel.sh/vercel.json", "buildCommand": "cd ../.. && ./node_modules/.bin/devora build --app=app --adapter=vercel", "framework": null }"framework": nullstops Vercel from running a plainvite build, and the command goes to the repo root, wheredevora.config.tsand the shared packages are. Keep "Include files outside the Root Directory" on. - Environment variables:
DEVORA_SESSION_SECRETfor apps withauth: "shared"(the same value in every shared app),DEVORA_SESSION_SECRET_<APP>for anisolatedone, nothing forauth: "none". Redeploy after changing them.
Two things that break on serverless
The session store. A Vercel function runs as many short-lived instances. sessions: { store: "memory" } gives each its own empty store, so logins don't stick. Point shared.sessions.store at a module backed by your database or Redis. The build tells you:
$ ./node_modules/.bin/devora build --app=app --adapter=vercel [devora] "app" Vercel runtime: nodejs24.x (from the running Node 24 (satisfies engines.node ">=20")) [devora] "app" preflight warning: shared.sessions.store is "memory" — on serverless each function instance has its own empty store, so logins won't stick. Use a DB-backed store before relying on sessions in production.
A top-level api/ folder. In a Vercel project, api/ is Vercel's own functions folder: every file in apps/<name>/api/ becomes a separate function next to the one Devora builds (and counts against the Hobby plan's limit). Apps created since 0.3.2 use endpoints/ (apiDir in app.config.ts); URLs stay under /api. The preflight check warns when it finds an api/ folder.
The alternative: Root Directory = the repo root
If you can't move an api/ folder yet, leave Root Directory empty and write the build output where Vercel looks for it, per project:
./node_modules/.bin/devora build --app=app --adapter=vercel --out=.vercel/output
Set that as the build command in each project's dashboard (one repo-root vercel.json can't hold several commands), with Framework Preset "Other".
One login across the apps
On separate subdomains, browsers keep a separate cookie per host. To share one login between app.example.com and admin.example.com, set shared.sessions.cookie.domain: "example.com"; the build checks every shared app is under it. Bearer tokens aren't affected.
The full guide, including Netlify, Docker and a plain VPS, is on Deployment.