---
title: "Embedded Dives: Interactive Data Apps for Customer-Facing Analytics"
canonical: "https://motherduck.com/blog/introducing-embedded-dives/"
related:
  - title: "Embedding Dives in your web application | MotherDuck Docs"
    url: "https://motherduck.com/docs/key-tasks/ai-and-motherduck/dives/embedding-dives/"
  - title: "Vibe-Coding a Dashboard? Here Are 5 Steps So It Doesn't Suck"
    url: "https://motherduck.com/blog/vibecoding-dashboards-best-practices/"
  - title: "Building Interactive Data Apps with MotherDuck Dives | MotherDuck"
    url: "https://motherduck.com/videos/interactive-data-apps-motherduck-dives/"
gated_asset:
  title: "Dives: Interactive Dashboards & Embedded Analytics"
  url: "https://motherduck.com/product/dives/"
---

# Embedded Dives: Interactive Data Apps for Customer-Facing Analytics

Today, we're releasing embedding for Dives, allowing developers to build fast, interactive data experiences in their own applications. Embedding is included with Business plans on MotherDuck at no additional cost.

Most companies that provide [customer-facing analytics](https://motherduck.com/learn/customer-analytics-dashboard) do it through an embedded BI tool. It makes sense: you edit a dashboard, your customers see the change. No deploys, no CI pipelines. Dashboards are code, but the BI tool owns the infrastructure, so you get to treat them as content. The tradeoff is that the embed is always their dashboard viewer inside your app. You get their charts, their filters, their interaction patterns. You can theme it, but it'll always look and feel like a BI tool stuck into your application.

Well, *certainly* AI changes this dynamic. After all, it's nearly trivial to vibe-code a one-off dashboard or visualization using ubiquitous web development tools. What used to require a frontend team now takes a conversation with an agent. That's the world [Dives](https://motherduck.com/docs/key-tasks/ai-and-motherduck/dives/) were built for: MotherDuck's AI-created interactive visualizations, built as React components that directly query your data.

But creating a dashboard with AI is only half the problem. You still need to get it in front of your customers. Because Dives are just React and SQL, it’s dead-simple for customers to make a Dive look like their own native application. And the case for embedding is strong, even when building from scratch is cheap: even our most technical customers prefer Dive embeds over CI/CD pipelines. Skip the deploy, just publish. Same content model as a BI tool paired with the incredible flexibility of vibe-coded React.

Before we, ahem, dive in, here's an example of an embedded Dive querying MotherDuck. Press **play**, then click and drag on the timeline to filter earthquake events. You'll notice that latency is nearly instantaneous thanks to MotherDuck's dual execution architecture with DuckDB-Wasm; more on this below.

<br>

<motherduck-dive dive-id="a8b3cfd3-a134-425b-8be6-044847d3b13e"></motherduck-dive>

<br>

Anything you can build with React and SQL is fair game. Here's another example, using a clever Datadog-style query interface. This one runs on server-side compute, but queries are still incredibly fast.

<br>

<motherduck-dive dive-id="a3efa3d5-5bef-4ab9-9dcf-c2a3b927afe6"></motherduck-dive>

<br>

You can head over to the [Dive Gallery](https://motherduck.com/dive-gallery/) to see examples from the community, then check out the [documentation](https://motherduck.com/docs/key-tasks/ai-and-motherduck/dives/embedding-dives/) for a guide on embedding Dives in your own application. Get inspired, create your own Dives, and share with the community!

## Dual Execution: Fast Interactions with DuckDB-Wasm

MotherDuck's [dual execution architecture](https://motherduck.com/docs/concepts/architecture-and-capabilities/) places a full DuckDB engine on the client and the server; both in the MotherDuck cloud, and one in your browser via WebAssembly. When an embedded Dive loads, the cloud engine handles the initial query and streams the result set into the browser's local DuckDB instance. From that point on, every interaction–filtering, cross-filtering, aggregation–executes entirely client-side with no network roundtrips. The result is 5-20ms query latency on interactions, the kind of responsiveness you'd expect from a native app, not a BI tool-generated dashboard.

This isn't something you can bolt onto a traditional cloud warehouse. It requires a fully-functioning database engine on both ends, which is a unique property of MotherDuck's architecture built on DuckDB. Dual execution offers the foundation for highly performant analytics user experiences: the full power of a cloud data warehouse for heavy lifting, and local compute for instant interactivity.

For customer-facing use cases, this architecture pairs with MotherDuck's [hypertenancy model](https://motherduck.com/docs/concepts/hypertenancy/). You can grant each application user a embedded user gets [isolated compute](https://motherduck.com/product/hypertenancy/) on the server side (a "Duckling"). One customer's queries never compete with another's–no noisy neighbors and no degraded user experience at scale.

Embedded Dives support two query modes:

- **Server mode** (default): Queries execute via MotherDuck's Postgres endpoint. Simple to deploy, no special headers required.
- **Dual mode**: Queries use the full hybrid architecture with DuckDB-Wasm in the browser. Add `?queryMode=wasm` to the embed URL. This mode requires [cross-origin isolation headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy) (`Cross-Origin-Embedder-Policy: require-corp` and `Cross-Origin-Opener-Policy: same-origin`) on the parent page. The latency difference is significant for interactive workloads.

While cross-origin isolation won't be an option for every deployment, we're working to ease this restriction in the future.

## Getting Started

### Create a Dive

Dives are created through natural language using an AI agent connected to the [MotherDuck MCP Server](https://motherduck.com/docs/getting-started/mcp-getting-started/). Here's the workflow with Claude Code:

```bash
# Add the MotherDuck MCP server
claude mcp add MotherDuck --transport http https://api.motherduck.com/mcp

# Start Claude Code and authenticate via /mcp
claude
```

From there, it's conversational. Ask your agent to explore your data, then describe the visualization you want:

> "Create a Dive showing monthly revenue by region for the last 12 months, with a date range filter."

The agent writes the React component, connects it to your MotherDuck data, and launches a local dev server with hot-reload so you can iterate. When you're happy with the result, tell the agent to save it to MotherDuck.

Under the hood, a Dive is a React component that uses a special hook, [`useSQLQuery`](https://motherduck.com/docs/sql-reference/motherduck-sql-reference/ai-functions/dives/use-sql-query/), to execute SQL against your MotherDuck databases, with [Recharts](https://recharts.org/) for visualization and Tailwind CSS for styling. You never need to touch the code unless you want to.

See the [Dives documentation](https://motherduck.com/docs/key-tasks/ai-and-motherduck/dives/) for the full guide.

### Embed It

Embedding follows a backend-to-frontend flow. Your server creates an embed session (keeping credentials safe), and the frontend renders the Dive in an iframe.

**Step 1: Create an embed session (backend)**

```javascript
// Node.js
const response = await fetch(
  `https://api.motherduck.com/v1/dives/${DIVE_ID}/embed-session`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${MOTHERDUCK_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ username: SERVICE_ACCOUNT_USERNAME }),
  }
);
const { session } = await response.json();
```

```python
# Python
import httpx

response = httpx.post(
    f"https://api.motherduck.com/v1/dives/{DIVE_ID}/embed-session",
    headers={
        "Authorization": f"Bearer {MOTHERDUCK_TOKEN}",
        "Content-Type": "application/json",
    },
    json={"username": SERVICE_ACCOUNT_USERNAME},
)
session = response.json()["session"]
```

The admin token generates a scoped session that runs as a [service account](https://motherduck.com/docs/key-tasks/service-accounts-guide/). Your token never leaves the backend.

**Step 2: Render the iframe (frontend)**

```html
<iframe
  src="https://embed-motherduck.com/sandbox/#session=SESSION_FROM_BACKEND"
  sandbox="allow-scripts allow-same-origin"
  width="100%" height="600" style="border:none;">
</iframe>
```

The session is passed as a URL fragment (`#session=...`), so browsers strip it from HTTP requests -- it won't appear in server logs or referrer headers. Sessions expire after 24 hours; generate a fresh one per page load or cache and refresh server-side.

End users do not need a MotherDuck account. For Content Security Policy, add `frame-src https://embed-motherduck.com;` to your headers.

See the [embedding docs](https://motherduck.com/docs/key-tasks/ai-and-motherduck/dives/embedding-dives/) for the full reference.

## SQL Functions and Dives as Code

While the Dive creation experience is designed with agents in mind, they're not mandatory. MotherDuck exposes [SQL functions](https://motherduck.com/docs/sql-reference/motherduck-sql-reference/ai-functions/dives/) for managing Dives without leaving your SQL client:

- `MD_CREATE_DIVE(title, content)` -- create a new Dive
- `MD_UPDATE_DIVE_CONTENT(id, content)` -- push a new version
- `MD_LIST_DIVES()` -- list all Dives in your workspace
- `MD_GET_DIVE(id)` -- retrieve full Dive source
- `MD_LIST_DIVE_VERSIONS(id)` -- view version history

This means you can manage Dives as code with standard git workflows. The [blessed-dives-example](https://github.com/motherduckdb/blessed-dives-example) starter repo includes a GitHub Actions CI/CD pipeline that:

- **On PR**: Detects modified Dive folders, deploys branch-tagged preview versions, and comments with direct MotherDuck links for reviewers
- **On merge**: Deploys production Dives matched by title
- **On branch delete**: Cleans up preview Dives automatically

Fork the repo to get started, or see the [managing Dives as code](https://motherduck.com/docs/key-tasks/ai-and-motherduck/dives/managing-dives-as-code/) guide for the full workflow.
