# Managing Dives as Code
> Set up a Git-based workflow for developing, previewing, and deploying Dives, Flights, and their data dependencies.
Creating Dives through an AI agent is fast, but as your team relies on them for decision-making, you may want the same rigor you apply to production code: version history, code review, and automated deployments. Since Dives are React components and SQL queries under the hood, you can manage them with Git and CI/CD like the rest of your codebase.

For repositories that contain Dives, Flights, and shared data products, use [MotherDuck Blueprints](https://github.com/motherduckdb/motherduck-blueprints). Blueprints keeps independently owned resources in typed directories, connects producers and consumers with explicit inputs and outputs, deploys complete branch-scoped previews, and updates production through GitHub Actions.

The rest of this guide also documents the smaller [Dives-only starter repository](https://github.com/motherduckdb/blessed-dives-example). Use that workflow when your repository only manages Dives and you don't need dependency-aware Flight deployment.

## Choose a repository structure

A Blueprints repository can use this structure:

```text
flights/
  <producer_name>/
    blueprint.yml
    src/flight.py
dives/
  <dive_name>/
    blueprint.yml
    src/dive.tsx
guides/
roles/
projects/
shared/
```

Use `flights/`, `dives/`, `guides/`, and `roles/` when those resources have separate owners or deployment schedules. Use `projects/` when several resources need to preview, deploy, and roll back as one unit.

A Flight package can export a share under a stable output name, and a Dive package can consume it:

```yaml
# flights/events-ingest/blueprint.yml
outputs:
  events:
    share: events
```

```yaml
# dives/events-dashboard/blueprint.yml
inputs:
  events:
    blueprint: events-ingest
    output: events

resources:
  dives:
    dashboard:
      requiredResources:
        - input: events
          alias: events
```

For pull requests, Blueprints expands the selection upstream and downstream so the Flight, branch-scoped share, and Dive are previewed together. In production, changing a producer redeploys its consumers, while changing only a Dive uses the existing production output without rerunning the Flight.

## Start with the Dives-only repository

Fork the [Dives-only starter repository](https://github.com/motherduckdb/blessed-dives-example) when you don't need Flight or data dependency management. It includes:

- A working example Dive
- The Vite preview setup for local development
- GitHub Actions for deploy and cleanup
- A `CLAUDE.md` that teaches the agent the repo conventions

Fork the repo, set a `MOTHERDUCK_TOKEN` secret, and you're deploying Dives on merge.

## Prerequisites

- A [MotherDuck account](https://app.motherduck.com/)
- A GitHub repository to store your Dive source files, such as a repository based on [MotherDuck Blueprints](https://github.com/motherduckdb/motherduck-blueprints) or the [Dives-only starter repository](https://github.com/motherduckdb/blessed-dives-example)
- A MotherDuck API token set as a GitHub secret (`MOTHERDUCK_TOKEN`)

The Dives-only pull-down workflow below also requires a published Dive and [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) connected to the [MotherDuck MCP Server](/key-tasks/ai-and-motherduck/mcp-setup/). Blueprints can start from a Flight, Dive, Guide, role, or combined project and does not require an existing Dive.

## Pull a dive for local development

Start with a Dive that's already published in MotherDuck. Copy its share link from the MotherDuck UI, then tell Claude Code to set it up locally:

```text
Set up this dive for local development: https://app.motherduck.com/dives/...
```

The agent uses the MotherDuck MCP Server to:

1. Read the Dive source through the SQL API using the share link
2. Pull down the file into a local directory in your repo
3. Register the Dive for CI
4. Start a lightweight Vite development server for live preview

The MCP Server's `get_dive_guide` tool provides the agent with everything it needs — the React component contract, dependency setup, and instructions for the local dev server. No additional skills or context files are required beyond what the MCP server provides.

![Claude Code spinning up the Vite dev server after pulling down a Dive for local development.](./img/claude_code_vite_terminal_1ffa9f80a9.png)

## Edit locally with an AI agent

With the local dev server running, you can iterate on the Dive using Claude Code. The agent can restyle charts, rewrite SQL queries, add filters, swap visualizations — anything you can express as a prompt.

```text
Make this much better visually. Top-tier style please.
```

The Vite dev server hot-reloads changes, so you see updates instantly in the browser. The MCP server provides schema context so the agent writes accurate SQL against your live data.

![A Dive running locally, showing the updated dashboard with improved styling and layout.](./img/dive_local_preview_9bccdb19bf.png)

If your repo includes a `CLAUDE.md` file (the [Dives-only starter repository](https://github.com/motherduckdb/blessed-dives-example) includes one), the agent also knows the folder conventions and how to register Dives for CI.

## Deploy a preview with GitHub actions

Once you're happy with your changes, tell the agent to push a PR:

```text
Put up a PR on a new feature branch
```

When a PR is opened (or updated with new commits), a GitHub Action detects which Dive folders changed and deploys a **preview** Dive to MotherDuck. The preview uses the same live environment as production but has a branch-tagged title so it's clearly labeled. A comment appears on the PR with a direct link.

![A GitHub Actions bot comment on a PR showing a preview Dive link — click Open Dive to see it live in MotherDuck.](./img/pr_preview_comment_13ca302ff9.png)

Your reviewer clicks the link and sees the Dive running with live queries — no local setup needed.

The deploy action uses path filters to detect which Dive folders changed, then calls a shared deploy script (`scripts/deploy-dive.sh`) for each one. The script reads the Dive's source and metadata, and uses the DuckDB CLI with the MotherDuck extension to create or update the Dive.

## Merge to production

When the preview looks right, merge the PR. A separate deploy job runs that creates or updates the production Dive, matched by title.

The production Dive is now live and shareable with anyone in your organization.

![The deploy GitHub Action after a merge to main, completing in 20 seconds.](./img/deploy_action_success_f763894ae0.png)

## Clean up preview dives

Delete the feature branch after merging. A cleanup action fires that removes the preview Dive from your MotherDuck account — no orphaned Dives cluttering your workspace.

The entire pipeline is two GitHub Actions and one secret (`MOTHERDUCK_TOKEN`). At MotherDuck, we use a dedicated service account so anyone with repo access can edit and deploy with the same ownership scope.

## Related resources

- [Creating Visualizations with Dives](/key-tasks/dives/) — Create Dives from natural language with AI agents
- [Dives SQL functions](/sql-reference/motherduck-sql-reference/dives/) — Manage Dives directly from SQL
- [Connect to MCP Server](/key-tasks/ai-and-motherduck/mcp-setup/) — Set up the MCP server with your AI assistant
- [MotherDuck Blueprints](https://github.com/motherduckdb/motherduck-blueprints) — Manage Dives, Flights, Guides, roles, and dependency-aware deployments in Git
- [Dives-only starter repository](https://github.com/motherduckdb/blessed-dives-example) — Use the smaller workflow for repositories that only deploy Dives


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fkey-tasks%2Fdives%2Fmanaging-dives-as-code%2F&page_title=Managing%20Dives%20as%20Code&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
