Next.js usually runs behind its own dev server, but the Node.js application just runs one entry file. The bridge between the two is Next's standalone output plus a tiny launcher. This guide is the exact, verified recipe to serve a Next.js site on Falix — three small files, and the reason each one exists.
| At a glance | |
|---|---|
| You need | A Falix server running the Node.js application and a Next.js project (yours, or a fresh create-next-app) |
| Time | Twenty-five minutes, plus build time |
If Node on Falix is new to you, read Node.js on Falix first — this builds on its index.js entry file and automatic npm install. A Next.js site is also a natural Git deploy.
The problem, in one line
The Node.js application starts your site by running node index.js. Next.js has no index.js you can run directly — it expects next start behind a build. Standalone output closes that gap: Next can emit a plain-Node server you can run directly.
Three files
Three small files, and the job each one does:
| File | Job |
|---|---|
next.config.js |
Emit a self-contained standalone Node server |
package.json |
Build on install via postinstall, then copy static/public in |
index.js |
Launcher — set PORT/HOSTNAME, then start the standalone server |
1. next.config.js — build a standalone server
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
};
module.exports = nextConfig;
output: 'standalone' tells Next to produce a self-contained server at .next/standalone/server.js after a build — no framework CLI needed to run it, just node. That's the file the Node application can start.
2. package.json — build during the automatic install
The Node application runs npm install on every start when a package.json exists. Hook the build onto that with a postinstall script:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"postinstall": "next build && cp -r .next/static .next/standalone/.next/"
}
}
postinstall runs right after npm install, so every start goes: install dependencies → next build → a fresh standalone server. The cp is not optional: standalone deliberately leaves out .next/static (your compiled CSS and JS chunks), so you copy them in yourself. Skip it and the site loads with no styling at all.
If your project has a public/ folder (create-next-app makes one), mirror it into standalone the same way — this is the standard companion step in Next's own standalone docs:
"postinstall": "next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/"
3. index.js — the launcher (your Main file)
The Node application runs index.js by default, so name the launcher index.js and leave the Main file variable alone:
process.env.PORT = process.env.SERVER_PORT || 3000;
process.env.HOSTNAME = '0.0.0.0';
console.log(`Listening on port ${process.env.PORT}`);
require('./.next/standalone/server.js');
Next's standalone server reads PORT and HOSTNAME from the environment, so the launcher sets them from Falix's SERVER_PORT and 0.0.0.0 before handing off — the two rules from every web app here, applied to Next. The console.log is there on purpose: the panel flips your server to online when it sees the word Listening, and Next's own ready line doesn't contain it, so printing this turns the status green.
Start it — and expect a wait
Press Start. The console runs npm install, then next build. When it finishes you'll see the Listening line and the standalone server boot. Open your server's address from the Network page and the site loads.
💡 Tip: Building a site takes real time, so the first start is slow and can look like it's hanging. It isn't; watch the build output scroll by.
🎯 Good to know: Because the build lives in
postinstall, it reruns on every start. That's the simplest setup, but it means every restart rebuilds.
Environment variables and API routes
Two things people always ask about Next carry over here unchanged.
Environment variables. Next reads them from .env files in your project. Anything the browser needs to see must be prefixed NEXT_PUBLIC_ (for example NEXT_PUBLIC_API_URL); Next inlines those at build time, so the .env has to be present when next build runs — which in this setup is on the server during postinstall. Names without the prefix stay server-only. Keep real secrets out of Git and out of NEXT_PUBLIC_ names — see Keep secrets out of Git.
API routes. Route handlers (app/api/**/route.js or pages/api/**) are bundled straight into the standalone server and answer on the same public port as your pages — no separate service and no extra config.
Deploying from Git
A Next.js project is a natural fit for Deploy from Git. If you'd rather not rebuild on every start, move next build out of postinstall and into a post-deploy command so it runs once per deploy instead — see Build steps on deploy. Leave the launcher and next.config.js exactly as they are; only where the build runs changes.
Troubleshooting
- Page loads but has no styling — the static copy step is missing or failed. Confirm
postinstallends withcp -r .next/static .next/standalone/.next/and that it ran cleanly in the console. - Images or files in
public/return 404 — you didn't copypublic/into standalone. Add the companioncp -r public .next/standalone/. - Start seems stuck for minutes — it's building.
next buildis the slow part; let it finish. A larger site simply takes longer. - Killed mid-build (exit code 137) —
next buildran out of memory, common on big sites and tight on free's 2.5 GB shared RAM. See Out of memory; a plan with more RAM builds reliably.