# Mastra v1 Release

Mastra v1 was released! Start [new projects](/content/docs/getting-started/start/index.html) with v1 or [upgrade](/content/guides/migrations/upgrade-to-v1/overview/index.html) your existing project today.

## On this page

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.

- App Router  
- Pages 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`.

## Integration Steps

1. 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
   npx mastra@^0 init --dir . --components agents,tools --example --llm openai
   ```
   > See [mastra init](/content/reference/v0/cli/create-mastra/index.html) 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
   npx mastra@^0 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:

2. **Set Up API Key**
   
   `.env`
   
   ```bash
   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.

3. **Add to your `next.config.ts`:**
   
   `next.config.ts`
   
   ```typescript
   import type { NextConfig } from "next";

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

export default nextConfig;
   ```

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

5. **Create a new directory that will contain a Page, Action, and Form for testing purposes:**
   
   ```bash
   mkdir app/test
   ```

6. **Create a new Action, and add the example code:**
   
   ```bash
   touch app/test/action.ts
   ```
   
   `app/test/action.ts`
   
   ```typescript
   "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;
   }
   ```

7. **Create a new Form component, and add the example code:**
   
   ```bash
   touch app/test/form.tsx
   ```
   
   `app/test/form.tsx`
   
   ```typescript
   "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>}
          </>
        );
   }
   ```

8. **Create a new Page, and add the example code:**
   
   ```bash
   touch app/test/page.tsx
   ```
   
   `app/test/page.tsx`
   
   ```typescript
   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.

### Test Output

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!
```

---

**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`.

## Integration Steps for Pages Router

1. **Repeat the setup from above, paying attention to directory structure and commands.**

5. **Create a new API Route, and add the example code:**
   
   ```bash
   touch pages/api/test.ts
   ```
   
   `pages/api/test.ts`
   
   ```typescript
   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);
   }
   ```

6. **Create a new Page, and add the example code:**
   
   ```bash
   touch pages/test.tsx
   ```
   
   `pages/test.tsx`
   
   ```typescript
   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.

### Test Output

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!
```
