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

# Build an App

> Create a notebook or a custom app, use the AI App Builder, and configure how the app starts, what it can reach and what the builder knows

This page covers creating each kind of app and everything you configure while
building one: the App Builder chat, the start command and port, the sandbox
environment, harness and vault, attached knowledge, sources and skills.

<Note>
  Building and configuring a custom app requires the **Builder** or **Admin**
  role in the workspace. Any member can create a notebook.
</Note>

## Create a notebook

<Steps>
  <Step title="Open the Notebooks page">
    Go to **Apps** and choose **Notebooks**.
  </Step>

  <Step title="Click New notebook">
    Fill in the dialog:

    * **Title**: the display name, for example `Sales analysis`.
    * **Name**: the notebook's file name in the shared folder and the reference
      agents use (`app:<name>`). Lowercase letters, digits, dash and underscore,
      up to 64 characters. It cannot be changed later.
    * **Description** (optional): what the notebook is for.
    * **Sandbox environment**: the image the notebook's kernel boots in. Only
      environments with a built notebook image can be picked; **Workspace
      default** uses the workspace's standard image.
  </Step>

  <Step title="Click Create">
    The notebook starts as soon as it is created and opens in the marimo editor.
    Add cells, run them, and the file is saved in the workspace's shared
    notebooks folder.
  </Step>
</Steps>

You can also ask an agent in chat, for example *"Create a notebook that charts
weekly signups"*. The agent uses its `create_notebook` tool and opens the
result beside the chat.

## Create a custom app

<Steps>
  <Step title="Open the Custom apps page">
    Go to **Apps** and choose **Custom apps**, then click **New app**.
  </Step>

  <Step title="Pick an app type">
    * **Regular app**: a UI for people, with APIs as needed.
    * **MCP app**: a UI for people and tools for agents.
  </Step>

  <Step title="Describe the app">
    Write who it is for and what it should do, or start from one of the ideas
    under **A few places to start** (**A dashboard**, **An internal tool**,
    **A customer portal**). Open **App name (optional)** to set the title and
    name yourself; otherwise a name is generated from the title.
  </Step>

  <Step title="Start building">
    **Start building** opens the App Builder and sends your description as the
    first message. **Skip to settings** opens the builder on its **Settings**
    tab without starting a chat.
  </Step>
</Steps>

### Import an existing folder

Already have the code? On the **Custom apps** page click **Import folder**,
pick a folder from your computer, and set a **Title** and **Name**. The files
land in the builder as a draft; nothing is published until you save a version
and publish it.

