# Integrate Mastra in your Next.js project
[EN] Source: https://mastra.ai/docs/frameworks/web-frameworks/next-js

Mastra integrates with Next.js, making it easy to:

- Build flexible APIs to serve AI-powered features
- Simplify deployment with a unified codebase for frontend and backend
- Take advantage of Next.js's built-in server actions (App Router) or API Routes (Pages Router) for efficient server-client workflows

Use this guide to scaffold and integrate Mastra with your Next.js project.

<Tabs>
  <TabItem value="app-router" label="App Router">

:::warning

This guide assumes you're using the Next.js App Router at the root of your project, e.g., `app` rather than `src/app`.

:::

<Steps>

<StepItem>

To integrate Mastra into your project, you have two options:

- Use the One-Liner

  Run the following command to quickly scaffold the default Weather agent with sensible defaults:

  ```bash copy
  npx mastra@latest init --dir . --components agents,tools --example --llm openai
  ```

  > See [mastra init](/reference/cli/create-mastra) for more information.

- Use the Interactive CLI

  If you prefer to customize the setup, run the `init` command and choose from the options when prompted:

  ```bash copy
  npx mastra@latest init
  ```

  :::warning

  By default, `mastra init` suggests `src` as the install location. If you're using the App Router at the root of your project (e.g., `app`, not `src/app`), enter `.` when prompted:

  :::

</StepItem>

<StepItem>

Set Up API Key

```bash title=".env" copy
OPENAI_API_KEY=<your-api-key>
```

> Each LLM provider uses a different env var. See [Model Capabilities](https://sdk.vercel.ai/providers) for more information.

</StepItem>

<StepItem>

Add to your `next.config.ts`:

```typescript title="next.config.ts" showLineNumbers copy
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  serverExternalPackages: ["@mastra/*"],
};

export default nextConfig;
```

</StepItem>

<StepItem>

You can start your Next.js app in the usual way.

</StepItem>

<StepItem>

Create a new directory that will contain a Page, Action, and Form for testing purposes.

```bash copy
mkdir app/test
```

</StepItem>

<StepItem>

Create a new Action, and add the example code:

```bash copy
touch app/test/action.ts
```

```typescript title="app/test/action.ts" showLineNumbers copy
"use server";

import { mastra } from "../../mastra";

export async function getWeatherInfo(formData: FormData) {
  const city = formData.get("city")?.toString();
  const agent = mastra.getAgent("weatherAgent");

  const result = await agent.generate(`What's the weather like in ${city}?`);

  return result.text;
}
```

</StepItem>

<StepItem>

Create a new Form component, and add the example code:

```bash copy
touch app/test/form.tsx
```

```typescript title="app/test/form.tsx" showLineNumbers copy
"use client";

import { useState } from "react";
import { getWeatherInfo } from "./action";

export function Form() {
  const [result, setResult] = useState<string | null>(null);

  async function handleSubmit(formData: FormData) {
    const res = await getWeatherInfo(formData);
    setResult(res);
  }

  return (
    <>
      <form action={handleSubmit}>
        <input name="city" placeholder="Enter city" required />
        <button type="submit">Get Weather</button>
      </form>
      {result && <pre>{result}</pre>}
    </>
  );
}
```

</StepItem>

<StepItem>

Create a new Page, and add the example code:

```bash copy
touch app/test/page.tsx
```

```typescript title="app/test/page.tsx" showLineNumbers copy
import { Form } from "./form";

export default async function Page() {
  return (
    <>
      <h1>Test</h1>
      <Form />
    </>
  );
}
```

> You can now navigate to `/test` in your browser to try it out.

Submitting **London** as the city would return a result similar to:

```plaintext
Agent response: The current weather in London is as follows:

- **Temperature:** 12.9°C (Feels like 9.7°C)
- **Humidity:** 63%
- **Wind Speed:** 14.7 km/h
- **Wind Gusts:** 32.4 km/h
- **Conditions:** Overcast

Let me know if you need more information!
```

</StepItem>

  </Steps>
  </TabItem>

  <TabItem value="pages-router" label="Pages Router">

:::warning

This guide assumes you're using the Next.js Pages Router at the root of your project, e.g., `pages` rather than `src/pages`.

:::

<Steps>

<StepItem>

To integrate Mastra into your project, you have two options:

- Use the One-Liner

  Run the following command to quickly scaffold the default Weather agent with sensible defaults:

  ```bash copy
  npx mastra@latest init --dir . --components agents,tools --example --llm openai
  ```

  > See [mastra init](/reference/cli/create-mastra) for more information.

- Use the Interactive CLI

  If you prefer to customize the setup, run the `init` command and choose from the options when prompted:

  ```bash copy
  npx mastra@latest init
  ```

  :::warning

  By default, `mastra init` suggests `src` as the install location. If you're using the Pages Router at the root of your project (e.g., `pages`, not `src/pages`), enter `.` when prompted:

  :::

</StepItem>

<StepItem>

Set Up API Key

```bash title=".env" copy
OPENAI_API_KEY=<your-api-key>
```

> Each LLM provider uses a different env var. See [Model Capabilities](https://sdk.vercel.ai/providers) for more information.

</StepItem>

<StepItem>

Add to your `next.config.ts`:

```typescript title="next.config.ts" showLineNumbers copy
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  serverExternalPackages: ["@mastra/*"],
};

export default nextConfig;
```

</StepItem>

<StepItem>

You can start your Next.js app in the usual way.

</StepItem>

<StepItem>

Create a new API Route, and add the example code:

```bash copy
touch pages/api/test.ts
```

```typescript title="pages/api/test.ts" showLineNumbers copy
import type { NextApiRequest, NextApiResponse } from "next";

import { mastra } from "../../mastra";

export default async function getWeatherInfo(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const city = req.body.city;
  const agent = mastra.getAgent("weatherAgent");

  const result = await agent.generate(`What's the weather like in ${city}?`);

  return res.status(200).json(result.text);
}
```

</StepItem>

<StepItem>

Create a new Page, and add the example code:

```bash copy
touch pages/test.tsx
```

```typescript title="pages/test.tsx" showLineNumbers copy
import { useState } from "react";

export default function Test() {
  const [result, setResult] = useState<string | null>(null);

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    const formData = new FormData(event.currentTarget);
    const city = formData.get("city")?.toString();

    const response = await fetch("/api/test", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ city })
    });

    const text = await response.json();
    setResult(text);
  }

  return (
    <>
      <h1>Test</h1>
      <form onSubmit={handleSubmit}>
        <input name="city" placeholder="Enter city" required />
        <button type="submit">Get Weather</button>
      </form>
      {result && <pre>{result}</pre>}
    </>
  );
}
```

> You can now navigate to `/test` in your browser to try it out.

Submitting **London** as the city would return a result similar to:

```plaintext
Agent response: The current weather in London is as follows:

- **Temperature:** 12.9°C (Feels like 9.7°C)
- **Humidity:** 63%
- **Wind Speed:** 14.7 km/h
- **Wind Gusts:** 32.4 km/h
- **Conditions:** Overcast

Let me know if you need more information!
```

</StepItem>

  </Steps>
  </TabItem>
</Tabs>

## Next Steps

- [Deployment | With Next.js on Vercel](/docs/deployment/web-framework#with-nextjs-on-vercel)
- [Monorepo Deployment](../../deployment/monorepo)


---
title: "Integrate Mastra in your SvelteKit project | Frameworks"
description: A step-by-step guide to integrating Mastra with SvelteKit.
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import Steps from "@site/src/components/Steps";
import StepItem from "@site/src/components/StepItem";