Skip to main content
A React app built with Vite is just a Node.js project that produces static files. Nubo runs your build, then a small server to serve the dist/ folder.

Set up

npm create vite@latest my-app -- --template react
cd my-app
npm install
npm install serve
serve is what runs in production. Vite is for building. In package.json, set a start script that boots serve against the build output:
package.json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "start": "serve -s dist -l ${PORT:-3000}"
  }
}
The -s flag tells serve to fall back to index.html for unknown routes (so client-side routing works). The -l ${PORT:-3000} makes it respect Nubo’s port. Test locally:
npm run build
PORT=3000 npm start
# open http://localhost:3000

Deploy

Push to GitHub, then in the Nubo dashboard:
1

New Frame

Open your Project and Space, hit + Frame.
2

Pick the repo and branch

Connect your GitHub repo. Choose the branch Nubo should watch.
3

Confirm the port

Default 3000. Set it to whatever your start script listens on.
4

Deploy

Hit deploy. Nubo runs npm install, npm run build, then npm start.

Client-side routing (React Router)

serve -s already redirects unknown paths to index.html. If you use a different static server, make sure it does the same. Otherwise hitting /dashboard directly returns 404.

Things that trip people up

  • No start script. Without npm start, Nubo tries node index.js which doesn’t exist in a Vite project. Define start explicitly.
  • vite preview in start. vite preview is for local checking only; it’s not a production server. Use serve or another static server.
  • Hardcoded serve -l 3000. Use ${PORT:-3000} so the Frame’s port setting actually applies.

Going truly static

If you don’t need a Node container, build locally and deploy with the Static pack instead: commit your dist/ (or rename it to public/) and remove package.json from the repo. Nubo will then ship the files behind nginx with no Node runtime at all. Useful for cheap landing pages; not useful when you want to redeploy from a git push.

How the build works

Uses the Node.js pack of Raypacks. Same flow as any Node app: install, build, start.