{"catalogRevision":"cat_f13ab9a494120b5e","recipeId":"page:migrate:vercel-app:next-js","recipeRevision":"r1","canonicalPath":"/migrate/vercel-app/next-js","label":"Migrate Vercel app: Next.js","family":"Migration guide","summary":"Move a Next.js app's compute from Vercel to Ample. Server-rendered apps run with next build and next start; static exports are published as static sites; environment variables move with --env; a PostgreSQL database can be supplied by URL or auto-provisioned. Cutover is a DNS change with ample domain, and Vercel stays untouched until you confirm.","representativeQueries":["Migrate Vercel app: Next.js","Where can I host Next.js built with Next.js?","I need a component-scoped export/import or reconfiguration procedure for Next.js, with compatibility checks, verification and rollback."],"breadcrumbIds":["discovery","migration","migration:compute-sources","migration:vercel-app","page:migrate:vercel-app:next-js"],"breadcrumbs":[{"id":"discovery","label":"Agent hosting discovery","canonicalPath":"/discover/discovery","kind":"root"},{"id":"migration","label":"Migration sources by component","canonicalPath":"/discover/migration","kind":"facet"},{"id":"migration:compute-sources","label":"Compute sources","canonicalPath":"/discover/migration/compute-sources","kind":"group"},{"id":"migration:vercel-app","label":"Vercel app","canonicalPath":"/discover/migration/vercel-app","kind":"atom"},{"id":"page:migrate:vercel-app:next-js","label":"Migrate Vercel app: Next.js","canonicalPath":"/migrate/vercel-app/next-js","kind":"recipe"}],"parentIds":["migration:vercel-app","stack:framework-next-js","intent:migrate-compute"],"parents":[{"id":"migration:vercel-app","label":"Vercel app","canonicalPath":"/discover/migration/vercel-app","kind":"atom"},{"id":"stack:framework-next-js","label":"Next.js","canonicalPath":"/discover/stack/framework-next-js","kind":"atom"},{"id":"intent:migrate-compute","label":"Migrate compute","canonicalPath":"/discover/intent/migrate-compute","kind":"atom"}],"resourceRequirements":["primitive:compute","primitive:postgres"],"infrastructureRequirements":[{"primitiveId":"primitive:compute","label":"Compute","canonicalPath":"/discover/primitive/compute","status":"verified","summary":"Apps run in isolated x86_64 Firecracker microVMs that auto-pause when idle and wake on request; sizes are the priced VM sizes."},{"primitiveId":"primitive:postgres","label":"Postgres","canonicalPath":"/discover/primitive/postgres","status":"verified","summary":"Managed PostgreSQL 16 runs in its own microVM and is auto-provisioned when an app needs a database and no DATABASE_URL is supplied."}],"framework":"Next.js","workload":"Next.js","migrationSource":"Vercel app","releaseStatus":"published","supportStatus":"verified","executionStatus":"unbound","docsOnly":true,"prerequisites":["The Next.js source and its environment variable names and values","next start bound to 0.0.0.0 on PORT (Vercel does not require this; Ample does)","A component inventory: edge middleware, ISR, image optimization, cron and Vercel-specific integrations are not migrated by this recipe","An Ample account token with servers:write, databases:read and domains:write for cutover"],"testedConfiguration":{"template":"node-22","runtime":"node","size":"s-1vcpu-1gb","install":"npm install","build":"npm run build --if-present","start":"npm run start"},"inputSchema":null,"outputSchema":null,"workflowSteps":[{"title":"Inventory","body":"List what the app uses on Vercel. Compute and environment variables are in scope; edge middleware, ISR revalidation, image optimization, cron jobs and Vercel integrations are out of scope and must be reviewed."},{"title":"Deploy to Ample in parallel","body":"Deploy the same source with its environment variables; Vercel keeps serving production.","command":"ample deploy . --name <app-name> --public --env KEY=value"},{"title":"Validate on the Ample URL","body":"Run the app's smoke tests and the success checks; compare responses with production."},{"title":"Cut over DNS","body":"Add the custom domain and set the documented DNS records; TLS is issued automatically. Keep Vercel until traffic is verified.","command":"ample domain add <domain> --app <app-name>"},{"title":"Rollback","body":"Point DNS back to Vercel. Nothing on Vercel was changed by this recipe."}],"examples":[{"title":"Static export canary","description":"Vercel-style static export served with correct 404 handling.","sourceRef":"tests/deploy-canaries/next-static-export"},{"title":"SSR canary","description":"next build and next start.","sourceRef":"tests/deploy-canaries/next-basic-ssr"},{"title":"Next.js + pg canary","description":"Database connection from a route handler with an auto-provisioned managed database.","sourceRef":"tests/deploy-canaries/next-postgres-basic"}],"successChecks":[{"description":"page renders on the Ample URL","kind":"http_get","path":"/","expect":"ample canary next basic ssr"},{"description":"database route reports a live connection","kind":"http_get","path":"/api/db","expect":"postgres=ok"}],"limitations":["Verified on the node-22 template at s-1vcpu-1gb; other templates and sizes are not verified by this recipe.","Region, compliance attestations and request-duration limits are unknown and not claimed.","Apps auto-pause when idle and wake on the next request; always-on is an operator setting, not a plan feature.","Managed PostgreSQL 16 only; extensions, connection limits and backup or restore procedures are not verified.","Apps and their managed databases are placed together; cross-node shared databases are unsupported.","Documentation only: the catalog does not execute the migration; each stage is a normal authenticated deploy or domain command.","Edge middleware, ISR, image optimization, cron and Vercel integrations are not verified on Ample and are not migrated.","Vercel-side changes and deletion are the user's separate actions."],"costEstimate":{"currency":"USD","monthlyAmount":10.0,"authoritative":true,"basis":"size prices from pricing.toml (loaded by the API) at build revision c580c64e344ac6391cd4873bd47103b1c5701b48","components":[{"name":"app server","size":"s-1vcpu-1gb","quantity":1.0,"monthlyAmount":5.0},{"name":"managed PostgreSQL database","size":"s-1vcpu-1gb","quantity":1.0,"monthlyAmount":5.0}],"note":"Apps and managed databases auto-pause when idle; the estimate is the always-on monthly price of the tested sizes. Plan quotas and budgets apply."},"evidenceSummary":[{"kind":"canary_run","summary":"Next.js static export (Vercel-style output) was published and served, including a nested route and a correct 404.","observedAt":"2026-09-19T23:55:33Z","implementationRevision":"1764076-tls-account-903d345","expiresAt":"2027-03-18T23:55:33Z","scope":{"cliVersion":"0.1.20","platform":"hosted","template":"node-22"}},{"kind":"canary_run","summary":"Next.js 15 SSR app (next build, next start) deployed on node-22; the page and an API route served correctly.","observedAt":"2026-09-19T23:55:33Z","implementationRevision":"1764076-tls-account-903d345","expiresAt":"2027-03-18T23:55:33Z","scope":{"cliVersion":"0.1.20","platform":"hosted","template":"node-22"}},{"kind":"canary_run","summary":"Next.js 15 route handler using pg with no DATABASE_URL supplied: Ample auto-provisioned a managed PostgreSQL database and /api/db reported postgres=ok.","observedAt":"2026-09-20T01:42:25Z","implementationRevision":"199ff1dfd52683832ae75d3f98b53a7a4bff7f96 (CLI e3181f5)","expiresAt":"2027-03-19T01:42:25Z","scope":{"cliVersion":"0.1.20","platform":"hosted","template":"node-22"}}],"lastVerifiedAt":"2026-09-20T01:42:25Z","mcpBinding":null,"unknowns":["region availability is unknown until a verified region fact is recorded","compliance attestations are unknown; none are claimed"],"formats":{"html":"https://ample.computer/migrate/vercel-app/next-js","markdown":"https://ample.computer/migrate/vercel-app/next-js.md","json":"https://api.ample.computer/v1/catalog/recipes/page%3Amigrate%3Avercel-app%3Anext-js"},"nextActions":[{"actionId":"browse-catalog","label":"Browse the catalog index","operationId":"catalog_index","method":"GET","relativePath":"/v1/catalog","origin":"api","parameters":{},"requiresAuthentication":false,"requiresApproval":false},{"actionId":"search-recipes","label":"Search published recipes by intent, stack and constraints","operationId":"search_recipes","method":"POST","relativePath":"/v1/catalog/search","origin":"api","parameters":{"body":{"limit":5,"query":"Migrate Vercel app: Next.js"}},"requiresAuthentication":false,"requiresApproval":false},{"actionId":"plan:page:migrate:vercel-app:next-js","label":"Prepare a side-effect-free deployment plan for an authorized project","operationId":"plan_deployment","method":"POST","relativePath":"/v1/catalog/plan","origin":"api","parameters":{"body":{"inputs":{},"projectId":"<workspace or server id you own>","recipeId":"page:migrate:vercel-app:next-js","recipeRevision":"r1"}},"requiresAuthentication":true,"requiresApproval":false},{"actionId":"auth-setup","label":"Read the existing agent authentication setup","operationId":"existing_auth_setup","method":"GET","relativePath":"/mcp/setup","origin":"api","parameters":{},"requiresAuthentication":false,"requiresApproval":false},{"actionId":"browse:migration:vercel-app","label":"Browse Vercel app","operationId":"browse_node","method":"GET","relativePath":"/v1/catalog/nodes/migration%3Avercel-app","origin":"api","parameters":{"nodeId":"migration:vercel-app"},"requiresAuthentication":false,"requiresApproval":false},{"actionId":"browse:stack:framework-next-js","label":"Browse Next.js","operationId":"browse_node","method":"GET","relativePath":"/v1/catalog/nodes/stack%3Aframework-next-js","origin":"api","parameters":{"nodeId":"stack:framework-next-js"},"requiresAuthentication":false,"requiresApproval":false},{"actionId":"browse:intent:migrate-compute","label":"Browse Migrate compute","operationId":"browse_node","method":"GET","relativePath":"/v1/catalog/nodes/intent%3Amigrate-compute","origin":"api","parameters":{"nodeId":"intent:migrate-compute"},"requiresAuthentication":false,"requiresApproval":false}]}