Include a `datagen.app.json` at the top of the folder to state how the app
starts (see [How the app starts](#how-the-app-starts)). A folder without one
still imports, but cannot be saved or published until the manifest exists. The
builder agent can read the code and write it for you.

## The App Builder

The App Builder lives at `/signalgen/apps/<appId>/build`. Open it with **Open
builder** on an app's detail page or **Edit** while viewing the app.

| Column | Tabs | What it does |
| - | - | - |
| Left | **Chats**, **Settings**, **Versions** | Past builder conversations, the app's configuration, and its saved versions |
| Center | **Chat** and open files | Talk to the builder; files the AI is writing open as tabs beside the chat |
| Right | **UI**, **API**, **Tools**, **Files** | Live preview of the draft, the app's discovered API and MCP tools, and the draft's file tree |

### Build with the chat

Describe a change, or ask about the app's files: *"Add a page that lists open
requests"*, *"Why does the chart show no data?"*. The builder edits a **draft**
copy of the app in its own builder sandbox. Nothing you do here reaches the
running app until you publish.

* **New chat** starts a fresh conversation about the same app.
* **Reload** refreshes the preview page; **Restart** stops and restarts the app
  process, which is needed after a command, port or dependency change.
* **Restart sandbox** recreates the builder sandbox and keeps your draft.
* **Discard** restores every pending file to the newest saved version.
  **Revert** does the same for one file.
* On the **API** and **Tools** tabs, **Add** and **Update** prepare a prompt in
  the chat describing the interface change; review it and send it when ready.

<Tip>
  One person edits an app at a time. If someone else holds the builder, the
  header shows who is editing. **Take over** makes your next change the one
  that counts; their in-flight turn still finishes.
</Tip>

## How the app starts

A custom app's start settings live in a `datagen.app.json` file at the root of
the app's files. The **How it starts** section in **Settings** shows the
current values read-only; edit the file (or ask the builder chat to) and the
settings follow.

```json datagen.app.json theme={null}
{
  "command": "python app.py",
  "port": 8080,
  "envVars": {
    "APP_MODE": "production"
  }
}
```

| Field | Meaning |
| - | - |
| `command` | The start command only. Dependencies are installed when a version is saved, so leave `npm install &&` and similar out. A custom app cannot use `marimo` as its command; create a notebook instead. |
| `port` | The port the app binds on `0.0.0.0`, between 1024 and 65535. The value is also exported as `$PORT`. A change recreates the sandbox. |
| `cwd` | Optional working directory, an absolute path inside the app's own folder. Defaults to the app's folder. |
| `envVars` | Plain, non-secret configuration as `{"NAME": "value"}`. Names use uppercase letters, digits and underscores. Put secrets in the vault. |
| `install` | Optional install command, used instead of the one detected from the dependency files. |
| `build` / `artifacts` | Optional build step and the paths it produces (for example `".next"`). Declare both or neither; the build output is baked into the version's image. |
| `dev` | Optional command for the builder preview only, for a dev server that serves from source. Published apps never use it. |

When the file is missing, the builder detects a likely start command from the
files (a `start` or `dev` script in `package.json`, an entry file at the root,
or a static `index.html`) and **Create datagen.app.json** or **Set up with
agent** writes the manifest.

<Warning>
  `datagen.app.json` cannot bind secrets. Keys such as `secrets` are rejected.
  Bind credentials in **Settings** instead, as described below.
</Warning>

### Dependencies

Dependencies declared in `package.json`, `package-lock.json`,
`requirements.txt`, `pyproject.toml` or `uv.lock` are installed into an image
for each saved version. Opening an app whose image is still building shows
**Installing dependencies** until it is ready.

## Settings

The **Settings** tab in the builder (and the **Settings** tab on the app's
detail page) holds everything the manifest does not. Anything left unset uses
the workspace default.

| Setting | What it controls |
| - | - |
| **Name** | The app's folder and the `app:<name>` reference. Permanent. |
| **Title**, **Description** | Shown on the Apps page and the detail page. |
| **Harness** | The runtime and model the builder chat runs on. See [Harness](/foundation/harness). |
| **Connection Vault** | Credentials the **running app** receives as environment variables. Each member's own values are used, so a per-user credential stays theirs. **No vault** means the app gets none. See [Vault](/foundation/vault). |
| **DataGen MCP** | Lets the builder chat call DataGen tools while writing the app. The published app never gets these tools. |
| **Tool bundle** | Which tools the builder chat may call. Applies only while DataGen MCP is on. |
| **Sandbox** | The sandbox environment the app starts in. Changing it rebuilds a custom app's dependency image on the new environment, then recreates the sandbox. See [Sandbox Environments](/foundation/sandbox-environments). |
| **Credential vault** | Workspace secrets the app's process receives as environment variables. Only the secret's name is stored on the app; the value stays in the vault. Restart the sandbox for a change to reach the running app. |

<Note>
  The port and sandbox environment are fixed when an app's sandbox starts.
  After changing them on the detail page, stop the app and open it again.
</Note>

## Give the builder knowledge and skills

### Attach knowledge bases

In **Settings > Knowledge bases** (or the detail page's **Tools & knowledge**
tab), click **Connect context** and pick a published knowledge base. Connected
knowledge bases are mounted read-only in the builder's sandbox as background
for writing the app. The published app does not read them.

See [Use Context](/context/use) for how knowledge bases are built and attached.

### Install skills

On the detail page's **Tools & knowledge** tab, the **Skills** section lists
skills approved in the workspace. Click **Install** to make one available to the
builder. Installed skills live only in the builder's sandbox; they are tools for
building the app, never part of a published version. When the registry has a
newer approved version, the row shows **Update available**.

See [Skills](/context/skills) for uploading and approving skills.

<Note>
  On deployments with the assets layer enabled, **Tools & knowledge** also lists
  the knowledge bases and analytic models the **running app** may read, as the
  person who opened it. Pick one and click **Connect**.
</Note>

## Give the running app data

### Sources: workspace files

The detail page's **Sources** tab selects workspace files the app can read.
Selected files are copied into the app's `.sources/` folder when its sandbox
starts, and the app can also read them through the Files API. Sources are not
part of a published version, so a running app always sees the current files.

After changing files, **Rebuild sources** re-copies them into the running app
without restarting it. A process that loads its data only at startup keeps the
old copy until you stop and reopen the app.

See [Files](/files/overview) for uploading files to the workspace.

### Databases

To query a database from the app's code, store a read-only credential in a
Connection Vault, select that vault in **Settings**, and read the connection
values from environment variables. The pattern is the same as for agents; see
[Query from code](/data/query-from-code).

## Next

<CardGroup cols={2}>
  <Card title="Publish and share" icon="share-nodes" href="/apps/publish-and-share">
    Save a version, publish it, and control who can open the app.
  </Card>

  <Card title="Ship an app tutorial" icon="graduation-cap" href="/tutorial/05-ship-an-app">
    Build a marimo dashboard from the demo data end to end.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.