ObjectStackObjectStack

Deploy to Vercel

Deploy ObjectStack applications to Vercel with the Hono server adapter.

Deploy to Vercel

ObjectStack 11 deploys to Vercel in server mode — serverless functions running the Hono adapter (@objectstack/hono). The published ObjectStack Studio/console ships as a static Vite SPA that points at a separate ObjectStack server (via VITE_SERVER_URL).

Removed in 11. The in-browser MSW mode (@objectstack/plugin-msw) and the Next.js adapter (@objectstack/nextjs) are no longer published — use the Hono server path below.


Server Mode (Serverless Functions)

In Server mode, ObjectStack runs inside Vercel Serverless Functions. API requests are handled by real backend logic with a real database.

Architecture

┌─── Vercel ────────────────────────────────────────────────────┐
│                                                               │
│  Static Assets (React SPA)                                    │
│  ┌───────────────────────────────────┐                        │
│  │  /index.html, /assets/*           │                        │
│  └───────────────────────────────────┘                        │
│                                                               │
│  Serverless Functions                                         │
│  ┌───────────────────────────────────┐                        │
│  │  /api/[...objectstack]            │                        │
│  │    → ObjectKernel                 │                        │
│  │    → ObjectQL                     │                        │
│  │    → PostgreSQL / MongoDB / ...   │──── External DB        │
│  └───────────────────────────────────┘                        │
│                                                               │
└───────────────────────────────────────────────────────────────┘

Hono serverless function (@objectstack/hono)

This is a valid self-contained pattern when you want to ship a Vite SPA and its API from a single Vercel project: the SPA is served as static assets, and a Hono-based serverless function handles /api/* requests.

The published ObjectStack Studio/console (@object-ui/console) does not use this topology. It deploys as a pure static SPA with no api/ function — it is meant to be embedded in, or pointed at, a separate ObjectStack server via VITE_SERVER_URL. For that separate server, prefer the CLI (objectstack serve) over a hand-rolled Hono function.

1. Create the kernel singleton (api/_kernel.ts — prefixed with _ to prevent Vercel from creating a route):

// api/_kernel.ts
import { ObjectKernel, DriverPlugin, AppPlugin } from '@objectstack/runtime';
import { ObjectQLPlugin } from '@objectstack/objectql';
import { InMemoryDriver } from '@objectstack/driver-memory';
import { createHonoApp } from '@objectstack/hono';
import { Hono } from 'hono';
import appConfig from '../objectstack.config';

let _kernel: ObjectKernel | null = null;
let _app: Hono | null = null;

async function ensureKernel(): Promise<ObjectKernel> {
  if (_kernel) return _kernel;
  _kernel = new ObjectKernel();
  await _kernel.use(new ObjectQLPlugin());
  await _kernel.use(new DriverPlugin(new InMemoryDriver(), 'memory'));
  await _kernel.use(new AppPlugin(appConfig));
  await _kernel.bootstrap();
  return _kernel;
}

export async function ensureApp(): Promise<Hono> {
  if (_app) return _app;
  const kernel = await ensureKernel();
  _app = createHonoApp({ kernel, prefix: '/api/v1' });
  return _app;
}

InMemoryDriver keeps this snippet self-contained, but on serverless all data is lost on every cold start — fine for a demo, wrong for anything real. Before going past a proof of concept, swap the driver for a real database (see Database Drivers) and point OS_DATABASE_URL at it.

2. Create the API entrypoint (api/index.ts):

// api/index.ts
import { Hono } from 'hono';
import { handle } from 'hono/vercel';
import { ensureApp } from './_kernel';

const app = new Hono();

app.all('*', async (c) => {
  const inner = await ensureApp();
  return inner.fetch(c.req.raw);
});

export default handle(app);

3. vercel.json:

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "framework": "vite",
  "buildCommand": "vite build",
  "outputDirectory": "dist",
  "build": {
    "env": {
      "VITE_USE_MOCK_SERVER": "false",
      "VITE_SERVER_URL": ""
    }
  },
  "rewrites": [
    { "source": "/api/(.*)", "destination": "/api" },
    { "source": "/((?!api/).*)", "destination": "/index.html" }
  ]
}

Setting VITE_SERVER_URL to empty string tells the client SDK to use same-origin API calls. The first rewrite routes all /api/* sub-paths to the api/index.ts serverless function. The second rewrite excludes /api/ paths so all other paths serve the SPA.


Environment Variables

Configure these in Vercel Project Settings → Environment Variables:

Studio / SPA build

VariableDescription
VITE_USE_MOCK_SERVERLeave false — the SPA talks to a real backend at VITE_SERVER_URL. (The true in-browser mock mode was removed in 11.) A build-time flag baked into the SPA bundle.
VITE_SERVER_URLBackend API URL (empty for same-origin)

Cloud control plane

The Cloud control-plane distribution lives outside this framework repo. If you deploy a Cloud host on Vercel, remember that Vercel functions have an ephemeral, read-only filesystem — local SQLite and local-FS storage will not persist between invocations. Use a durable database and S3-compatible object storage for artifacts.

VariableRequiredDescription
OS_AUTH_SECRETyes≥ 32 chars (AUTH_SECRET is accepted as a deprecated alias)
OS_CONTROL_DATABASE_URLyeslibsql://… (Turso) — control plane DB
OS_CONTROL_DATABASE_AUTH_TOKENyesTurso token (or TURSO_AUTH_TOKEN)
OS_STORAGE_ADAPTERyess3 (must, on Vercel)
OS_S3_BUCKETyes (s3)Bucket name
OS_S3_REGIONyes (s3)us-east-1, or auto for Cloudflare R2
OS_S3_ENDPOINToptionalFor R2 / MinIO / B2 / non-AWS
OS_S3_ACCESS_KEY_IDoptionalFalls back to AWS SDK credential chain
OS_S3_SECRET_ACCESS_KEYoptionalFalls back to AWS SDK credential chain
OS_S3_FORCE_PATH_STYLEoptional1 for MinIO / self-hosted

The Cloud control plane's storage backend (S3, Cloudflare R2, MinIO, etc.) is configured and documented in that separate distribution, not in this framework repo. See Publish, Versioning & Preview for the package publish/install workflow the control plane exposes to the CLI.

Never commit secrets. Use Vercel's environment variable UI or the Vercel CLI (vercel env add) to configure tokens and S3 credentials.


Deployment Checklist

  • api/index.ts Hono entrypoint exists with handle(app) export
  • api/_kernel.ts boots the kernel with the correct driver
  • vercel.json sets VITE_USE_MOCK_SERVER=false and VITE_SERVER_URL= (empty)
  • Rewrite rule routes /api/* to /api and excludes /api/ from SPA rewrite
  • OS_DATABASE_URL is configured in Vercel environment variables (for production drivers)
  • CORS is configured if frontend and API are on different origins

On this page