---
title: Next.js
description: Run an eve agent and a Next.js app as one project with withEve.
---

# Next.js



`eve/next` ships a Next.js frontend and an eve agent as a single project. Wrap your config with `withEve()` to run both from one dev server and one Vercel deploy. [`useEveAgent`](./overview) finds the mounted routes on its own, so there's no CORS to configure and no URL env vars to keep in sync.

## Prerequisites

* The `eve` package installed in your project (`npm install eve@latest`).
* An existing eve agent directory. If you don't have one, start from [Getting started](../../getting-started).
* A Next.js app to mount the agent in.

## Wrap the Next.js config

```ts title="next.config.ts"
import type { NextConfig } from "next";
import { withEve } from "eve/next";

const nextConfig: NextConfig = {};

export default withEve(nextConfig);
```

By default `withEve()` looks for an `agent/` folder inside your Next.js project root. If the agent lives somewhere else, point at it with `eveRoot`:

```ts
export default withEve(nextConfig, {
  eveRoot: "../my-agent",
});
```

For multiple agents, use `agents`. String values are agent roots; object values can override the build command or private production service prefix for that agent:

```ts
export default withEve(nextConfig, {
  agents: {
    support: "./agents/support",
    billing: {
      root: "./agents/billing",
      buildCommand: "pnpm build:billing-agent",
      servicePrefix: "/_eve_internal/billing",
    },
  },
});
```

Named agents mount under `/eve/agents/<name>/eve/v1/*`. Call the matching agent from React with `agent`:

```tsx
const support = useEveAgent({ agent: "support" });
const billing = useEveAgent({ agent: "billing" });
```

Use either `eveRoot` or `agents`, not both. `eveRoot` remains the shorthand for a single unnamed agent mounted at `/eve/v1/*`.

Generated agent services build with `EVE_PUBLIC_ROUTE_PREFIX` set to the agent's public mount (for example `/eve/agents/support`) so framework-minted callback URLs — OAuth connection callbacks and remote-subagent session callbacks — resolve to the public per-agent path. If you configure eve services manually in `vercel.json` instead, export that variable in each named agent's build command.

### `withEve` options

All fields are optional.

| Option               | Type                  | Default                | Purpose                                                                                                                                                    |
| -------------------- | --------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `eveRoot`            | `string`              | Next.js app root       | Path to one unnamed eve app root, relative to `process.cwd()` unless absolute. Do not combine with `agents`.                                               |
| `agents`             | `Record<string, ...>` | unset                  | Named eve agents to mount under `/eve/agents/<name>/eve/v1/*`. Each value is a root string or `{ root, buildCommand?, servicePrefix? }`.                   |
| `eveBuildCommand`    | `string`              | generated              | Build command for generated eve Vercel services. In multi-agent mode this is the default for agents without their own `buildCommand`.                      |
| `servicePrefix`      | `string`              | `"/_eve_internal/eve"` | Private route namespace for legacy manual Vercel service configs and non-Vercel production proxying. Named agents derive unique defaults from this prefix. |
| `devServerTimeoutMs` | `number`              | `180000`               | Maximum time to wait for each eve development server to become available.                                                                                  |

For slow cold starts, increase the development timeout:

```ts
export default withEve(nextConfig, {
  devServerTimeoutMs: 300_000,
});
```

## Call the hook

With `withEve()` in `next.config.ts`, the eve routes are same-origin, so client code can call [`useEveAgent`](./overview) without naming a host. Cookie-based auth (Auth.js or any session cookie) needs no extra wiring, since the browser already sends those cookies on every eve request. For non-cookie schemes, attach the credentials yourself:

```tsx
const agent = useEveAgent({
  headers: async () => ({
    authorization: `Bearer ${await getAccessToken()}`,
  }),
});
```

The default eve channel is fail-closed. With no `agent/channels/eve.ts` authored, eve registers `eveChannel({ auth: [vercelOidc(), localDev()] })`: `vercelOidc()` gets the first chance to resolve a Vercel caller, `localDev()` opens the remaining localhost requests, and everything else gets a `401`. To run your app's own auth policy, add `agent/channels/eve.ts`:

```ts title="agent/channels/eve.ts"
import { eveChannel } from "eve/channels/eve";
import { localDev, vercelOidc } from "eve/channels/auth";

export default eveChannel({ auth: [vercelOidc(), localDev()] });
```

For a public demo, use `none()` (also from `eve/channels/auth`) to skip authentication. See [Channels](../../channels/overview) and [Auth & route protection](../auth-and-route-protection).

## Dev vs deploy topology

* **Local dev.** `npm run dev` boots the eve dev server next to `next dev` and rewrites the eve routes over to it. The browser only ever talks to the Next.js origin.

* **Vercel.** The web app and the eve runtime deploy as a single project. `withEve()` writes Build Output `services` for eve and `routes` that send `/eve/v1/**` to that service before filesystem routing; the Next.js app itself remains the default app. Vercel assembles authored [schedules](../../schedules) into the project config as Vercel Cron Jobs, including correctly prefixed jobs for named agents, while cron entries owned by the Next.js app are preserved. By default, generated services run the installed eve binary from the agent root, so the agent directory does not need its own `package.json`. When the agent needs its own build step, set `eveBuildCommand`:

  ```ts
  export default withEve(nextConfig, {
    eveBuildCommand: "npm run build:eve",
  });
  ```

* **Local production build.** `next build && next start` serves the eve runtime from its built `.output/server/index.mjs` on a stable local port (`4274`) and proxies the eve routes to it. Run `eve build` first so that output exists. Change the port with `EVE_NEXT_PRODUCTION_PORT`:

  ```bash
  EVE_NEXT_PRODUCTION_PORT=5000 npm run build && npm start
  ```

* **Non-Vercel hosts.** When the eve service lives on a separate origin, tell Next.js where to find it with `EVE_NEXT_PRODUCTION_ORIGIN`:

  ```bash
  EVE_NEXT_PRODUCTION_ORIGIN=https://agent.example.com npm run build
  ```

## What to read next

* [Frontend overview](./overview): the `useEveAgent` API
* [Auth & route protection](../auth-and-route-protection)
* [Deployment](../deployment/overview)


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)