@exortek/remix-express
v2.0.0
Published
Express adapter for React Router v7 / Remix
Maintainers
Readme
@exortek/remix-express
Express middleware for React Router v7 / Remix v2.
Handles the Vite dev server in development and static asset serving in production — you bring your own Express app.
Compatibility
| Package | React Router | Remix | Express |
|---------|:------------:|:-----:|:-------:|
| ^2.x | ^7.x | ^2.x | ^5.x |
Installation
React Router v7
npm install @exortek/remix-express @react-router/node react-router react react-domor
yarn add @exortek/remix-express @react-router/node react-router react react-domRemix v2
npm install @exortek/remix-express @remix-run/node @remix-run/server-runtime react react-domor
yarn add @exortek/remix-express @remix-run/node @remix-run/server-runtime react react-domUsage
// server.mjs
import express from 'express';
import remixExpress from '@exortek/remix-express';
const app = express();
app.use(await remixExpress({ mode: process.env.NODE_ENV }));
app.listen(3000);With load context
app.use(await remixExpress({
mode: process.env.NODE_ENV,
getLoadContext: (req, res) => ({
db: dbClient,
user: req.user,
}),
}));TypeScript
import express from 'express';
import remixExpress from '@exortek/remix-express';
import type { RemixExpressOptions } from '@exortek/remix-express';
const app = express();
const options: RemixExpressOptions = {
mode: process.env.NODE_ENV,
getLoadContext: (req, res) => ({
db: dbClient,
}),
};
app.use(await remixExpress(options));
app.listen(3000);How it works
- Development — mounts the Vite dev server as middleware (
middlewareMode: true) with HMR viavirtual:react-router/server-build. - Production — serves static assets from
build/clientviaexpress.static, then routes all requests through React Router / Remix.
remixExpress is async because the Vite dev server setup happens at initialization time, not per request.
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| buildDirectory | string | 'build' | Root build output directory |
| clientDirectory | string | 'client' | Client assets sub-directory |
| serverDirectory | string | 'server' | Server build sub-directory |
| serverBuildFile | string | 'index.js' | Server entry filename |
| mode | string | NODE_ENV | 'development' or 'production' |
| getLoadContext | Function | undefined | Returns React Router AppLoadContext passed to loaders/actions |
| expressStaticOptions | object | {} | Options forwarded to express.static (production only) |
| viteOptions | object | {} | Options forwarded to Vite dev server (development only) |
getLoadContext
Use getLoadContext to pass server-side data (database clients, auth info, environment variables, etc.) into your route loaders and actions via the context parameter.
// server.mjs
app.use(await remixExpress({
getLoadContext: (req, res) => ({
db: dbClient,
env: process.env,
}),
}));
// routes/dashboard.tsx
export async function loader({ context }) {
const posts = await context.db.query('SELECT * FROM posts');
return { posts };
}