---
title: "Server Imports"
description: "`nuxt/server` is the import surface for server code that isn't tied to a particular server runtime."
canonical_url: "https://nuxt.com/docs/4.x/guide/going-further/server-imports"
---
# Server Imports

> `nuxt/server` is the import surface for server code that isn't tied to a particular server runtime.

It's possible to use different [server builders](https://nuxt.com/docs/4.x/guide/going-further/builders) with Nuxt: Nitro 2 (`nitropack`, the default in Nuxt 3 and 4), Nitro 3 (`nitro`, from Nuxt 5), or Vite directly.

`nuxt/server` exists to provide agnostic utilities for server code that aren't tied to a particular server runtime. It is the second runtime surface of Nuxt, alongside `nuxt/app` (also reachable as `#app`), which is for the part of your application that also runs in the browser.

```ts [server/api/hello.ts]
import { defineEventHandler, getQuery } from 'nuxt/server'

export default defineEventHandler((event) => {
  const { name } = getQuery<{ name?: string }>(event)
  return { message: `Hello, ${name ?? 'world'}!` }
})
```

This code can run under `@nuxt/nitro-server` and under `@nuxt/vite-server`, and will also keep running across an h3 or Nitro major, because Nuxt absorbs those changes centrally.

`nuxt/server` ships from Nuxt 4.6, so one file can serve Nuxt 4.6 running `nitropack` v2, Nuxt 5 running Nitro v3, and anything a future builder brings.

<tip>

`nuxt` is installed in every Nuxt application, so `nuxt/server` resolves with no alias and no added dependency. A module importing from it needs no peer dependency on h3 or Nitro.

</tip>

## Types and Utilities

<table>
<thead>
  <tr>
    <th>
      Import
    </th>
    
    <th>
      Purpose
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        defineEventHandler
      </code>
    </td>
    
    <td>
      Define a request handler.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        createError
      </code>
      
      , <code>
        isNuxtError
      </code>
    </td>
    
    <td>
      Construct and recognise an HTTP error.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getRequestURL
      </code>
    </td>
    
    <td>
      The URL of the request.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getRequestHeader
      </code>
      
      , <code>
        getRequestHeaders
      </code>
    </td>
    
    <td>
      Read request headers.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getQuery
      </code>
    </td>
    
    <td>
      Read the query string.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        readBody
      </code>
    </td>
    
    <td>
      Read and parse the request body.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getCookie
      </code>
      
      , <code>
        setCookie
      </code>
      
      , <code>
        deleteCookie
      </code>
    </td>
    
    <td>
      Read and write cookies.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        setResponseStatus
      </code>
    </td>
    
    <td>
      Set the response status and reason phrase.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        setResponseHeader
      </code>
      
      , <code>
        setResponseHeaders
      </code>
    </td>
    
    <td>
      Set response headers.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sendRedirect
      </code>
    </td>
    
    <td>
      Redirect the request.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        getRouteRules
      </code>
    </td>
    
    <td>
      The <a href="https://nuxt.com/docs/4.x/guide/concepts/rendering#route-rules">
        route rules
      </a>
      
       matched for the request.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        useRuntimeConfig
      </code>
    </td>
    
    <td>
      The server's <a href="https://nuxt.com/docs/4.x/guide/going-further/runtime-config">
        runtime configuration
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        toNuxtRequestEvent
      </code>
    </td>
    
    <td>
      The event in the shape the server runtime provides.
    </td>
  </tr>
</tbody>
</table>

Types are exported alongside the utilities: `RequestEvent`, `RequestEventContext`, `NuxtRequestEvent`, `EventHandler`, `AppRouteRules`, `ServerRoutes`, `NuxtError`, `NuxtErrorDetails`, `NuxtErrorJSON` and `NuxtErrorLike`.

