Vercel Edge Deployment

Deploy your MoroJS applications to Vercel Edge Runtime for ultra-fast performance and global distribution with zero cold starts.

Quick Start

MoroJS provides native support for Vercel Edge Runtime with the same API you use for Node.js development.

Basic Edge Function

typescript

1// api/hello.ts
2import { createAppEdge } from '@morojs/moro';
3
4const app = createAppEdge();
5
6app.get('/', () => {
7  return { message: 'Hello from Vercel Edge!' };
8});
9
10app.post('/users', {
11  body: z.object({
12    name: z.string(),
13    email: z.string().email()
14  }),
15  handler: ({ body }) => {
16    return {
17      success: true,
18      user: body
19    };
20  }
21});
22
23// Export for Vercel
24export default app.getHandler();
25
26// Optional: Export specific HTTP methods
27export const GET = app.getHandler();
28export const POST = app.getHandler();

Edge Runtime Benefits

  • • Zero cold start latency
  • • Global edge deployment
  • • Automatic scaling
  • • Smaller bundle sizes
  • • Enhanced security

Project Structure

Recommended Project Structure

typescript

1my-moro-app/
2├── api/
3│   ├── auth/
4│   │   ├── login.ts
5│   │   └── callback.ts
6│   ├── users/
7│   │   ├── index.ts
8│   │   └── [id].ts
9│   └── hello.ts
10├── lib/
11│   ├── auth.ts
12│   ├── db.ts
13│   └── utils.ts
14├── package.json
15├── vercel.json
16└── tsconfig.json
17
18// package.json
19{
20  "name": "my-moro-app",
21  "version": "1.0.0",
22  "scripts": {
23    "dev": "vercel dev",
24    "build": "tsc",
25    "deploy": "vercel"
26  },
27  "dependencies": {
28    "@morojs/moro": "^1.0.0",
29    "zod": "^3.22.0"
30  },
31  "devDependencies": {
32    "@vercel/node": "^3.0.0",
33    "typescript": "^5.0.0",
34    "vercel": "^32.0.0"
35  }
36}
37
38// vercel.json
39{
40  "functions": {
41    "api/**/*.ts": {
42      "runtime": "@vercel/edge"
43    }
44  },
45  "regions": ["all"]
46}

Advanced Edge Configuration

Edge-Optimized Application

typescript

1// api/app.ts
2import { createAppEdge } from '@morojs/moro';
3import { z } from 'zod';
4
5const app = createAppEdge({
6  // Edge-specific configuration
7  runtime: {
8    // Memory limit for edge function
9    memory: 128, // MB
10    
11    // Maximum execution duration
12    maxDuration: 30, // seconds
13    
14    // Regions to deploy to
15    regions: ['iad1', 'sfo1', 'fra1'], // or 'all'
16  },
17  
18  // CORS for edge
19  cors: {
20    origin: ['https://myapp.com', 'https://admin.myapp.com'],
21    credentials: false // Cookies not supported in edge
22  },
23  
24  // Edge-compatible features only
25  features: {
26    // File system not available in edge
27    fileSystem: false,
28    
29    // Streaming responses supported
30    streaming: true,
31    
32    // WebCrypto API available
33    crypto: true
34  }
35});
36
37// Global middleware for edge
38app.use(async (context, next) => {
39  // Add edge-specific headers
40  context.response.headers.set('X-Edge-Runtime', 'vercel');
41  context.response.headers.set('X-Edge-Region', process.env.VERCEL_REGION || 'unknown');
42  
43  await next();
44});
45
46// Geolocation-aware routing
47app.get('/api/location', {
48  handler: ({ request }) => {
49    // Access Vercel edge headers
50    const country = request.headers.get('x-vercel-ip-country') || 'unknown';
51    const city = request.headers.get('x-vercel-ip-city') || 'unknown';
52    const region = request.headers.get('x-vercel-ip-country-region') || 'unknown';
53    
54    return {
55      country,
56      city,
57      region,
58      timezone: request.headers.get('x-vercel-ip-timezone'),
59      latitude: request.headers.get('x-vercel-ip-latitude'),
60      longitude: request.headers.get('x-vercel-ip-longitude')
61    };
62  }
63});
64
65export default app.getHandler();

Edge Database Integration

typescript

1// lib/edge-db.ts
2import { createClient } from '@planetscale/database';
3
4// Edge-compatible database clients
5const db = createClient({
6  url: process.env.DATABASE_URL
7});
8
9// Redis for edge (Upstash)
10import { Redis } from '@upstash/redis';
11
12const redis = new Redis({
13  url: process.env.UPSTASH_REDIS_REST_URL,
14  token: process.env.UPSTASH_REDIS_REST_TOKEN
15});
16
17// api/users/[id].ts
18import { createAppEdge } from '@morojs/moro';
19import { db, redis } from '../../lib/edge-db';
20
21const app = createAppEdge();
22
23app.get('/api/users/:id', {
24  params: z.object({
25    id: z.string().uuid()
26  }),
27  handler: async ({ params }) => {
28    // Try cache first
29    const cached = await redis.get(`user:${params.id}`);
30    if (cached) {
31      return JSON.parse(cached);
32    }
33    
34    // Query database
35    const result = await db.execute(
36      'SELECT id, name, email FROM users WHERE id = ?',
37      [params.id]
38    );
39    
40    const user = result.rows[0];
41    if (user) {
42      // Cache for 5 minutes
43      await redis.setex(`user:${params.id}`, 300, JSON.stringify(user));
44    }
45    
46    return user || { error: 'User not found' };
47  }
48});
49
50export default app.getHandler();

