← ClaudeAtlas

vercel-node-serverlesslisted

Deploy an existing file-based Node/Express app (HTML/CSS/JS frontend served by an Express server, data in a JSON file) to Vercel serverless — and fix the gotchas that silently break it there. Use this whenever someone wants to put a Node/Express, HTML+API, or "server.js" style site live on Vercel, connect a custom domain, or is confused why a site that "works locally" is broken in production: unstyled pages / 404 assets, data that disappears after a while (logins fail, orders vanish, admin edits reset), or emails that never arrive. Also use when adding persistent storage (Postgres/Neon) to a JSON-file app, or a manual bKash/Nagad (Bangladesh mobile-money) payment + order flow. Trigger even if the user only says "deploy my site to Vercel", "my Vercel site looks broken", "make logins persist", or "sign-in stopped working in production" — the serverless traps below apply to almost every file-based Node app.
hellokianben-collab/vishal-agarwal-context · ★ 0 · DevOps & Infrastructure · score 60
Install: claude install-skill hellokianben-collab/vishal-agarwal-context
# Shipping a file-based Node/Express app to Vercel serverless Vercel does **not** run your `node server.js` as a long-lived process. It bundles your app into a **serverless function** that spins up per request, runs on a **read-only, ephemeral filesystem**, and is **frozen the moment you send the HTTP response**. Almost everything that "works on localhost but breaks on Vercel" traces back to one of those three facts. This skill is the checklist of what breaks and how to fix it, learned the hard way. Work top to bottom the first time. On a repeat visit, jump to the symptom. ## 0. The mental model (read this first) | Local (`node server.js`) | Vercel serverless | |---|---| | One process stays alive | Function starts per request, dies after | | Disk is writable + persistent | Disk is **read-only except `/tmp`**, wiped on cold start | | `app.listen()` holds the port | The **exported `app`** is invoked; `listen()` is meaningless | | Work after `res.send()` still runs | Function is **frozen after the response** — trailing async is dropped | | Files next to `server.js` are readable | Only files **explicitly bundled** are present | Keep this table in mind; each fix below is just honoring one row. ## 1. Make Express run as a function Vercel's `@vercel/node` invokes the module's **exported Express app** as the handler. Two things must be true: 1. `server.js` ends with `module.exports = app;` 2. `app.listen()` is guarded so it only runs locally — on Vercel it's dead weight an