- A
package.jsonat the repo root. - A
startscript that boots your server. - Your server reads the port from
process.env.PORT.
Quick start
server.js:
server.js
"type": "module" and a start script to package.json:
package.json
Deploy
1
Open the New Frame modal
In your Nubo dashboard, open the Project and Space you want, then hit + Frame.
2
Pick the repo and branch
Connect your GitHub repo and choose the branch Nubo should watch.
3
Confirm the port
The port your app listens on. Matches the
PORT value you read in code.4
Deploy
Hit deploy. Watch the build in the Logs tab.
Package managers
Nubo auto-picks based on your lockfile:
Commit your lockfile. Without one, Nubo falls back to npm. This isn’t fatal but builds are slower and less deterministic.
TypeScript apps
Add abuild script that produces JavaScript and a start script that runs it:
package.json
npm run build automatically when a build script exists.
For a non-standard project, you can override the Install command and Build command per Frame under Frame Settings. Leave them blank to let Raypacks auto-detect from your lockfile and scripts.
Things that trip people up
- No
startscript. Nubo will trynode index.jsas a fallback. If your entry isn’tindex.js, set"main"inpackage.jsonor add astartscript. - Hardcoded port. Read
process.env.PORT, don’t write3000directly. - Listening on
localhost. Use the default Express behavior (app.listen(port)) or bind explicitly to0.0.0.0. - Native modules.
node:22-slimdoesn’t ship build toolchains. Prefer packages with prebuilt binaries, or switch to the Paketo builder.
Framework guides
React (Vite)
Single-page app with a Vite build
Discord.js
Long-running bot, no HTTP listener
How the build works
This guide uses the Node.js pack of Raypacks, Nubo’s default builder. It installs your deps, runs yourbuild script if you have one, and ships on node:22-slim (or oven/bun:slim for bun).
For control beyond what the pack offers, switch the Frame’s Builder to Paketo in Frame Settings.