From Next.js (15 & 16)
This guide takes a standard Next.js app and runs it on the brrrd runtime. It is the runtime half of a migration; if your data is in Cloudflare D1, do the Cloudflare guide instead (it includes this runtime work plus the database move).
1. Add the brrrd adapter
Section titled “1. Add the brrrd adapter”pnpm add @brrrd/adapterWire it into your Next config via Next’s adapterPath. If your config is ESM
(next.config.ts / .mjs), resolve the adapter with createRequire:
import type { NextConfig } from "next";import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const nextConfig: NextConfig = { adapterPath: require.resolve("@brrrd/adapter"), // If you talk to libSQL over websockets, keep the ws client external: serverExternalPackages: ["@libsql/isomorphic-ws"],};
export default nextConfig;Remove any other hosting adapter (e.g. OpenNext / @opennextjs/cloudflare init)
— brrrd is now your target.
2. Build
Section titled “2. Build”next build --webpackThe adapter emits a deployable package at dist/brrrd. That directory is
what you hand to comwit deploy.
3. (If you need a database) create one on Louhi
Section titled “3. (If you need a database) create one on Louhi”comwit databases create --project <projectId> --name app-dbCopy the one-time database_token from the output (it is shown once). Your app
connects with the returned database_url + token — see
Create & connect a database. You will set these
as environment variables in step 5.
4. Apply the runtime checklist
Section titled “4. Apply the runtime checklist”brrrd runs your app in V8 isolates. These are the constraints that actually bite, each with a one-line fix. Skim them now — they are cheaper to fix before the first deploy than to debug after.
-
No native
.nodeaddons.next/og’sImageResponsepulls insharpon the Node runtime, which isolates can’t load. Make OG/icon routes run on the edge runtime (a WASM encoder is used instead):app/opengraph-image.tsx (and icon routes) export const runtime = "edge";@brrrd/adapteralready forcesimages.unoptimizedfor you (there is nosharpin the isolate), so you don’t strictly need to set it — addingimages: { unoptimized: true }yourself is harmless and just makes the intent explicit. -
Middleware matchers: no regex look-around. brrrd’s matcher engine rejects negative lookahead like
/((?!api|_next/static).*)(you’ll see “look-around not supported”). Use a match-all matcher and filter inside the function:middleware.ts export const config = { matcher: "/:path*" };// …then early-return for paths you want to skip inside middleware(). -
30s request wall-clock. A single request may run up to ~30s. Move anything longer (heavy jobs, long streams) off the request path.
-
public/assets are served by the adapter, with correct MIME types for common file types (images, video, audio, fonts, PDF, CSV, ZIP…) and HTTP Range support, so<video>/<audio>stream and seek. Only unrecognized/exotic extensions fall back toapplication/octet-stream.
5. Set environment and deploy
Section titled “5. Set environment and deploy”Create the app, set any env it needs, and deploy the build:
comwit apps create --project <projectId> --name web
# Plain env values only (no secret store yet). For a Louhi DB:# PUT /v1/projects/{projectId}/apps/{appId}/environment/DATABASE_URL { "value": "...", "secret": false }# PUT /v1/projects/{projectId}/apps/{appId}/environment/DATABASE_AUTH_TOKEN { "value": "...", "secret": false }
comwit deploy \ --project <projectId> \ --app <appId> \ --package ./dist/brrrd \ --host app.example.comSee Deploy an app for all deploy flags, and Environment variables for how env is applied (plain values only — keep real secrets out for now). To attach a custom domain, see Custom hostnames.
Next 15 — upgrade to 16
Section titled “Next 15 — upgrade to 16”Because the adapter requires Next ^16.2, bump first:
pnpm add next@^16.2 react@^19 react-dom@^19Then run next build --webpack and fix anything the Next 16 upgrade surfaces
before applying the steps above. The Next.js codemods (npx @next/codemod@latest upgrade) handle most breaking changes; the brrrd-specific work is the same as
for any Next 16 app.
Verify
Section titled “Verify”After deploy, hit your hostname and check the pages render (not just that the
build passed — isolate-only runtime errors don’t show up at build time). Then
roll forward normally with comwit deploy, or automate it from
GitHub Actions.