Migrate from Vercel to Netlify with an AI agent
Migrating a Vercel project to Netlify typically involves manual configuration changes, runtime adjustments, and careful mapping of platform-specific features. An AI agent workflow can automate this process, handling everything from directory structure to runtime conversions.
This guide demonstrates how to use a specialized AI prompt to migrate Vercel projects to Netlify, automatically addressing Edge Function runtime differences, API route mappings, environment variable syntax, and build configuration.
Prerequisites
Section titled “Prerequisites”Before starting the migration, ensure you have:
- Netlify CLI installed and authenticated (installation guide)
- Access to your Vercel project repository with read/write permissions
- An AI coding assistant that supports custom prompts (such as Windsurf, Cursor, or GitHub Copilot)
- Node.js and npm for dependency management
Understanding the migration scope
Section titled “Understanding the migration scope”The AI agent handles comprehensive cross-platform conversions:
Directory mappings
Section titled “Directory mappings”| Vercel | Netlify | Notes |
|---|---|---|
/api | netlify/functions | Serverless functions with Node runtime |
/edge | netlify/edge-functions | Edge runtime (Deno-based) |
| Vercel ISR | On-Demand Builders or Edge Functions | Revalidation patterns |
| Vercel KV/Blob | @netlify/blobs | Key-value and blob storage |
| Vercel Images | Netlify Image CDN | Automatic image optimization |
| Vercel Cron | Scheduled Functions | Background jobs |
Runtime differences
Section titled “Runtime differences”Critical distinction: Vercel Edge Functions run on the Node.js runtime, while Netlify Edge Functions use Deno. The agent automatically:
- Rewrites
process.envtoNetlify.env.get() - Converts Node-specific imports to Deno-compatible syntax
- Adds
node:prefix for built-in modules or uses URL imports - Updates function signatures to match Netlify conventions
- Converts functions to
.mts(ESM TypeScript) format
Configuration transformations
Section titled “Configuration transformations”The agent creates or updates your netlify.toml with proper build settings:
[build] command = "npm run build" publish = ".next" # or "dist" depending on framework
[build.environment] NODE_VERSION = "20"
[functions] directory = "netlify/functions"
[build.edge_functions] directory = "netlify/edge-functions"Migration workflow
Section titled “Migration workflow”Step 1: Prepare the AI prompt
Section titled “Step 1: Prepare the AI prompt”Use this specialized migration prompt with your AI coding assistant. The prompt enforces Netlify conventions and handles platform differences:
task: migrate_projectdescription: > Convert existing Vercel project to fully functional Netlify deployment. Ensure total compliance with Netlify conventions and runtime.
REQUIREMENTS: - must_build_with: netlify build - must_deploy_with: netlify deploy - must_pass_local_test: netlify dev - runtime_edge: Deno (no Node-only syntax) - runtime_functions: ESM + TypeScript (.mts) - use_env: Netlify.env.get() - never_use: process.env - ensure_latest_next: true
mappings: vercel_edge → netlify/edge-functions vercel_api → netlify/functions vercel_isr → on-demand builders or edge vercel_kv_blob → @netlify/blobs vercel_image → Netlify Image CDN vercel_cron → scheduled functions env → Netlify dashboard/CLI
directories: functions: netlify/functions edge: netlify/edge-functions ignore: .netlify
dependencies: - "@netlify/functions@latest" - "@netlify/edge-functions@latest" - "@netlify/blobs@latest"
netlify_toml: build.command: npm run build build.publish: .next or dist functions.directory: netlify/functions build.edge_functions: netlify/edge-functions
verify: - npm install success - netlify dev success - all routes respond - no syntax errors - env accessible
notes: - Edge uses Deno; adapt imports accordingly - prefer URL imports or node: prefix - no global side effects - update Next.js versions if build fails - doc_ref: https://docs.netlify.com/ai-context/netlify-development.mdcStep 2: Run the AI agent
Section titled “Step 2: Run the AI agent”- Open your Next.js Vercel project directory in an AI-powered code editor or navigate to your project directory in your terminal if using an AI coding assistant there.
- Provide the migration prompt to the AI assistant with instructions to migrate the project
- Let the agent analyze your project structure, dependencies, and Vercel-specific configurations
The agent will:
- Scan your repository for Vercel-specific patterns
- Identify API routes in
/apior/pages/api - Detect Edge Functions in
/edgedirectories - Read your
vercel.jsonconfiguration - Map environment variables and build settings
Step 3: Review automated changes
Section titled “Step 3: Review automated changes”The AI agent will make several categories of changes:
Directory restructuring
Section titled “Directory restructuring”# Before (Vercel structure)api/ hello.js users.jsedge/ geolocation.js
# After (Netlify structure)netlify/ functions/ hello.mts users.mts edge-functions/ geolocation.tsEnvironment variable conversions
Section titled “Environment variable conversions”// Before (Vercel)const apiKey = process.env.API_KEY;
// After (Netlify Edge Function)import { Config } from "@netlify/edge-functions";
export default async (request: Request, context: Context) => { const apiKey = Netlify.env.get("API_KEY"); // ... function logic};
export const config: Config = { path: "/api/geolocation"};Import statement updates for Deno
Section titled “Import statement updates for Deno”// Before (Node.js imports)import { parse } from 'url';import crypto from 'crypto';
// After (Deno-compatible)import { parse } from 'node:url';import crypto from 'node:crypto';// Or use Deno's built-in URL APINext.js version updates
Section titled “Next.js version updates”If your project uses Next.js, the agent may update to version 13.5+ to ensure compatibility with Netlify’s zero-configuration Next.js support:
{ "dependencies": { "next": "^14.0.0" }}Step 4: Install dependencies
Section titled “Step 4: Install dependencies”After the agent completes its changes, install the required Netlify packages:
npm install @netlify/functions @netlify/edge-functions @netlify/blobsStep 5: Test locally
Section titled “Step 5: Test locally”Verify the migration with Netlify’s local development server:
# Start local development environmentnetlify devThis command:
- Runs your build command
- Starts the Netlify Dev server
- Emulates Edge Functions and serverless functions
- Provides access to environment variables
Test your routes:
- Navigate to previously working Vercel endpoints
- Verify Edge Function responses (e.g., geolocation)
- Check API route functionality
- Test form submissions if applicable
Step 6: Build and deploy
Section titled “Step 6: Build and deploy”Once local testing succeeds, deploy to Netlify:
# Build for productionnetlify build
# Deploy to productionnetlify deploy --prodThe agent ensures your netlify.toml is configured correctly, so the deployment should succeed without additional configuration.
Runtime considerations
Section titled “Runtime considerations”Edge Functions (Deno runtime)
Section titled “Edge Functions (Deno runtime)”Netlify Edge Functions run on Deno, not Node.js. Key differences:
Import requirements:
// Correct: Use node: prefix for built-in modulesimport { Buffer } from "node:buffer";
// Correct: Use URL imports for Deno modulesimport { serve } from "https://deno.land/std/http/server.ts";
// Incorrect: Node-style imports won't workimport { Buffer } from "buffer";Environment variables:
// Correct: Netlify environment APIconst dbUrl = Netlify.env.get("DATABASE_URL");
// Incorrect: process.env not available in Denoconst dbUrl = process.env.DATABASE_URL;No global side effects: Edge Functions should not have top-level side effects. Initialize within the handler function.
Serverless Functions (Node runtime)
Section titled “Serverless Functions (Node runtime)”Netlify serverless functions use Node.js and support CommonJS or ESM:
// netlify/functions/api.mtsimport type { Config } from "@netlify/functions";
export default async (req: Request) => { const data = await fetch("https://api.example.com/data"); return new Response(JSON.stringify(await data.json()), { headers: { "Content-Type": "application/json" } });};
export const config: Config = { path: "/api/data"};Environment variables
Section titled “Environment variables”Migrating from Vercel
Section titled “Migrating from Vercel”- Export from Vercel: Download your environment variables from the Vercel dashboard
- Import to Netlify: Use the Netlify UI or CLI:
# Set individual variablesnetlify env:set API_KEY "your-key-value"
# Import from .env filenetlify env:import .env- Update code references: The AI agent should handle this, but verify all
process.envreferences in Edge Functions are converted toNetlify.env.get()
Scoped variables
Section titled “Scoped variables”Configure environment variable scopes for different contexts:
- Production: Live site environment variables
- Deploy Previews: Variables for pull request previews
- Branch deploys: Branch-specific configurations
Verification checklist
Section titled “Verification checklist”After migration, confirm:
- Build succeeds:
netlify buildcompletes without errors - Local dev works:
netlify devruns and serves all routes - Functions respond: All API endpoints return expected responses
- Edge Functions execute: Test edge routes (check headers, geo data, etc.)
- Environment variables accessible: Verify all env vars load correctly
- Images optimize: Confirm Netlify Image CDN processes images
- Redirects work: Test redirect rules from
netlify.tomlor_redirects - Forms submit: If using forms, verify submissions work
- No console errors: Check browser console and build logs
Troubleshooting
Section titled “Troubleshooting”Build failures
Section titled “Build failures”Next.js version mismatch:
# Update to supported versionnpm install next@latestMissing dependencies:
npm install @netlify/functions @netlify/edge-functionsCache and dependency conflicts: If you encounter persistent build or installation errors, clear the cache and update packages:
# Clear npm cachenpm cache clean --force
# Remove node_modules and lock filerm -rf node_modules package-lock.json
# Reinstall with latest versionsnpm installRuntime errors
Section titled “Runtime errors”Edge Function errors (Deno):
- Verify imports use
node:prefix or URL imports - Check that no Node-only packages are imported
- Ensure environment variables use
Netlify.env.get()
Function timeout: Netlify Functions have a 10-second timeout (26 seconds for Pro plans). For long-running tasks, consider:
- Background Functions for tasks up to 15 minutes
- Splitting work across multiple function calls
- Using Netlify Queues for asynchronous processing
Environment variable issues
Section titled “Environment variable issues”If variables aren’t accessible:
- Verify they’re set in the Netlify dashboard for the correct deploy context
- Check that Edge Functions use
Netlify.env.get()instead ofprocess.env - Confirm variable names match exactly (case-sensitive)
Example: Geolocation Edge Function migration
Section titled “Example: Geolocation Edge Function migration”Here’s a real-world example of migrating a Vercel Edge Function that returns visitor geolocation:
Before (Vercel)
Section titled “Before (Vercel)”// edge/geolocation.jsexport const config = { runtime: 'edge' };
export default async function handler(request) { const country = request.geo.country || 'Unknown'; const city = request.geo.city || 'Unknown';
return new Response(JSON.stringify({ country, city }), { headers: { 'content-type': 'application/json' } });}After (Netlify)
Section titled “After (Netlify)”// netlify/edge-functions/geolocation.tsimport type { Config, Context } from "@netlify/edge-functions";
export default async (request: Request, context: Context) => { const country = context.geo?.country?.name || "Unknown"; const city = context.geo?.city || "Unknown";
return new Response(JSON.stringify({ country, city }), { headers: { "content-type": "application/json" } });};
export const config: Config = { path: "/api/geolocation"};Key changes:
- TypeScript types imported from
@netlify/edge-functions - Geolocation accessed via
context.geoinstead ofrequest.geo - Explicit
Configexport defines the route path - Uses Deno-compatible syntax
Resources
Section titled “Resources”Migration tools and examples
Section titled “Migration tools and examples”- Netlify AI context reference: Netlify Development MDC
Netlify documentation
Section titled “Netlify documentation”- Edge Functions overview
- Serverless Functions guide
- Next.js on Netlify
- Environment variables setup
- Netlify Image CDN
- Netlify Blobs storage
Additional resources
Section titled “Additional resources”Did you find this doc useful?
Your feedback helps us improve our docs.