Deploying to Vercel
Deploy your EreoJS application to Vercel.
Prerequisites
- Vercel account
- Vercel CLI (optional)
Quick Deploy
From GitHub
- Push your code to GitHub
- Go to vercel.com/new
- Import your repository
- Vercel auto-detects EreoJS settings
- Click Deploy
From CLI
# Install Vercel CLI
npm i -g vercel
# Deploy
vercelConfiguration
Using the Vercel Adapter (Recommended)
Install the adapter:
bun add @ereo/deploy-vercelGenerate configuration using @ereo/deploy-vercel:
// scripts/setup-vercel.ts
import { generateVercelJson, generateBuildScript } from '@ereo/deploy-vercel'
// Generate vercel.json
await Bun.write('vercel.json', generateVercelJson({
edge: false, // Use Node.js runtime
regions: ['iad1'] // Optional: specify regions
}))
// Generate build script
await Bun.write('build.sh', generateBuildScript())This generates a vercel.json like:
{
"version": 2,
"builds": [
{
"src": "dist/server.js",
"use": "@vercel/node",
"config": {
"includeFiles": ["dist/**"]
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "dist/server.js"
}
],
"regions": ["iad1"]
}Manual Configuration
If you prefer manual setup, create vercel.json:
{
"version": 2,
"builds": [
{
"src": "dist/server.js",
"use": "@vercel/node",
"config": {
"includeFiles": ["dist/**"]
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "dist/server.js"
}
]
}Build Configuration
Update ereo.config.ts for Vercel using the adapter. The vercel() function sets the build target to 'node' (default) or 'edge':
import { defineConfig } from '@ereo/core'
import { vercel } from '@ereo/deploy-vercel'
export default defineConfig({
...vercel({ edge: false }), // Node.js runtime (default)
// or
// ...vercel({ edge: true }), // Edge runtime
})Configuration Options
| Option | Type | Description |
|---|---|---|
edge | boolean | Use Edge runtime instead of Node.js (default: false) |
regions | string[] | Deployment regions (e.g., ['iad1', 'sfo1']) |
timeout | number | Function timeout in seconds (reserved for future use) |
memory | number | Memory allocation in MB (reserved for future use) |
env | Record<string, string> | Environment variables (reserved for future use) |
Note: Currently,
vercel()uses theedgeoption to set the build target. Theregionsoption is used bygenerateVercelJson(). Thetimeout,memory, andenvoptions are accepted for forward compatibility and will be used in future releases. To configure function timeouts and memory now, set them directly invercel.json(see Troubleshooting).
Manual Configuration (Alternative)
If you prefer not to use the adapter, set the build target directly:
import { defineConfig } from '@ereo/core'
export default defineConfig({
build: {
target: 'node', // 'node' for Vercel Node.js, 'edge' for Vercel Edge
outDir: 'dist'
}
})Edge Runtime Configuration
For Edge runtime, update both the config and vercel.json:
// ereo.config.ts
import { defineConfig } from '@ereo/core'
import { vercel } from '@ereo/deploy-vercel'
export default defineConfig({
...vercel({ edge: true, regions: ['iad1', 'sfo1'] }),
})The generated vercel.json for Edge:
{
"version": 2,
"builds": [
{
"src": "dist/server.js",
"use": "@vercel/edge",
"config": {
"includeFiles": ["dist/**"]
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "dist/server.js"
}
],
"regions": ["iad1", "sfo1"],
"functions": {
"dist/server.js": {
"runtime": "edge",
"regions": ["iad1", "sfo1"]
}
}
}Environment Variables
Via Dashboard
- Go to Project Settings → Environment Variables
- Add your variables
- Redeploy to apply
Via CLI
vercel env add DATABASE_URL productionIn vercel.json
{
"env": {
"PUBLIC_API_URL": "https://api.example.com"
}
}Data Loading on Vercel
EreoJS loaders and actions work the same way on Vercel as on any other platform. Define them in your route files using any of the three approaches:
// routes/posts/index.tsx
import { createLoader, createAction, redirect } from '@ereo/data'
export const loader = createLoader(async ({ params }) => {
const posts = await db.posts.findMany()
return { posts }
})
export const action = createAction(async ({ request }) => {
const formData = await request.formData()
await db.posts.create({ title: formData.get('title') as string })
return redirect('/posts')
})
export default function Posts({ loaderData }) {
return (
<ul>
{loaderData.posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}For a full guide on loaders, actions, and the three different approaches to defining them, see Data Loading.
Vercel Serverless Functions
EreoJS already handles API routes via HTTP method exports in your route files. You only need Vercel-native serverless functions if you want to run code outside the EreoJS router:
// api/posts.ts (Vercel-native function)
import type { VercelRequest, VercelResponse } from '@vercel/node'
export default async function handler(
req: VercelRequest,
res: VercelResponse
) {
if (req.method === 'GET') {
const posts = await getPosts()
return res.json(posts)
}
res.status(405).json({ error: 'Method not allowed' })
}Tip: For most API routes, prefer using EreoJS route files with
GET/POST/PUT/DELETEexports. Use Vercel-native functions only when you need Vercel-specific features outside the EreoJS request pipeline.
Edge Functions
For faster response times at the edge:
// api/hello.ts
export const config = {
runtime: 'edge'
}
export default function handler(request: Request) {
return new Response('Hello from the edge!')
}Static Assets
Static files in public/ are automatically served from Vercel's CDN.
{
"headers": [
{
"source": "/static/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
]
}Redirects and Rewrites
{
"redirects": [
{
"source": "/old-path",
"destination": "/new-path",
"permanent": true
}
],
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://api.example.com/:path*"
}
]
}Preview Deployments
Every pull request gets a preview URL:
https://your-project-git-branch-name-username.vercel.appProduction Deployment
# Deploy to production
vercel --prodOr push to your main branch with auto-deploy enabled.
Monitoring
Vercel provides built-in:
- Analytics
- Speed Insights
- Logs
- Error tracking
Access from your project dashboard.
Troubleshooting
Build Failures
Check build logs in the Vercel dashboard or:
vercel logsFunction Timeouts
Default timeout is 10 seconds. Increase in vercel.json:
{
"functions": {
"api/**/*.ts": {
"maxDuration": 30
}
}
}Memory Issues
{
"functions": {
"api/**/*.ts": {
"memory": 1024
}
}
}Domain Setup
- Go to Project Settings → Domains
- Add your domain
- Configure DNS as shown
- SSL is automatic
CI/CD with GitHub Actions
# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'Related
- Data Loading — Loaders, actions, and all three definition approaches
- Deploying to Cloudflare — Alternative deployment platform
- CLI deploy command — Deploy from the command line