To host a Nuxt app in South Africa, build it with nuxt build, which uses Nitro's default node-server preset, and run the result with node .output/server/index.mjs on any host that runs Node.js. The .output folder is self-contained, runtime settings come from NUXT_ environment variables, and the port comes from PORT. This guide covers the build output, configuration, static generation as an alternative and deploying on local servers.
How Nuxt runs in production
Nuxt's server engine, Nitro, compiles your app into a deployable bundle. What you get depends on the preset:
| Preset | Output | Needs Node.js at runtime |
|---|---|---|
node-server (default) |
.output/server/index.mjs plus .output/public |
Yes |
node-cluster |
Same, but runs multiple workers | Yes |
static (via nuxt generate) |
Plain HTML, CSS and JS in .output/public |
No |
| Platform presets (various) | Serverless or edge functions for a specific provider | Depends on the platform |
For a normal Nuxt app with server routes, SSR, authentication or API endpoints in server/api, the default node-server preset is what you want. It needs a host that can run a long-lived Node.js process, which is exactly what Node.js app hosting provides.
Build and start commands
Your package.json from npm create nuxt@latest includes build, dev, generate and preview scripts. Add a start script for production:
{
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"generate": "nuxt generate",
"preview": "nuxt preview",
"start": "node .output/server/index.mjs"
},
"engines": {
"node": ">=22"
}
}
Then:
npm ci
npm run build
npm start
The build prints the size of .output and the command to run it. Nitro bundles your server code and copies only the dependencies it needs into .output/server/node_modules, so the .output folder can run on its own. You do not need the project's full node_modules at runtime.
Use nuxt preview only for checking a build locally. In production, run the .output server directly with Node.js.
Port and host
The Nitro Node.js server reads its port and host from environment variables:
| Variable | Default | Purpose |
|---|---|---|
PORT or NITRO_PORT |
3000 |
Port to listen on |
HOST or NITRO_HOST |
all interfaces | Address to bind |
Most platforms set PORT for you. If you run behind your own reverse proxy on a VPS, set PORT and proxy to it.
Runtime config and environment variables
Nuxt separates build-time configuration from runtime configuration. Declare runtime values in nuxt.config.ts with safe defaults:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
apiSecret: "", // server-only
databaseUrl: "", // server-only
public: {
apiBase: "/api", // exposed to the browser
},
},
});
Then override them at runtime with environment variables using the NUXT_ prefix and uppercase snake case:
NUXT_API_SECRET=change-me
NUXT_DATABASE_URL=mysql://user:pass@host:3306/app
NUXT_PUBLIC_API_BASE=https://api.example.co.za
Important details:
- Only keys declared in
runtimeConfigcan be overridden. An environment variable with no matching key is ignored. NUXT_PUBLIC_values reach the browser. Never put secrets underpublic.- These are read at runtime, unlike Next.js's
NEXT_PUBLIC_variables, so you can change them and restart without rebuilding. - Read them with
useRuntimeConfig(), not by sprinklingprocess.envthrough your code.
// server/api/orders.get.ts
export default defineEventHandler(async () => {
const config = useRuntimeConfig();
// config.apiSecret and config.databaseUrl are available here, server-side only
return { ok: true };
});
Static generation as an alternative
If your Nuxt site has no server routes and every page can be prerendered (a marketing site or documentation, for example), nuxt generate produces static files in .output/public. You can host those on any web host, including classic web hosting. You lose server routes and per-request rendering, so choose this only if you really do not need them.
A middle ground is hybrid rendering with routeRules: prerender some routes, cache others and keep the rest server-rendered, all inside one node-server build:
export default defineNuxtConfig({
routeRules: {
"/": { prerender: true },
"/blog/**": { swr: 3600 },
"/account/**": { ssr: true },
},
});
Things to check before going live
- Node.js version. Use a current LTS release (Node.js 24, or 22 in maintenance) and pin it in
engines. - Images. If you use
@nuxt/imagewith the default IPX provider, images are processed on your server, which uses CPU and RAM. Resize originals sensibly. - Memory. SSR and large payloads use more RAM than a static site. Measure your app and leave headroom.
- Graceful restarts. Nitro's Node.js server handles shutdown signals, but make sure any database connections you open are closed cleanly too. The same production basics apply as for any Node.js app.
- Case-sensitive imports. Linux servers treat
Header.vueandheader.vueas different files.
Hosting Nuxt on NewHost
NewHost's app hosting runs Nuxt alongside Next.js, Node.js, Express and static sites, on servers in Johannesburg. Setup:
- Connect your GitHub or GitLab repository and choose the production branch.
- Set the install command to
npm ci, the build command tonpm run buildand the start command tonpm start(which runsnode .output/server/index.mjs). - Add your
NUXT_environment variables; they are stored encrypted. - Deploy, add your domain and get a free Let's Encrypt certificate.
Every push to the branch deploys automatically, and on the Developer plan and up each other branch gets its own preview URL. Need a database for your server routes? Add a managed MySQL database. Plans start at R99/month excluding VAT.
Frequently asked questions
What is the start command for a Nuxt app in production?
node .output/server/index.mjs, run after nuxt build. Adding it as the start script in package.json lets any host run it with npm start.
Do I need node_modules on the server to run Nuxt?
Not at runtime. Nitro copies the dependencies the server needs into .output/server/node_modules, so the .output folder is self-contained. You still need dependencies during the build.
Why are my NUXT_ environment variables not working?
The key must be declared in runtimeConfig in nuxt.config.ts, and the variable name must match it in uppercase snake case with the NUXT_ prefix. For example, runtimeConfig.public.apiBase becomes NUXT_PUBLIC_API_BASE.
Can I host Nuxt on shared cPanel hosting?
A fully static site from nuxt generate works on any web host. A server-rendered Nuxt app needs a running Node.js process, so use Node.js app hosting instead. Read Node.js hosting in South Africa for the options.
Want your Nuxt app on local servers, billed in rand? See NewHost Node.js hosting and deploy from Git in a few minutes.