Skip to main content
Deploy your Resolid application to any Node.js environment, including traditional servers, VPS, containers, and cloud platforms.

Configuration

Configure your application for Node.js deployment in resolid.config.ts:
resolid.config.ts
import { defineDevConfig } from "@resolid/dev";

export const { vitePluginOptions, reactRouterConfig } = defineDevConfig({
  appDirectory: "src",
  platform: "node",
  nodeVersion: 22,
});

Configuration Options

platform
string
required
Set to "node" for Node.js deployment
nodeVersion
number
default:"22"
Node.js runtime version (18, 20, 22, or 24)
includeFiles
string[]
Additional files to include in the server bundle (e.g., templates, static assets)

Server Setup

Create your server entry file using createHonoNodeServer:
src/server.ts
import { createHonoNodeServer } from "@resolid/dev/http.server";
import { env } from "node:process";

export default await createHonoNodeServer({
  port: env.SERVER_PORT || 3000,
  defaultLogger: true,
  configure: async (hono) => {
    // Add custom middleware or routes
  },
  getLoadContext: () => {
    // Return context available in route loaders/actions
    return {};
  },
  onShutdown: async () => {
    // Cleanup on server shutdown
  },
});

Server Options

port
number
default:"3000"
Port number for the server to listen on
defaultLogger
boolean
default:"false"
Enable request logging (automatically disabled in production)
configure
function
Function to configure the Hono server instance with custom middleware
getLoadContext
function
Function returning context object available in React Router loaders and actions
onShutdown
function
Cleanup function called when the server shuts down
listeningListener
function
Callback function invoked when the server starts listening

Build Process

1

Build the application

Run the build command to create a production bundle:
npm run build
This command:
  • Compiles client assets to build/client
  • Bundles server code to build/server
  • Generates package.json with production dependencies
  • Optimizes and minifies code for production
2

Install production dependencies

Navigate to the server build directory and install dependencies:
cd build/server
npm install --production
3

Start the server

Run the production server:
node server.mjs
The server will start on the configured port (default: 3000).

Environment Variables

Configure your application using environment variables:
NODE_ENV
string
default:"production"
Application environment mode
SERVER_PORT
number
default:"3000"
Port for the server to listen on
SERVER_PATH
string
Base path for the server (e.g., /api)

Static File Serving

The Node.js server automatically serves static files:
  • Production: Assets from build/client with cache headers
    • Assets directory (/assets/*): Cached for 1 year (immutable)
    • Other static files: Cached for 1 hour
  • Development: Assets from public directory

Process Management

For production deployments, use a process manager like PM2:
npm install -g pm2
pm2 start build/server/server.mjs --name "my-app"
Or use a systemd service:
/etc/systemd/system/my-app.service
[Unit]
Description=My Resolid App
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/my-app
Environment="NODE_ENV=production"
Environment="SERVER_PORT=3000"
ExecStart=/usr/bin/node build/server/server.mjs
Restart=on-failure

[Install]
WantedBy=multi-user.target

Docker Deployment

Example Dockerfile for containerized deployment:
Dockerfile
FROM node:22-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --production

COPY build ./build

EXPOSE 3000

CMD ["node", "build/server/server.mjs"]

Client IP Detection

Get client IP addresses with nodeClientIpGetter:
src/server.ts
import { createHonoNodeServer, nodeClientIpGetter } from "@resolid/dev/http.server";
import { clientIp } from "@resolid/dev/http.server";

export default await createHonoNodeServer({
  configure: async (hono) => {
    hono.use("*", clientIp(nodeClientIpGetter()));
  },
});

Request Origin

Get request origin information:
src/server.ts
import { createHonoNodeServer, nodeRequestOriginGetter } from "@resolid/dev/http.server";
import { requestOrigin } from "@resolid/dev/http.server";

export default await createHonoNodeServer({
  configure: async (hono) => {
    hono.use("*", requestOrigin(nodeRequestOriginGetter(true)));
  },
});

Health Checks

Add health check endpoints for load balancers:
src/server.ts
export default await createHonoNodeServer({
  configure: async (hono) => {
    hono.get("/health", (c) => c.json({ status: "ok" }));
  },
});

Build docs developers (and LLMs) love