RFC: Deployment Adapters API
On the 2nd of April 2025 Lee Robinson (Vercel) did post a RFC in the discussions section of the Next.js project on GitHub.
Since 2016, Next.js has offered self-hosting via a custom Express server, Node.js server (next start), standalone builds, and static exports.
However, serverless platforms like Netlify struggle with bespoke deployment requirements — forcing them to reverse-engineer undocumented manifests, patch next.config, and shim the full Next.js server.
Main Goals
- Serverless compatibility: Provide a clear adapter API so platforms like Netlify, Cloudflare, and AWS Lambda can deploy Next.js without custom hacks.
- Uniform deployment experience: Guarantee that Vercel and all other hosts use the exact same adapter hooks, ensuring identical behavior across environments.
- Address provider pain points:
- Lack of background-work signals: Avoid reverse-engineering internals to detect when tasks (e.g., cache revalidation) finish.
- No official config overrides: Eliminate the need to patch or wrap
next.config
or rely on undocumented environment variables. - Undocumented build manifests: Replace brittle, out-of-band JSON files with a structured, versioned API.
- Heavy next-server dependency: Remove the requirement to load the full Next.js server for each entrypoint, improving cold-start times and control.
- Better build-time hooks: Introduce
modifyConfig
(pre-build) andonBuildComplete
(post-build) so adapters can tweak settings and receive a structured manifest of routes, functions, and assets.
Adapter API
This is how the interface of a Next.js adapter could look like:
interface NextAdapter {
// "vercel", "netlify", "cloudflare" ...etc
name: string,
// "modifyConfig" is called before build and is an opportunity
// to modify the loaded Next config
modifyConfig(config: NextConfig)?: Promise | NextConfig,
// "built" is called after compilation and pre-rendering is finished
// outputs will include all assets/functions we've created
// it also includes public folder assets. Each pre-render path is
// it's own function output with it's own config
onBuildComplete({
routes: {
headers: Array }>
rewrites: Array
redirects: Array
},
outputs: Array<{
id: string,
fallbackID?: string, // a fallbackID points to another output ID
runtime?: 'nodejs' | 'edge',
pathname: string,
allowQuery?: string[]
config: {
// Any user provided function / pre-render config is provided here
maxDuration?: number
expiration?: number
revalidate?: number
},
// These are the traced dependencies needed for the entry
// to run in an isolated environment (standalone)
// Record of file name (relative from project root) to absolute path
assets?: Record
filePath: string,
type: RouteType
}>
})?: Promise | void
}
Iteration with partners
Netlify, Cloudflare, AWS Amplify and the OpenNext community are collaborating with Vercel to refine and shape of the deployment adapters API.
Using a deployment adapter could be as easy as importing them on your next.config.ts
// next.config.ts
module.exports = {
adpaterPath: require.resolve('@next/adapter-vercel')
}