# Studio deployment

Studio is a React-based Single Page Application (SPA) that runs in the browser and connects to a running [Mastra server](https://mastra.ai/docs/deployment/mastra-server).

You can deploy Studio in two primary ways:

- [Cloud](https://mastra.ai/docs/mastra-cloud/overview) hosts Studio for you and allows you to share access with your team via link
- You can self-host Studio on your own infrastructure, either alongside your Mastra server or separately as a standalone SPA

On this page you'll learn how to deploy Studio on your own infrastructure. As the finer details of deployment can vary widely based on your needs and setup, we'll cover the general principles and options available to you.

## Quickstart

The easiest way to run Studio is the [`mastra studio`](https://mastra.ai/reference/cli/mastra) command.

Whereas `mastra dev` runs both Studio and an API for development purposes, the purpose of `mastra studio` is to serve a standalone, static UI that connects to an already-running Mastra server. This allows you to deploy Studio on its own, separate from the Mastra server, if desired.

Open a terminal and install the `mastra` CLI globally:

**npm**:

```bash
npm install -g mastra
```

**pnpm**:

```bash
pnpm add -g mastra
```

**Yarn**:

```bash
yarn global add mastra
```

**Bun**:

```bash
bun add --global mastra
```

Run the `mastra studio` command:

```bash
mastra studio
```

Open [localhost:3000](http://localhost:3000) in your browser to see the Studio UI. By default, it will attempt to connect to a Mastra server running at `http://localhost:4111`. If it doesn't find one there, you'll see a form where you can enter your Mastra instance URL and API prefix.

If you're hosting Studio under a subpath (for example `/agents` behind Nginx), set `MASTRA_STUDIO_BASE_PATH` before starting Studio:

```bash
MASTRA_STUDIO_BASE_PATH=/agents mastra studio
```

This updates the HTML base URL and static asset routing so the standalone Studio works correctly under that subpath.

The command uses Node's built-in `http` module and [`serve-handler`](https://www.npmjs.com/package/serve-handler) to serve the static files.

## Running a server

Running `mastra studio` as a long-running process is no different from running any other Node.js service. All the best practices, tools, and options for deployment apply here as well. You can use process managers like PM2, use Docker, or cloud services that support Node.js applications. You'll need to ensure CORS is configured correctly and errors are monitored, as with any web service.

> **Warning:** Once Studio is connected to your Mastra server, it has full access to your agents, workflows, and tools. Be sure to secure it properly in production (e.g. behind authentication, VPN, etc.) to prevent unauthorized access.
>
> Visit the [Authentication](https://mastra.ai/docs/studio/auth) docs to learn more.

### Alongside your API

Alternatively, you can serve Studio alongside your [Mastra server](https://mastra.ai/docs/deployment/mastra-server). This way you only have one service to deploy and manage.

To do this, run `mastra build` with the `--studio` flag:

```bash
mastra build --studio
```

It'll create a `.mastra/output/studio` folder with the built Studio assets. By defining the `MASTRA_STUDIO_PATH` environment variable, the Mastra server can serve the Studio UI, too.

```bash
MASTRA_STUDIO_PATH=.mastra/output/studio node .mastra/output/index.mjs
```

## Using a CDN

### Automatic

Some of the [Cloud providers](https://mastra.ai/docs/deployment/cloud-providers) offer an option to deploy Studio alongside your serverless function. Currently, the supported providers are:

- [`VercelDeployer`](https://mastra.ai/reference/deployer/vercel)

### Manual

You can't directly deploy the built Studio assets to a CDN, as the UI relies on some dynamic configuration. With a bit of extra setup, you can create a standalone SPA out of the built assets and deploy it to any static hosting service.

Follow the example below to create a SPA using Vite.

1. Create a new folder and initialize a new Node.js project:

   **npm**:

   ```bash
   mkdir studio-spa
   cd studio-spa
   npm init
   ```

   **pnpm**:

   ```bash
   mkdir studio-spa
   cd studio-spa
   pnpm init
   ```

   **Yarn**:

   ```bash
   mkdir studio-spa
   cd studio-spa
   yarn init
   ```

   **Bun**:

   ```bash
   mkdir studio-spa
   cd studio-spa
   bun init
   ```

2. Install `vite` and `mastra` as dependencies:

   **npm**:

   ```bash
   npm install vite mastra
   ```

   **pnpm**:

   ```bash
   pnpm add vite mastra
   ```

   **Yarn**:

   ```bash
   yarn add vite mastra
   ```

   **Bun**:

   ```bash
   bun add vite mastra
   ```

3. Add a build script to your `package.json`:

   ```json
   {
     "scripts": {
       "build": "vite build"
     }
   }
   ```

4. Create a placeholder `index.html` file:

   ```html
   <!doctype html>
   <html>
     <head></head>
     <body></body>
   </html>
   ```

5. Create a `vite.config.js` file. It copies the built Studio assets to the `dist` folder and replaces any `%%PLACEHOLDER%%` values in the HTML with environment variable values.

   ```js
   import { defineConfig, loadEnv } from 'vite'
   import { readFileSync, cpSync, writeFileSync } from 'node:fs'
   import { resolve, join } from 'node:path'

   const studioDir = resolve(import.meta.dirname, 'node_modules/mastra/dist/studio')

   export default defineConfig(({ mode }) => {
     const env = loadEnv(mode, process.cwd(), 'MASTRA_')

     return {
       plugins: [
         {
           name: 'mastra-studio',
           closeBundle() {
             const outDir = resolve(import.meta.dirname, 'dist')
             cpSync(studioDir, outDir, { recursive: true })

             const indexPath = join(outDir, 'index.html')
             const html = readFileSync(indexPath, 'utf-8')
             writeFileSync(
               indexPath,
               html.replaceAll(/%%(\w+)%%/g, (_, key) => env[key] ?? ''),
             )
           },
         },
       ],
       build: {
         emptyOutDir: true,
       },
     }
   })
   ```

6. Create a `.env` file with the necessary environment variables.

   ```env
   MASTRA_SERVER_HOST=localhost
   MASTRA_SERVER_PORT=4111
   MASTRA_SERVER_PROTOCOL=http
   MASTRA_API_PREFIX=/api
   MASTRA_HIDE_CLOUD_CTA=false
   MASTRA_CLOUD_API_ENDPOINT=
   MASTRA_EXPERIMENTAL_FEATURES=false
   MASTRA_TEMPLATES=false
   MASTRA_TELEMETRY_DISABLED=true
   MASTRA_REQUEST_CONTEXT_PRESETS=
   MASTRA_THEME_TOGGLE=false
   MASTRA_EXPERIMENTAL_UI=false
   MASTRA_STUDIO_BASE_PATH=
   ```

7. Run the build script to generate the static files in the `dist` folder:

   **npm**:

   ```bash
   npm run build
   ```

   **pnpm**:

   ```bash
   pnpm run build
   ```

   **Yarn**:

   ```bash
   yarn build
   ```

   **Bun**:

   ```bash
   bun run build
   ```

8. Point your hosting provider to the `dist` folder and deploy!