Skip to content

Commit 07a0700

Browse files
authored
docs: clarify runtime (#64593)
1 parent f93ae7c commit 07a0700

File tree

9 files changed

+29
-184
lines changed

9 files changed

+29
-184
lines changed

docs/02-app/01-building-your-application/01-routing/12-route-handlers.mdx

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,6 @@ const openai = new OpenAI({
406406
apiKey: process.env.OPENAI_API_KEY,
407407
})
408408

409-
export const runtime = 'edge'
410-
411409
export async function POST(req: Request) {
412410
const { messages } = await req.json()
413411
const response = await openai.chat.completions.create({
@@ -430,8 +428,6 @@ const openai = new OpenAI({
430428
apiKey: process.env.OPENAI_API_KEY,
431429
})
432430

433-
export const runtime = 'edge'
434-
435431
export async function POST(req) {
436432
const { messages } = await req.json()
437433
const response = await openai.chat.completions.create({
@@ -649,16 +645,6 @@ export async function POST(request) {
649645

650646
Notably, unlike API Routes with the Pages Router, you do not need to use `bodyParser` to use any additional configuration.
651647

652-
### Edge and Node.js Runtimes
653-
654-
Route Handlers have an isomorphic Web API to support both Edge and Node.js runtimes seamlessly, including support for streaming. Since Route Handlers use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) as Pages and Layouts, they support long-awaited features like general-purpose [statically regenerated](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) Route Handlers.
655-
656-
You can use the `runtime` segment config option to specify the runtime:
657-
658-
```ts
659-
export const runtime = 'edge' // 'nodejs' is the default
660-
```
661-
662648
### Non-UI Responses
663649

664650
You can use Route Handlers to return non-UI content. Note that [`sitemap.xml`](/docs/app/api-reference/file-conventions/metadata/sitemap#generating-a-sitemap-using-code-js-ts), [`robots.txt`](/docs/app/api-reference/file-conventions/metadata/robots#generate-a-robots-file), [`app icons`](/docs/app/api-reference/file-conventions/metadata/app-icons#generate-icons-using-code-js-ts-tsx), and [open graph images](/docs/app/api-reference/file-conventions/metadata/opengraph-image) all have built-in support.
Lines changed: 15 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,26 @@
11
---
2-
title: Edge and Node.js Runtimes
2+
title: Runtimes
33
description: Learn about the switchable runtimes (Edge and Node.js) in Next.js.
4+
related:
5+
description: View the Edge Runtime API reference.
6+
links:
7+
- app/api-reference/edge
48
---
59

610
{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
711

8-
In the context of Next.js, runtime refers to the set of libraries, APIs, and general functionality available to your code during execution.
12+
Next.js has two server runtimes you can use in your application:
913

10-
On the server, there are two runtimes where parts of your application code can be rendered:
14+
- The **Node.js Runtime** (default) which has access to all Node.js APIs and compatible packages from the ecosystem.
15+
- The **Edge Runtime** which contains a more limited [set of APIs](/docs/app/api-reference/edge).
1116

12-
- The **Node.js Runtime** (default) has access to all Node.js APIs and compatible packages from the ecosystem.
13-
- The **Edge Runtime** is based on [Web APIs](/docs/app/api-reference/edge).
17+
## Use Cases
1418

15-
## Runtime Differences
19+
- The Node.js runtime is used for rendering your application.
20+
- The Edge runtime is used for Middleware (routing rules like redirects, rewrites, and setting headers).
1621

17-
There are many considerations to make when choosing a runtime. This table shows the major differences at a glance. If you want a more in-depth analysis of the differences, check out the sections below.
22+
## Caveats
1823

19-
| | Node | Serverless | Edge |
20-
| ------------------------------------------------------------------------------------------------------------------------------------- | ------ | ---------- | ---------------- |
21-
| Cold Boot | / | Normal | Low |
22-
| [HTTP Streaming](/docs/app/building-your-application/routing/loading-ui-and-streaming) | Yes | Yes | Yes |
23-
| IO | All | All | `fetch` |
24-
| Scalability | / | High | Highest |
25-
| Security | Normal | High | High |
26-
| Latency | Normal | Low | Lowest |
27-
| npm Packages | All | All | A smaller subset |
28-
| [Static Rendering](/docs/app/building-your-application/rendering/server-components#static-rendering-default) | Yes | Yes | No |
29-
| [Dynamic Rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering) | Yes | Yes | Yes |
30-
| [Data Revalidation w/ `fetch`](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) | Yes | Yes | Yes |
31-
32-
### Edge Runtime
33-
34-
In Next.js, the lightweight Edge Runtime is a subset of available Node.js APIs.
35-
36-
The Edge Runtime is ideal if you need to deliver dynamic, personalized content at low latency with small, simple functions. The Edge Runtime's speed comes from its minimal use of resources, but that can be limiting in many scenarios.
37-
38-
For example, code executed in the Edge Runtime [on Vercel cannot exceed between 1 MB and 4 MB](https://vercel.com/docs/concepts/limits/overview#edge-middleware-and-edge-functions-size), this limit includes imported packages, fonts and files, and will vary depending on your deployment infrastructure. In addition, the Edge Runtime does not support all Node.js APIs meaning some `npm` packages may not work. For example, "Module not found: Can't resolve 'fs'" or similar errors. We recommend using the Node.js runtime if you need to use these APIs or packages.
39-
40-
### Node.js Runtime
41-
42-
Using the Node.js runtime gives you access to all Node.js APIs, and all npm packages that rely on them. However, it's not as fast to start up as routes using the Edge runtime.
43-
44-
Deploying your Next.js application to a Node.js server will require managing, scaling, and configuring your infrastructure. Alternatively, you can consider deploying your Next.js application to a serverless platform like Vercel, which will handle this for you.
45-
46-
### Serverless Node.js
47-
48-
Serverless is ideal if you need a scalable solution that can handle more complex computational loads than the Edge Runtime. With Serverless Functions on Vercel, for example, your overall code size is [50MB](https://vercel.com/docs/concepts/limits/overview#serverless-function-size) including imported packages, fonts, and files.
49-
50-
The downside compared to routes using the [Edge](https://vercel.com/docs/concepts/functions/edge-functions) is that it can take hundreds of milliseconds for Serverless Functions to boot up before they begin processing requests. Depending on the amount of traffic your site receives, this could be a frequent occurrence as the functions are not frequently "warm".
51-
52-
<AppOnly>
53-
54-
## Examples
55-
56-
### Segment Runtime Option
57-
58-
You can specify a runtime for individual route segments in your Next.js application. To do so, [declare a variable called `runtime` and export it](/docs/app/api-reference/file-conventions/route-segment-config). The variable must be a string, and must have a value of either `'nodejs'` or `'edge'` runtime.
59-
60-
The following example demonstrates a page route segment that exports a `runtime` with a value of `'edge'`:
61-
62-
```tsx filename="app/page.tsx" switcher
63-
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
64-
```
65-
66-
```jsx filename="app/page.js" switcher
67-
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
68-
```
69-
70-
You can also define `runtime` on a layout level, which will make all routes under the layout run on the edge runtime:
71-
72-
```tsx filename="app/layout.tsx" switcher
73-
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
74-
```
75-
76-
```jsx filename="app/layout.js" switcher
77-
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
78-
```
79-
80-
If the segment runtime is _not_ set, the default `nodejs` runtime will be used. You do not need to use the `runtime` option if you do not plan to change from the Node.js runtime.
81-
82-
</AppOnly>
83-
84-
> Please refer to the [Node.js Docs](https://nodejs.org/docs/latest/api/) and [Edge Docs](/docs/app/api-reference/edge) for the full list of available APIs. Both runtimes can also support [streaming](/docs/app/building-your-application/routing/loading-ui-and-streaming) depending on your deployment infrastructure.
24+
- The Edge runtime does not support all Node.js APIs. Some packages will not work. Learn more about the unsupported APIs in the [Edge Runtime](/docs/app/api-reference/edge#unsupported-apis).
25+
- The Edge runtime does not support Incremental Static Regeneration (ISR).
26+
- Both runtimes can support [streaming](/docs/app/building-your-application/routing/loading-ui-and-streaming) depending on your deployment infrastructure.

docs/02-app/01-building-your-application/06-optimizing/04-metadata.mdx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,11 @@ export const metadata = {
247247
248248
The `ImageResponse` constructor allows you to generate dynamic images using JSX and CSS. This is useful for creating social media images such as Open Graph images, Twitter cards, and more.
249249
250-
`ImageResponse` uses the [Edge Runtime](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#edge-runtime), and Next.js automatically adds the correct headers to cached images at the edge, helping improve performance and reducing recomputation.
251-
252250
To use it, you can import `ImageResponse` from `next/og`:
253251
254252
```jsx filename="app/about/route.js"
255253
import { ImageResponse } from 'next/og'
256254

257-
export const runtime = 'edge'
258-
259255
export async function GET() {
260256
return new ImageResponse(
261257
(

docs/02-app/01-building-your-application/06-optimizing/09-instrumentation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export async function register() {
7070
7171
### Importing runtime-specific code
7272

73-
Next.js calls `register` in all environments, so it's important to conditionally import any code that doesn't support specific runtimes (e.g. [Edge](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#edge-runtime) or [Node.js](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#nodejs-runtime)). You can use the `NEXT_RUNTIME` environment variable to get the current environment:
73+
Next.js calls `register` in all environments, so it's important to conditionally import any code that doesn't support specific runtimes (e.g. [Edge or Node.js](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes)). You can use the `NEXT_RUNTIME` environment variable to get the current environment:
7474

7575
```ts filename="instrumentation.ts" switcher
7676
export async function register() {

docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ The easiest way to generate an icon is to use the [`ImageResponse`](/docs/app/ap
8383
```tsx filename="app/icon.tsx" switcher
8484
import { ImageResponse } from 'next/og'
8585

86-
// Route segment config
87-
export const runtime = 'edge'
88-
8986
// Image metadata
9087
export const size = {
9188
width: 32,
@@ -126,9 +123,6 @@ export default function Icon() {
126123
```jsx filename="app/icon.js" switcher
127124
import { ImageResponse } from 'next/og'
128125

129-
// Route segment config
130-
export const runtime = 'edge'
131-
132126
// Image metadata
133127
export const size = {
134128
width: 32,
@@ -258,25 +252,6 @@ export default function Icon() {}
258252

259253
`icon` and `apple-icon` are specialized [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts.
260254

261-
| Option | Type | Default |
262-
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------- |
263-
| [`dynamic`](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) | `'auto' \| 'force-dynamic' \| 'error' \| 'force-static'` | `'auto'` |
264-
| [`revalidate`](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) | `false \| 'force-cache' \| 0 \| number` | `false` |
265-
| [`runtime`](/docs/app/api-reference/file-conventions/route-segment-config#runtime) | `'nodejs' \| 'edge'` | `'nodejs'` |
266-
| [`preferredRegion`](/docs/app/api-reference/file-conventions/route-segment-config#preferredregion) | `'auto' \| 'global' \| 'home' \| string \| string[]` | `'auto'` |
267-
268-
```tsx filename="app/icon.tsx" switcher
269-
export const runtime = 'edge'
270-
271-
export default function Icon() {}
272-
```
273-
274-
```jsx filename="app/icon.js" switcher
275-
export const runtime = 'edge'
276-
277-
export default function Icon() {}
278-
```
279-
280255
## Version History
281256

282257
| Version | Changes |

docs/02-app/02-api-reference/02-file-conventions/01-metadata/opengraph-image.mdx

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,6 @@ The easiest way to generate an image is to use the [ImageResponse](/docs/app/api
9292
```tsx filename="app/about/opengraph-image.tsx" switcher
9393
import { ImageResponse } from 'next/og'
9494

95-
// Route segment config
96-
export const runtime = 'edge'
97-
9895
// Image metadata
9996
export const alt = 'About Acme'
10097
export const size = {
@@ -149,9 +146,6 @@ export default async function Image() {
149146
```jsx filename="app/about/opengraph-image.js" switcher
150147
import { ImageResponse } from 'next/og'
151148

152-
// Route segment config
153-
export const runtime = 'edge'
154-
155149
// Image metadata
156150
export const alt = 'About Acme'
157151
export const size = {
@@ -313,25 +307,6 @@ export default function Image() {}
313307
314308
`opengraph-image` and `twitter-image` are specialized [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts.
315309
316-
| Option | Type | Default |
317-
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------- |
318-
| [`dynamic`](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) | `'auto' \| 'force-dynamic' \| 'error' \| 'force-static'` | `'auto'` |
319-
| [`revalidate`](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) | `false \| 'force-cache' \| 0 \| number` | `false` |
320-
| [`runtime`](/docs/app/api-reference/file-conventions/route-segment-config#runtime) | `'nodejs' \| 'edge'` | `'nodejs'` |
321-
| [`preferredRegion`](/docs/app/api-reference/file-conventions/route-segment-config#preferredregion) | `'auto' \| 'global' \| 'home' \| string \| string[]` | `'auto'` |
322-
323-
```tsx filename="app/opengraph-image.tsx" switcher
324-
export const runtime = 'edge'
325-
326-
export default function Image() {}
327-
```
328-
329-
```jsx filename="app/opengraph-image.js" switcher
330-
export const runtime = 'edge'
331-
332-
export default function Image() {}
333-
```
334-
335310
### Examples
336311
337312
#### Using external data
@@ -344,8 +319,6 @@ This example uses the `params` object and external data to generate the image.
344319
```tsx filename="app/posts/[slug]/opengraph-image.tsx" switcher
345320
import { ImageResponse } from 'next/og'
346321

347-
export const runtime = 'edge'
348-
349322
export const alt = 'About Acme'
350323
export const size = {
351324
width: 1200,
@@ -384,8 +357,6 @@ export default async function Image({ params }: { params: { slug: string } }) {
384357
```jsx filename="app/posts/[slug]/opengraph-image.js" switcher
385358
import { ImageResponse } from 'next/og'
386359

387-
export const runtime = 'edge'
388-
389360
export const alt = 'About Acme'
390361
export const size = {
391362
width: 1200,

docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,6 @@ The Route Segment options allows you to configure the behavior of a [Page](/docs
1515
| [`preferredRegion`](#preferredregion) | `'auto' \| 'global' \| 'home' \| string \| string[]` | `'auto'` |
1616
| [`maxDuration`](#maxduration) | `number` | Set by deployment platform |
1717

18-
```tsx filename="layout.tsx | page.tsx | route.ts" switcher
19-
export const dynamic = 'auto'
20-
export const dynamicParams = true
21-
export const revalidate = false
22-
export const fetchCache = 'auto'
23-
export const runtime = 'nodejs'
24-
export const preferredRegion = 'auto'
25-
export const maxDuration = 5
26-
27-
export default function MyComponent() {}
28-
```
29-
30-
```jsx filename="layout.js | page.js | route.js" switcher
31-
export const dynamic = 'auto'
32-
export const dynamicParams = true
33-
export const revalidate = false
34-
export const fetchCache = 'auto'
35-
export const runtime = 'nodejs'
36-
export const preferredRegion = 'auto'
37-
export const maxDuration = 5
38-
39-
export default function MyComponent() {}
40-
```
41-
42-
> **Good to know**:
43-
>
44-
> - The values of the config options currently need be statically analyzable. For example `revalidate = 600` is valid, but `revalidate = 60 * 10` is not.
45-
4618
## Options
4719

4820
### `dynamic`
@@ -118,7 +90,10 @@ export const revalidate = false
11890
- **`0`**: Ensure a layout or page is always [dynamically rendered](/docs/app/building-your-application/rendering/server-components#dynamic-rendering) even if no dynamic functions or uncached data fetches are discovered. This option changes the default of `fetch` requests that do not set a `cache` option to `'no-store'` but leaves `fetch` requests that opt into `'force-cache'` or use a positive `revalidate` as is.
11991
- **`number`**: (in seconds) Set the default revalidation frequency of a layout or page to `n` seconds.
12092

121-
> **Good to know**: The `revalidate` option is only available when using the [Node.js Runtime](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#nodejs-runtime). This means using the `revalidate` option with `runtime = 'edge'` will not work.
93+
> **Good to know**:
94+
>
95+
> - The revalidate value needs to be statically analyzable. For example `revalidate = 600` is valid, but `revalidate = 60 * 10` is not.
96+
> - The revalidate value is not available when using `runtime = 'edge'`.
12297
12398
#### Revalidation Frequency
12499

@@ -168,6 +143,8 @@ export const fetchCache = 'auto'
168143

169144
### `runtime`
170145

146+
We recommend using the Node.js runtime for rendering your application, and the Edge runtime for Middleware (only supported option).
147+
171148
```tsx filename="layout.tsx | page.tsx | route.ts" switcher
172149
export const runtime = 'nodejs'
173150
// 'nodejs' | 'edge'
@@ -181,7 +158,7 @@ export const runtime = 'nodejs'
181158
- **`'nodejs'`** (default)
182159
- **`'edge'`**
183160

184-
Learn more about the [Edge and Node.js runtimes](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes).
161+
Learn more about the [different runtimes](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes).
185162

186163
### `preferredRegion`
187164

0 commit comments

Comments
 (0)