---
title: "React + Vite | Frameworks"
description: A step-by-step guide to integrating Mastra with React and Vite.
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Integrate Mastra in your React + Vite project

In this guide, you'll build a tool-calling AI agent using Mastra, then connect it to React by calling the agent directly from Mastra's standalone server.

You'll use [AI SDK UI](https://ai-sdk.dev/docs/ai-sdk-ui/overview) and [AI Elements](https://ai-sdk.dev/elements) to create a beautiful, interactive chat experience.

## Before you begin

- You'll need an API key from a supported [model provider](/models/v1). If you don't have a preference, use [OpenAI](/models/v1/providers/openai).
- Install Node.js `v22.13.0` or later

## Create a new React + Vite app (optional)

If you already have a React + Vite app using Tailwind, skip to the next step.

### Project scaffold

Run the following command to [create a new React + Vite app](https://vite.dev/guide/#scaffolding-your-first-vite-project):

<Tabs groupId="pm">
<TabItem value="npm" label="npm">
```bash
npm create vite@latest mastra-react -- --template react-ts
cd mastra-react
```
</TabItem>
<TabItem value="pnpm" label="pnpm">
```bash
pnpm create vite mastra-react --template react-ts
cd mastra-react
```
</TabItem>
<TabItem value="yarn" label="yarn">
```bash
yarn create vite mastra-react --template react-ts
cd mastra-react
```
</TabItem>
<TabItem value="bun" label="bun">
```bash
bun create vite mastra-react --template react-ts
cd mastra-react
```
</TabItem>
</Tabs>

This creates a project called `mastra-react`, but you can replace it with any name you want.

### Tailwind

Next, install Tailwind: 

<Tabs groupId="pm">
<TabItem value="npm" label="npm">
```bash
npm install tailwindcss @tailwindcss/vite
```
</TabItem>
<TabItem value="pnpm" label="pnpm">
```bash
pnpm add tailwindcss @tailwindcss/vite
```
</TabItem>
<TabItem value="yarn" label="yarn">
```bash
yarn add tailwindcss @tailwindcss/vite
```
</TabItem>
<TabItem value="bun" label="bun">
```bash
bun add tailwindcss @tailwindcss/vite
```
</TabItem>
</Tabs>

Configure the Vite plugins:

```typescript title="vite.config.ts" {3-4,7-12}
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from "path"
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
})
```

Replace everything in `src/index.css` with the following:

```css title="src/index.css"
@import "tailwindcss";
```

Add these `compilerOptions` to `tsconfig.json`:

```ts title="tsconfig.json"
{
  // ...
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
```

Edit `tsconfig.app.json` to resolve paths:

```ts title="tsconfig.app.json"
{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./src/*"
      ]
    }
    // ...
  }
}
```

## Initialize Mastra

Run [`mastra init`](/reference/v1/cli/mastra#mastra-init). When prompted, choose a provider (e.g. OpenAI) and enter your key:

<Tabs groupId="pm">
<TabItem value="npm" label="npm">

```bash
cd mastra-react
npx mastra@beta init
```

</TabItem>
<TabItem value="pnpm" label="pnpm">

```bash
cd mastra-react
pnpm dlx mastra@beta init
```

</TabItem>
<TabItem value="yarn" label="yarn">

```bash
cd mastra-react
yarn dlx mastra@beta init
```

</TabItem>
<TabItem value="bun" label="bun">

```bash
cd mastra-react
bunx mastra@beta init
```

</TabItem>
</Tabs>

This creates a `src/mastra` folder with an example weather agent and the following files:

-	`index.ts` - Mastra config, including memory
- `tools/weather-tool.ts` - a tool to fetch weather for a given location
-	`agents/weather-agent.ts`- a weather agent with a prompt that uses the tool

You'll call `weather-agent.ts` from your chat UI in the next steps.

## Install AI SDK UI & AI Elements

Install AI SDK UI along with the Mastra adapter:

<Tabs groupId="pm">
<TabItem value="npm" label="npm">

```bash
npm install @mastra/ai-sdk@beta @ai-sdk/react ai
```

</TabItem>
<TabItem value="pnpm" label="pnpm">

```bash
pnpm add @mastra/ai-sdk@beta @ai-sdk/react ai
```

</TabItem>
<TabItem value="yarn" label="yarn">

```bash
yarn add @mastra/ai-sdk@beta @ai-sdk/react ai
```

</TabItem>
<TabItem value="bun" label="bun">

```bash
bun add @mastra/ai-sdk@beta @ai-sdk/react ai
```

</TabItem>
</Tabs>

Next, initialize AI Elements. When prompted, choose the default options:

<Tabs groupId="pm">
<TabItem value="npm" label="npm">

```bash
npx ai-elements@latest
```

</TabItem>
<TabItem value="pnpm" label="pnpm">

```bash
pnpm dlx ai-elements@latest
```

</TabItem>
<TabItem value="yarn" label="yarn">

```bash
yarn dlx ai-elements@latest
```

</TabItem>
<TabItem value="bun" label="bun">

```bash
bunx ai-elements@latest
```

</TabItem>
</Tabs>

This downloads the entire AI Elements UI component library into a `@/components/ai-elements` folder.

## Create a chat route

Open ⁠`src/mastra/index.ts` and add a [⁠chatRoute()](https://github.com/reference/v1/ai-sdk/chat-route) to your config. This creates an API route your React frontend can call for AI SDK-compatible chat responses, which you’ll use with ⁠useChat() next.

```ts title="src/mastra/index.ts"
import { Mastra } from '@mastra/core/mastra';
// Existing imports...
import { chatRoute } from "@mastra/ai-sdk"

export const mastra = new Mastra({
  // Existing config...
  server: {
    apiRoutes: [
      chatRoute({
        path: '/chat/:agentId'
      })
    ]
  }
});
```

## Add the chat UI

Replace the `src/App.tsx` file to create a chat interface:

```tsx title="src/App.tsx"
import * as React from 'react';
import { DefaultChatTransport, type ToolUIPart } from 'ai';
import { useChat } from '@ai-sdk/react';

import {
  PromptInput,
  PromptInputBody,
  PromptInputTextarea,
} from '@/components/ai-elements/prompt-input';

import {
  Conversation,
  ConversationContent,
  ConversationScrollButton,
} from '@/components/ai-elements/conversation';

import {
  Message,
  MessageContent,
  MessageResponse
} from '@/components/ai-elements/message';

import {
  Tool,
  ToolHeader,
  ToolContent,
  ToolInput,
  ToolOutput,
} from '@/components/ai-elements/tool';

export default function App() {
  const [input, setInput] = React.useState<string>('');

  const { messages, sendMessage, status } = useChat({
    transport: new DefaultChatTransport({
      api: 'http://localhost:4111/chat/weather-agent',
    }),
  });

  const handleSubmit = async () => {
    if (!input.trim()) return;

    sendMessage({ text: input });
    setInput('');
  };

  return (
    <div className="max-w-4xl mx-auto p-6 relative size-full h-screen">
      <div className="flex flex-col h-full">
        <Conversation className="h-full">
          <ConversationContent>
            {messages.map((message) => (
              <div key={message.id}>
                {message.parts?.map((part, i) => {
                  if (part.type === 'text') {
                    return (
                      <Message
                        key={`${message.id}-${i}`}
                        from={message.role}>
                          <MessageContent>
                            <MessageResponse>{part.text}</MessageResponse>
                          </MessageContent>
                      </Message>
                    );
                  }

                  if (part.type?.startsWith('tool-')) {
                    return (
                      <Tool key={`${message.id}-${i}`}>
                        <ToolHeader
                          type={(part as ToolUIPart).type}
                          state={(part as ToolUIPart).state || 'output-available'}
                          className="cursor-pointer"
                        />
                        <ToolContent>
                          <ToolInput input={(part as ToolUIPart).input || {}} />
                          <ToolOutput
                            output={(part as ToolUIPart).output}
                            errorText={(part as ToolUIPart).errorText}
                          />
                        </ToolContent>
                      </Tool>
                    );
                  }

                  return null;
                })}
              </div>
            ))}
            <ConversationScrollButton />
          </ConversationContent>
        </Conversation>
        <PromptInput onSubmit={handleSubmit} className="mt-20">
          <PromptInputBody>
            <PromptInputTextarea
              onChange={(e) => setInput(e.target.value)}
              className="md:leading-10"
              value={input}
              placeholder="Ask about the weather..."
              disabled={status !== 'ready'}
            />
          </PromptInputBody>
        </PromptInput>
      </div>
    </div>
  );
}
```

This component connects [`useChat()`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) to the `chat/weather-agent` endpoint, sending prompts there and streaming the response back in chunks.

It renders the response text using the [`<MessageResponse>`](https://ai-sdk.dev/elements/components/message#messageresponse-) component, and shows any tool invocations with the [`<Tool>`](https://ai-sdk.dev/elements/components/tool) component.

## Test your agent

In order to test your agent with the chat interface, you need to run both the Mastra server and the Vite development server.

1. Start the Mastra development server:

    ```bash copy
    npx mastra dev
    ```
1. In a separate terminal window, start the Vite development server:

    ```bash copy
    npm run dev
    ```
1. Open your application at http://localhost:5173
1. Try asking about the weather. If your API key is set up correctly, you'll get a response

## Next steps

Congratulations on building your Mastra agent with React! 🎉

From here, you can extend the project with your own tools and logic:

- Learn more about [agents](/docs/v1/agents/overview)
- Give your agent its own [tools](/docs/v1/agents/using-tools)
- Add human-like [memory](/docs/v1/agents/agent-memory) to your agent

When you're ready, read more about how Mastra integrates with AI SDK UI and React, and how to deploy your agent anywhere:

- Integrate Mastra with [AI SDK UI](/guides/v1/build-your-ui/ai-sdk-ui)
- Deploy your agent [anywhere](/docs/v1/deployment/overview)
