# Mosaic: linked data views that push queries down to DuckDB instead of the browser

> Mosaic is a TypeScript framework from the University of Washington where interface components publish declarative query needs and a coordinator cross-filters them against DuckDB, in the browser through WebAssembly or over the network. It is a monorepo of many packages, and its own README steers you away from one of them.

**uwdata/mosaic** — An extensible framework for linking databases and interactive views.

- Repository: https://github.com/uwdata/mosaic
- Website: https://idl.uw.edu/mosaic/
- Stars: 1,403 · Forks: 122
- Language: TypeScript
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/uwdata-mosaic

## Publish queries, let a coordinator cross-filter them

The architectural idea is stated once in the README and it is the whole design. The key idea is to have interface components publish their data needs as declarative queries that can be managed, optimized, and cross-filtered by a coordinator that proxies access to DuckDB.

That is a different shape from the usual dashboard library. In a conventional chart library, each chart fetches the data it needs and the developer wires up the linking between charts by hand. In Mosaic, a chart does not know what else is on the page. It states what it needs, the coordinator works out the combined query, and the result is cross-filtered against every other client automatically.

The claim that follows from that design is scale. The README says Mosaic is an extensible architecture for linking data visualizations, tables, input widgets and other data-driven components, leveraging a backing database for scalable processing of both static and interactive views, and that you can explore millions and even billions of data points at interactive rates. The computation is not in the browser drawing layer, it is in the database.

Two deployment paths follow from the same design. The coordinator can send queries over the network to a backing server through the rest client, or to a client-side DuckDB-WASM instance in the browser through the wasm client. The README describes the project as powered by DuckDB, pushing computation to DuckDB both server-side and in the browser via WebAssembly.

This is research software with a paper behind it. The README links a Mosaic research paper and asks that citations use a specific bibtex entry, a 2024 IEEE Transactions on Visualization and Computer Graphics article by Jeffrey Heer and Dominik Moritz.

## The monorepo layout and what each package does

This repository is a pnpm workspace, with lerna.json, pnpm-workspace.yaml and a private root package.json, and it contains a set of related packages spanning the core architecture, DuckDB servers, the vgplot visualization library and example projects.

The core sits in packages/mosaic. mosaic-core holds the central coordinator, parameters and selections for linking scalar values or query predicates respectively across Mosaic clients, and filter groups with materialized views of pre-aggregated data. mosaic-sql is an API for convenient construction and analysis of SQL queries, where query objects coerce to SQL query strings.

The visualization layer is packages/vgplot. The vgplot package itself is a visualization grammar API that demonstrates the features and performance of the Mosaic architecture, and for convenience it re-exports much of mosaic-core, mosaic-sql, mosaic-plot and mosaic-inputs, so for most applications importing @uwdata/vgplot alone is enough.

Underneath sit three more pieces. mosaic-inputs holds standalone data-driven components such as input menus, text search boxes, and sortable, load-on-scroll data tables. mosaic-plot is an interactive grammar of graphics implemented on top of Observable Plot, where marks serve as individual Mosaic clients and can push data processing such as binning, hex binning and regression, plus optimizations such as M4 for line and area charts, down to the database. mosaic-spec is a declarative specification of applications as JSON or YAML files, with a parser and code generation framework that reads a specification and generates live visualizations using the vgplot API. The widget package is a Jupyter widget that turns a declarative specification into web based visualizations while leveraging DuckDB in the Jupyter kernel, over Pandas, Polars data frames or DuckDB connections.

Examples live in packages/examples, with a vanilla-example showing how to deploy Mosaic in a website and a svelte-example showing Mosaic components inside a web framework.

## Four DuckDB servers, and the one the README steers you away from

The server packages are where the project is most honest about its own trade-offs, and one entry carries a clear warning.

duckdb-server is the Python based server that runs a local DuckDB instance and supports queries over HTTP, returning data in either Apache Arrow or JSON format. duckdb-server-rust is a Rust based server with additional support for HTTP/2, and the README says the team is still evaluating what server component works best, and that DuckDB support for Rust is often delayed compared to Python. duckdb-server-go is a Go based server, also with HTTP/2 support, which has experimental support for multi-tenant access control, function allowlisting and blocklisting, and other features to harden the server for production use.

Then there is mosaic-duckdb, a Promise based Node.js API to DuckDB with a data server that transfers Apache Arrow and JSON data over HTTP. The README says that due to quality and maintenance issues involving the Node.js DuckDB client and Arrow extension, the Python based duckdb-server package is recommended instead, and that the Node package is retained for both backwards compatibility and internal testing use.

So the Go server is the experimental one, the Rust server is the one lagging on DuckDB features, and the Node package is effectively deprecated in favour of Python. If you are deciding today, the Python server is the documented recommendation, and the Go server is the interesting one if you need access control in front of DuckDB.

The root package.json gives you the dev entry points for each, so you can run the server you intend to deploy without building the whole workspace.