Environment Variables

Environment Configuration

typescript

1// .env.local (for development)
2DATABASE_URL=mysql://user:pass@host/db
3UPSTASH_REDIS_REST_URL=https://...
4UPSTASH_REDIS_REST_TOKEN=...
5JWT_SECRET=your-secret-key
6VERCEL_ENV=development
7
8// lib/config.ts
9const config = {
10  database: {
11    url: process.env.DATABASE_URL!
12  },
13  redis: {
14    url: process.env.UPSTASH_REDIS_REST_URL!,
15    token: process.env.UPSTASH_REDIS_REST_TOKEN!
16  },
17  auth: {
18    jwtSecret: process.env.JWT_SECRET!
19  },
20  vercel: {
21    env: process.env.VERCEL_ENV || 'development',
22    region: process.env.VERCEL_REGION || 'local'
23  }
24};
25
26export default config;
27
28// Vercel CLI commands for environment variables
29// vercel env add JWT_SECRET production
30// vercel env add DATABASE_URL production
31// vercel env pull .env.local

Deployment Process

Deploy to Vercel

typescript

1# Install Vercel CLI
2npm install -g vercel
3
4# Login to Vercel
5vercel login
6
7# Deploy from project directory
8vercel
9
10# Or deploy with specific configuration
11vercel --prod
12
13# Deploy with environment variables
14vercel --prod --env DATABASE_URL=@database-url
15
16# GitHub Integration (automatic deployments)
17# 1. Connect your GitHub repository to Vercel
18# 2. Push to main branch triggers production deployment
19# 3. Push to other branches triggers preview deployments
20
21# Package.json scripts for easy deployment
22{
23  "scripts": {
24    "dev": "vercel dev",
25    "build": "tsc",
26    "deploy:preview": "vercel",
27    "deploy:prod": "vercel --prod",
28    "logs": "vercel logs"
29  }
30}

GitHub Actions Deployment

typescript

1# .github/workflows/deploy.yml
2name: Deploy to Vercel
3
4on:
5  push:
6    branches: [main]
7  pull_request:
8    branches: [main]
9
10jobs:
11  deploy:
12    runs-on: ubuntu-latest
13    
14    steps:
15      - uses: actions/checkout@v3
16      
17      - name: Setup Node.js
18        uses: actions/setup-node@v3
19        with:
20          node-version: '18'
21          cache: 'npm'
22      
23      - name: Install dependencies
24        run: npm ci
25      
26      - name: Build project
27        run: npm run build
28      
29      - name: Deploy to Vercel
30        uses: amondnet/vercel-action@v25
31        with:
32          vercel-token: ${{ secrets.VERCEL_TOKEN }}
33          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
34          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
35          vercel-args: '--prod'
36        if: github.ref == 'refs/heads/main'

Monitoring & Analytics

Edge Function Monitoring

typescript

1// api/metrics.ts
2import { createAppEdge } from '@morojs/moro';
3
4const app = createAppEdge();
5
6// Performance monitoring middleware
7app.use(async (context, next) => {
8  const start = Date.now();
9  
10  await next();
11  
12  const duration = Date.now() - start;
13  const region = process.env.VERCEL_REGION || 'unknown';
14  
15  // Log performance metrics
16  console.log(JSON.stringify({
17    timestamp: new Date().toISOString(),
18    method: context.request.method,
19    path: context.request.url,
20    duration,
21    region,
22    status: context.response.status
23  }));
24  
25  // Add performance headers
26  context.response.headers.set('X-Response-Time', `${duration}ms`);
27  context.response.headers.set('X-Edge-Region', region);
28});
29
30// Health check endpoint
31app.get('/api/health', {
32  handler: () => {
33    return {
34      status: 'healthy',
35      timestamp: new Date().toISOString(),
36      region: process.env.VERCEL_REGION,
37      runtime: 'edge'
38    };
39  }
40});
41
42export default app.getHandler();
43
44// Vercel Analytics integration
45import { track } from '@vercel/analytics';
46
47app.post('/api/events', {
48  body: z.object({
49    event: z.string(),
50    properties: z.record(z.any()).optional()
51  }),
52  handler: ({ body }) => {
53    // Track custom events
54    track(body.event, body.properties);
55    
56    return { success: true };
57  }
58});

Next Steps