Vercel
How it differs from Node/Bun
Section titled “How it differs from Node/Bun”| Node / Bun | Vercel / Netlify | |
|---|---|---|
| Config | routesDir string | ServerlessConfig object |
| Route discovery | loadRoutes() at startup | Pre-built manifest |
| Build step | Optional | Required (lacis build) |
Project structure
Section titled “Project structure”my-app/├── api/│ └── [...slug].ts ← Vercel catch-all handler├── routes/│ ├── users/│ │ └── index.ts│ └── posts/│ └── [id]/│ └── index.ts└── vercel.jsonAPI handler
Section titled “API handler”// api/[...slug].tsimport { vercelAdapter } from 'lacis/adapters'import { routes, middlewares } from '../routes/_manifest.js'
const handler = vercelAdapter.createHandler({ routes, middlewares })
export default handlervercel.json
Section titled “vercel.json”{ "rewrites": [ { "source": "/(.*)", "destination": "/api/slug" } ]}Deploy flow
Section titled “Deploy flow”-
Add
lacis buildto your build command inpackage.json:{"scripts": {"build": "lacis build"}} -
Commit your handler:
Terminal window git add api/ vercel.jsongit commit -m "add lacis vercel handler" -
Deploy:
Terminal window vercel deploy --prodVercel runs
lacis buildautomatically on each deploy, regenerating the routes manifest.
Optional config
Section titled “Optional config”const handler = vercelAdapter.createHandler({ routes, middlewares, cors: { origin: 'https://myapp.com', credentials: true }, hooks: { onNotFound: async (req, res) => { res.status(404).json({ error: 'Not found', path: req.url }) }, },})