## Building the workspace, running tests and the docs site

The build and check scripts live in the root package.json, and they show the shape of the toolchain. The package manager is pinned through the packageManager field, and the preinstall script runs npx only-allow pnpm, so a pip-install-style mistake fails fast rather than silently creating a second lockfile.

```json
"build": "tsc --build && lerna run build",
"test": "lerna run schema && pnpm run typecheck && vitest run && pnpm -F mosaic-widget test",
"lint": "lerna run lint",
"typecheck": "tsc --build && lerna run typecheck"
```

The test script is worth reading closely. It regenerates the schema first, then typechecks, then runs vitest, then runs the mosaic-widget test suite. Schema generation sitting at the front of the chain means a spec change that was not regenerated fails the test run rather than producing a stale artefact.

The docs are VitePress based, with docs:dev, docs:build and docs:preview scripts, and a separate docs:examples script that prepares the examples and then runs ruff format. That last detail tells you the documentation examples are partly Python and are formatted with ruff before publishing.

The Python side of the monorepo is managed by uv. The pyproject.toml declares a uv workspace with members covering the duckdb-server package, the widget package and the vgplot-python package, and the ruff configuration is strict, enabling preview rules with pydocstyle numpy conventions, required future annotations imports, and rule sets covering future annotations, type checking, pyupgrade, annotations, pep8 naming, error messages and bandit checks.

There is also a bin directory with helper scripts, including one for publishing the schema and one for generating the Python API from the schema, which is how the declarative spec reaches Python users.

## Where Mosaic is the wrong tool

Mosaic has opinions, and the cases where it is the wrong choice are specific.

First, the visual design system is not the point. mosaic-plot is a grammar of graphics on top of Observable Plot, and vgplot is a demo of the architecture's features and performance. If you need a bespoke chart type that does not map onto a mark, you are extending the grammar yourself, and the README does not describe a rich authoring API for that.

Second, the architecture assumes a backing database. There is no story here for a small static dataset, and the whole premise of pushing computation down to DuckDB does not pay for itself when the data would fit in memory anyway.

Third, there is real weight in the browser. The wasm client means the user downloads DuckDB compiled to WebAssembly, and that is a cost in page weight and startup time that a simple API-backed chart does not pay.

Fourth, the version cadence is brisk and the version numbers say so. The recent releases are v0.33.0 on 2026-10-13, v0.32.1 on 2026-10-09 and v0.32.0 on 2026-09-28, so this is pre-1.0 software shipping roughly weekly, and the last push was on 2026-10-18. The API surface of a pre-1.0 project can move between minor versions, so pinning matters more than it would for a stable library.

On licensing, the licence field is recorded as a custom licence GitHub cannot classify, while the root package.json declares BSD-3-Clause. The LICENSE file at the root is the authoritative text, and the discrepancy between the two declarations is worth resolving before you embed this in a product, since it is the kind of thing that determines whether you can ship it under your own terms.

## Conclusion

Adopt Mosaic if you are building an interactive exploration of a large dataset where cross-filtering between charts and tables matters more than the chart styling, since the coordinator model is the hard part and the visual grammar sits on top of Observable Plot. Do not adopt it for a static dashboard, a small dataset, or a team that does not want a DuckDB dependency in the browser bundle. Verify first which server package fits your stack, because the README states that the Node.js mosaic-duckdb package is retained only for backwards compatibility and internal testing and recommends the Python duckdb-server instead.

## FAQ

### What is the Mosaic framework from uwdata?

Mosaic is an extensible architecture for linking data visualizations, tables, input widgets and other data-driven components. Interface components publish declarative queries that a coordinator manages, optimizes and cross-filters while proxying access to DuckDB.

### Which DuckDB server package should I use with Mosaic?

The README recommends the Python based duckdb-server package, and says mosaic-duckdb, the Node.js package, is retained only for backwards compatibility and internal testing because of quality and maintenance issues with the Node DuckDB client and Arrow extension. The Go server is the one with experimental production hardening features.

### Can Mosaic run entirely in the browser?

Yes. The Mosaic coordinator can send queries either over the network to a backing server through the rest client, or to a client-side DuckDB-WASM instance through the wasm client.

### How do I declare a Mosaic application instead of writing code?

The mosaic-spec package provides declarative specification of Mosaic applications as JSON or YAML files, with a parser and code generation framework that reads a specification and generates live visualizations using the vgplot API. The widget package does the same inside a Jupyter kernel.

## Sources

- [Issues](https://github.com/uwdata/mosaic/issues)
- [Project website](https://idl.uw.edu/mosaic/)
- [README](https://github.com/uwdata/mosaic/blob/main/README.md)
- [Releases](https://github.com/uwdata/mosaic/releases)
- [uwdata/mosaic on GitHub](https://github.com/uwdata/mosaic)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/uwdata-mosaic
