Skip to content

Full-stack frameworks

Deploy a React Router app on Enzonic

React Router 7 in framework mode (the successor of Remix) builds with react-router build. Deploy serves the server build with react-router-serve, or deploys a static single-page app when react-router.config sets ssr: false.

At a glance

What Enzonic Deploy does with a React Router project when you connect it. You can override any of it in the project settings.

Language
JavaScript / TypeScript
Detected from
@react-router/dev in dependencies; react-router.config.ts, .js or .mjs (read to spot ssr: false)
Build command
react-router build
Output
build (server) or build/client (SPA)
Runs as
Server or SPA

Dependencies install with the package manager your lockfile names: npm ci, pnpm install --frozen-lockfile, yarn install --immutable (Berry) or --frozen-lockfile, or bun install --frozen-lockfile. Node.js 18, 20, 22 and 24 are available. Deploy reads engines.node in package.json, then .nvmrc or .node-version, and uses Node.js 22 when nothing pins a version.

How it runs

  • Server

    The default: build/server/index.js is started with react-router-serve.

  • SPA

    When react-router.config sets ssr: false: build/client is served and every route falls back to index.html.

Deploy React Router step by step

  1. 1Keep @react-router/serve in dependencies for server mode.
  2. 2Connect the repository on deploy.enzonic.com and deploy.
react-router.config.ts
import type { Config } from '@react-router/dev/config';

export default {
  // true (default): server rendering on Enzonic. false: a static SPA.
  ssr: true,
} satisfies Config;

Connect a database to React Router

Create a database on Enzonic Databases (or from the project's settings) and its connection string is added to the project's environment variables. This example uses PostgreSQL.

app/routes/home.tsx
import postgres from 'postgres';
import type { Route } from './+types/home';

const sql = postgres(process.env.DATABASE_URL!);

export async function loader() {
  return { posts: await sql`select id, title from posts limit 20` };
}

export default function Home({ loaderData }: Route.ComponentProps) {
  return <ul>{loaderData.posts.map((p) => <li key={p.id}>{p.title}</li>)}</ul>;
}

Postgres projects get two variables: DATABASE_URL through the connection pooler for the app, and DATABASE_URL_UNPOOLED for migrations.

PostgreSQL on Enzonic DatabasesEvery database engine

Things to know

  • Prerendered routes (prerender in the config) are served as files; loaders of those routes run at build time, so the database must be reachable from the build too.

Plan limits that matter here

From the live plan data. Every plan includes previews for each branch, instant rollback, environment variables and logs.

Plan limits that matter for React Router
LimitFreePro
Build minutes3,000/mo, 1 concurrent10,000/mo, 3 concurrent
Servers1 instance, 512 MB, sleeps after 15 min idle3 always-on, 2 GB
Bandwidth150 GB/mo2 TB/mo

Compare every plan

Related guides

Ship your React Router project tonight

Connect the repository and the build settings fill themselves in. Free plan, no card.

Start free