> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datazone.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Build and host custom React applications on your Datazone data, served behind your organisation's authentication

<Frame>
  <img src="https://mintcdn.com/datazone/Dwpxvpe4vYSjsj1i/images/covers/studio_app.png?fit=max&auto=format&n=Dwpxvpe4vYSjsj1i&q=85&s=c6d4b0623ca499c076129d4f835f8fc9" alt="Studio Apps" width="1920" height="741" data-path="images/covers/studio_app.png" />
</Frame>

# Studio Apps

A Studio App is a **Vite + React single-page application that lives in your project repository**. Datazone installs its dependencies, builds it in an isolated sandbox, and serves the result at a URL inside your deployment — behind the same session that protects the rest of Datazone.

Unlike an [Intelligent App](/reference/intelligent-apps/overview), which you describe declaratively in YAML, a Studio App is code you write. You get the whole React ecosystem and, with it, everything a dashboard cannot do: multi-step forms, write-back to [Knowledge Objects](/reference/knowledge-objects/overview), custom interactions, bespoke layouts.

## What you get

* **A real URL, behind your authentication** — the app is served from your Datazone deployment and only to signed-in users of the organisation that owns it. There is no separate hosting, no separate login.
* **The API, already authenticated** — the browser sends the user's Datazone session with every request. The app ships no API key, and every call runs with that user's permissions.
* **One build per branch** — each branch of your repository builds and serves its own version of the app, so you can review a change on a feature branch before it reaches `main`.
* **A pre-wired scaffold** — routing, Tailwind 4, the shadcn component setup, and a small Datazone client are generated for you.
* **Nothing to operate** — no Dockerfile, no deployment pipeline, no CDN configuration. Push, then build.

## When to use one

| Use                                          | Choose                                                                      |
| -------------------------------------------- | --------------------------------------------------------------------------- |
| Charts, KPIs, filters over existing datasets | [Intelligent App](/reference/intelligent-apps/overview)                     |
| Users need to create or edit records         | **Studio App** + [Knowledge Objects](/reference/knowledge-objects/overview) |
| A custom workflow, wizard, or internal tool  | **Studio App**                                                              |
| Exposing data to another system              | [Endpoint](/reference/integration/endpoints)                                |

An Intelligent App is considerably less work when it fits. Reach for a Studio App when you need behaviour a dashboard cannot express.

## How it works

1. **Create the app.** Datazone scaffolds a complete Vite + React app into `studio/<alias>/` and registers it in your project's `config.yml`, in a single commit.
2. **Write your app.** Edit the files in the repository — in the built-in code editor, with Orion, or locally with `git`. Push your changes.
3. **Build.** Datazone runs `npm install` and `vite build` in a sandboxed job, then publishes the static bundle.
4. **Open it.** The app is served at its URL for signed-in members of your organisation.

Registering an app makes it appear in Datazone; it does **not** build it. Building is an explicit step, so pushing a broken commit never takes down a working app.

## The app in your repository

```
studio/sales_dashboard/
├── package.json          pinned dependencies
├── index.html
├── vite.config.js
├── components.json       shadcn configuration
├── tsconfig.json
└── src/
    ├── main.tsx          router entry
    ├── App.tsx           your routes
    ├── index.css         Tailwind 4 theme
    ├── lib/datazone.ts   the Datazone client
    ├── lib/utils.ts
    ├── components/app-layout.tsx
    └── components/ui/    shadcn components you add
```

And in `config.yml`:

```yaml theme={null}
studio_apps:
  - alias: sales_dashboard
    name: Sales Dashboard
    path: studio/sales_dashboard
```

## Talking to Datazone

The scaffold includes `src/lib/datazone.ts`, a small client for the Datazone API. It sends requests same-origin and relative, so the browser attaches the user's session cookie automatically.

```tsx theme={null}
import { callEndpoint, executeQuery, getMe } from "@/lib/datazone"

const user = await getMe()

const rows = await executeQuery<{ region: string; total: number }>(
  "select region, sum(amount) as total from sales group by region",
)

const { records } = await callEndpoint("daily-revenue", { page_size: 50 })
```

| Export                       | Purpose                                                       |
| ---------------------------- | ------------------------------------------------------------- |
| `getMe()`                    | The signed-in user                                            |
| `executeQuery(sql)`          | SQL over the datasets this user can read                      |
| `callEndpoint(slug, params)` | Call a published [endpoint](/reference/integration/endpoints) |
| `apiFetch(path, init)`       | Any other API path                                            |
| `branch`, `projectId`        | The branch this build came from, and the project              |
| `branchQuery(filters)`       | Build a `branch=…&filters=…` query string                     |

Permissions are enforced by the API on every call, so a user who cannot read a dataset cannot read it through your app either. There is no API key in the bundle, and none is needed.

<Warning>
  Never put an API key, token, or secret in a Studio App. The bundle is JavaScript delivered to the browser — anything in it is visible to everyone who can open the app.
</Warning>

## Storing data

A Studio App is static files. It has no database and no server-side code, so anything users create or edit belongs in a [Knowledge Object](/reference/knowledge-objects/overview) — a versioned entity declared in your repository with a governed CRUD API.

That combination is the usual shape of an internal tool: objects for the records, a Studio App for the interface.

```tsx theme={null}
import { apiFetch, branch } from "@/lib/datazone"

// Instances are addressed by their `_key`, and every call takes the app's branch.
await apiFetch(`/knowledge-object/${objectId}/instances/${key}?branch=${branch}`, {
  method: "PATCH",
  body: JSON.stringify({ status: "SHIPPED" }),
})
```

See the [Knowledge Objects API](/reference/knowledge-objects/api) for the full surface.

## Branches and builds

Every app is built **per branch**. A branch has its own bundle, its own URL, and its own build history — the app on `feat/new-layout` is a different deployment from the one on `main`.

Two consequences worth remembering:

* After pushing, build again. Datazone marks the served build **stale** when the branch has moved on, but it does not rebuild on its own.
* Branch-scoped data (Knowledge Objects, for example) defaults to your default branch when a request does not name one. The client exports `branch` for exactly this reason — pass it, or an app on a feature branch will quietly read `main`'s data.

Build status is one of `NOT_BUILT`, `QUEUED`, `BUILDING`, `READY`, `ERROR`, or `TIMEOUT`. Logs for every build, successful or not, are on the app's **Builds** tab.

## Building with Orion

Orion knows how Studio Apps are structured and can write one for you — including designing the Knowledge Objects behind it. Describing what you want ("an app to manage orders, with a status filter and a create form") is usually faster than starting from the scaffold by hand.

## Limits

* **The app is client-side only.** No server-side rendering, no API routes, no server secrets.
* **Dependencies come from npm at build time**, from your `package.json`. Pin exact versions so a rebuild of the same commit installs the same code.
* **Builds are sandboxed and time-limited.** A build that hangs is marked `TIMEOUT`.
* **An app belongs to one organisation.** Users from other organisations are refused, not merely unable to find it.

## Next steps

* [Getting Started](/reference/studio-apps/getting-started) — create, build, and open your first app
* [Knowledge Objects](/reference/knowledge-objects/overview) — where a Studio App's data belongs
* [Endpoints](/reference/integration/endpoints) — publish a query for your app to call
* [Project Repository](/reference/development/project) — how `config.yml` ties it together