These names are [auto-imported](https://nuxt.com/docs/4.x/directory-structure/server) in server code, so the import statement above is optional. Writing it keeps the file working in a project with server auto-imports off, and is what a module should do.

<tip>

`defineEventHandler` preserves your handler's return type, which is what types [`$fetch` and `useFetch`](https://nuxt.com/docs/4.x/getting-started/data-fetching) calls to the route. Annotate the value you return rather than the handler.

</tip>

## The Event

`RequestEvent` is the event that `nuxt/server` utilities operate from, including the request, its URL, the response to be sent, and the request context.

```ts
interface RequestEvent {
  readonly req: Request
  url: URL
  readonly res: { status?: number, statusText?: string, readonly headers: Headers }
  readonly context: RequestEventContext
}
```

Nitro adds more on top, such as `event.node` and `event.waitUntil()`, but these four core properties work in all runtimes, and need no helpers:

```ts [server/api/echo.post.ts]
export default defineEventHandler(async (event) => {
  const { id } = await event.req.json()
  return { id, page: event.url.searchParams.get('page') }
})
```

`NuxtRequestEvent` is the same request in the shape the configured builder provides, which is h3 v1's `H3Event` under `@nuxt/nitro-server`. You can get a type-safe version of the event for the server builder you're using by calling `toNuxtRequestEvent(event)`.

## Reaching Past the Surface

`nuxt/server` isn't a re-export of h3, so if you need something else that h3 and Nitro offer, such as the server lifecycle (`defineNitroPlugin`, `defineNitroErrorHandler` and the Nitro app hooks), you would import it directly.

Most of those helpers take the event as it is:

```ts [server/api/upload.post.ts]
import { defineEventHandler, toNuxtRequestEvent } from 'nuxt/server'
import { readValidatedBody } from 'h3'

export default defineEventHandler(async (event) => {
  const body = await readValidatedBody(toNuxtRequestEvent(event), schema)
  return { received: body }
})
```

Under `@nuxt/nitro-server` the event a handler receives is a view of the h3 v1 event, so `toNuxtRequestEvent(event)` is what h3's own helpers take: `readValidatedBody`, `getValidatedQuery`, `getRouterParam`, `getRouterParams`, `getRequestIP`, `assertMethod`, the session helpers, the CORS helpers (such as `handleCors`), `proxy`, `proxyRequest`, `fetchWithEvent` and `writeEarlyHints`, as well as reading `event.node` or `event.waitUntil()`.

Nitro's own APIs mostly take no event at all: `defineCachedEventHandler()`, `useStorage()`, `useDatabase()` and tasks.

<tip>

If you find you are writing Nitro-specific code, you may simply prefer to import `defineEventHandler` from `h3` instead:

```ts [server/api/cors.ts]
import { defineEventHandler, handleCors } from 'h3'

export default defineEventHandler((event) => {
  handleCors(event, { origin: '*' })
  return { ok: true }
})
```

</tip>

## What Isn't Portable

Three key areas you may need will mean you need to reach outside `nuxt/server`, because Nuxt can't provide them for every builder:

- **Storage.** `useStorage()` comes from `nitropack/runtime`, and so does the driver configuration behind it.
- **Sessions.** The sealed-session helpers come from `h3`. They accept the runtime's event, but importing them pins the file to Nitro.
- **Caching.** `defineCachedEventHandler()` and `defineCachedFunction()` come from `nitropack/runtime`.

## Server Code Only

Importing `nuxt/server` from a Vue component, a plugin or the `shared/` directory fails the build, and the error points you at `#app`, `#imports`, `$fetch` and `useFetch` instead. Its types still resolve in those contexts, which is what lets `$fetch` know what your server routes return.

## Modules

A module whose runtime code imports only from `nuxt/server` runs under any server builder from v4.6 onwards, with no version check and no dependency on h3 or Nitro:

```ts [runtime/server/api/status.ts]
import { defineEventHandler, useRuntimeConfig } from 'nuxt/server'

export default defineEventHandler(() => ({
  version: useRuntimeConfig().myModule.version,
}))
```

<tip>

Leave `nuxt/server` external when you bundle; it will be resolved in the Nuxt build to the right server builder utilities.

</tip>

Supporting Nuxt versions <4.6 takes one more step, because those projects have no `nuxt/server` to resolve. You can instead register the portable file and the one you ship today side by side, and Nuxt will pick whichever the application can run.

<read-more to="https://nuxt.com/docs/4.x/guide/modules/server-compatibility">

See how to register one handler per server API.

</read-more>

<read-more to="https://nuxt.com/docs/4.x/guide/going-further/builders">

Learn how a server builder supplies the implementations behind `nuxt/server`.

</read-more>

---

- [Source](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/server/index.ts)


## Sitemap

See the full [sitemap](https://nuxt.com/sitemap.md) for all pages.
