# Querybook: a big data IDE where the query and the writeup live together

> Pinterest's open source SQL workbench pairs a CodeMirror query editor with notebook-style DataDocs, runs as three containers against MySQL, Redis and Elasticsearch, and has needed two security releases in a row.

**pinterest/querybook** — Querybook is a Big Data Querying UI, combining collocated table metadata and a simple notebook interface.

- Repository: https://github.com/pinterest/querybook
- Website: https://www.querybook.org
- Stars: 2,292 · Forks: 301
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/pinterest-querybook

## What Querybook is actually for

The repository description calls it a Big Data Querying UI that combines collocated table metadata with a simple notebook interface, and the readme puts it more plainly as a Big Data IDE for discovering, creating and sharing data analyses, queries and tables. The homepage is querybook.org and the owning organization is Pinterest, so this is infrastructure that came out of an internal analytics platform rather than a community project that happened to find a corporate home.

The unit of work is called an analysis, rendered in the UI as a DataDoc, and it is a rich text document with queries and charts interleaved. That is the whole idea in one sentence: instead of a query in one tool, a chart in a second tool and the explanation in a wiki page, all three sit in one document that is versioned in the same place and searchable by the people who need it.

Around that core the readme lists six capabilities. Queries get autocompletion and hover tooltips. DataDocs can be scheduled and charted to build dashboards. Multiple people can edit a query together live. Tables carry their own documentation. And the system derives lineage, sample queries and most-frequent-user signals from past query runs, then uses those to rank search results.

That last group is the part that separates Querybook from a SQL client. A text editor with autocomplete does not know that the person searching for churn by cohort is the person who wrote nine of the relevant queries last month, and it cannot tell you where a column came from. Querybook treats execution history as a first-class signal for discovery.

## The local setup is one command and one port

The getting started section is remarkably short, and that is a deliberate design choice about what a developer is supposed to have to know.

```
Please install Docker before trying out Querybook.
```

```
Pull this repo and run `make`. Visit http://localhost:10001 when the build completes.
```

There is no prerequisite list beyond Docker, no database to provision by hand, no Node version to install first. The Makefile builds an image and the compose file brings up the topology. The port is 10001, which matches the port mapping in the compose file.

For everything past that point the readme delegates. Infrastructure configuration points at a document in the docs_website directory, general configuration points at another one, and the detailed installation instructions live at a setup guide path in the same directory. The docs are in the repository rather than on a separate site, which is friendlier than the usual pattern, but they are also not in the readme, so a reader who only ever reads the readme stops at the browser window.

The compose file uses the long-form syntax with health conditions rather than the short depends_on list, which tells you the authors cared about startup ordering. The web service waits for MySQL, Redis and Elasticsearch to report healthy before it starts.

## Three services, and why each one is there

The compose file defines a web container, a worker container and a scheduler container, all from the same image. That is three roles from one artifact, and the split tells you the execution model.

```yaml
    web:
        container_name: querybook_web
        image: *querybook-image
        tty: true
        stdin_open: true
        command: './querybook/scripts/bundled_docker_run_web --initdb --initweb'
        ports:
            - '${PORT:-10001}:${PORT:-10001}'
```

The web entry point takes two flags, --initdb and --initweb, so the first run initializes the database schema and seeds the web assets in the same container that serves traffic. The worker runs a queue consumer with an explicit concurrency of 5.

```yaml
    worker:
        container_name: querybook_worker
        image: *querybook-image
        tty: true
        stdin_open: true
        command: './querybook/scripts/runservice worker -c 5'
```

A third service, the scheduler, is defined in the same file for the scheduled queries that the readme mentions as a DataDoc feature. Concurrency of 5 on the worker is a hardcoded default rather than an environment variable, which is worth knowing before you point it at an expensive cluster and wonder why only five queries run at once.

One detail in the volumes block is a good example of the kind of thing that costs an afternoon. The repository root is bind-mounted to /opt/querybook for live code reload, and three paths inside it are then masked with empty volumes.

```yaml
x-querybook-volumes: &querybook-volumes
    # This is to sync in live code change
    - $PWD:/opt/querybook
    - $PWD/docs_website/static/changelog:/opt/querybook/querybook/static/changelog
```

node_modules, dist and the bundled config file are all overridden separately, with comments explaining that the build files must not leak back to the host. A single masking volume would have shadowed the parent, so each exclusion needs its own entry. That is correct and it is also exactly the kind of detail you only discover by reading the compose file.

## The connectors that decide whether it fits your stack

Querybook's value is mostly determined by what it can talk to, so the integration list deserves to be read closely rather than skimmed.

Query engines named explicitly are Presto, Hive, Druid, Snowflake, BigQuery, MySQL, SQLite and PostgreSQL, with a link to a page listing all of them, which implies the adapter set is wider than the readme names. Metastores come from Hive Metastore, SQLAlchemy inspect, or AWS Glue Data Catalog, and this is the piece that makes column-level autocomplete possible in the first place, since the editor needs a schema to complete against.

Result storage is a separate decision from the engine, and four options are listed: a relational database, S3, Google Cloud Storage, or a local file. That separation is what makes it viable to run a fast Presto query and have the multi-gigabyte result land in object storage while the UI still charts it.

Authentication is four mechanisms, user and password, OAuth with four named providers covering Google Cloud, Okta, GitHub and Auth0, and LDAP. Notifications go to email or Slack. Export paths are Google Sheets and Python.

One naming inconsistency is worth knowing about as you read the rest of the system. The readme calls the unit of work an analysis in the feature list and a DataDoc everywhere else, including in the configuration docs and in the release notes. Both names refer to the same object.

## The 3.42.1 manifest and the 3.41.4 release

The package manifest on master reads version 3.42.1, with private set to true because the package is never published to a registry, and the repository field pointing at git+ssh://git@github.com:pinterest/querybook.git. The Node engine constraint is >=18.0.0.

The releases, meanwhile, top out at v3.41.4 published 2025-04-22. Before that, v3.32.0 from 2024-03-13 and v3.31.2 from 2024-02-28. So the two facts do not disagree, they measure different things. The tags mark what was published as a named release, and the manifest has moved roughly two dozen patch versions past the last tag on the development branch.

The practical consequence is about which artifact you deploy. If you build from master you are running code the maintainers never froze, which for an internal tool with a fast-moving dependency tree is a real risk. Pin the tag. If you build from a tag you are running code whose manifest may claim a lower version than the tag string, because the tag is applied at release time rather than being read from the file, so do not use the manifest version to verify which tag you actually got.

The frontend scripts in the same manifest are a reasonable summary of how development works here.

```json
    "scripts": {
        "test": "jest",
        "build": "npx webpack",
        "dev": "webpack serve --mode=development --open --hot",
        "lint": "eslint 'querybook/webapp/*/**/*.{ts,tsx}' --quiet --fix",
        "tsc-check": "tsc --noEmit"
    },
```

Webpack rather than Vite, Jest rather than Vitest, an ESLint invocation scoped to the webapp tree with --fix already in the script, and a separate type check pass. The Storybook script serves the querybook/static directory on port 6006, which is how the component library is developed in isolation.

There is also an AGENTS.md and a CLAUDE.md at the repository root. For a project that predates both conventions, their presence says the maintainers expect coding agents in the loop, which is a reasonable signal about where ongoing work is happening.

## Two security releases in consecutive versions

The most informative entries in the release history are the two that are not about features, and both concern the same class of bug.

v3.31.2 from 2024-02-28 states that a stored XSS vulnerability was observed and patched. The list that accompanies it is otherwise ordinary maintenance: support for serialized JSON environment variables, a fix to the DataDoc cell move down button, a Snyk-driven upgrade of jinja2 from 3.1.2 to 3.1.3, and a fix to schema filtering in the table search modal.

v3.32.0 from 2024-03-13, thirteen days later, calls itself a BREAKING change and explains why: it enforces an allowed list of CORS origins for websockets to address a cross-site websocket hijacking vulnerability. Its own change list mentions enabling websocket CORS for production, which reads like the enabling step for the enforcement rather than a separate feature.

Read together, those two releases tell you what to check first in your own deployment. The application is a notebook that renders stored user content, so stored XSS is the natural failure mode for anything with rich text cells. And the live collaboration feature listed in the readme is websocket-based, which is exactly the surface the CORS allowlist protects. If you are running an older build, upgrading past v3.32.0 is not optional hardening, and if you are behind the websocket origin allowlist you will need to populate it or collaboration features will fail rather than silently degrade.

The v3.32.0 change list also shows that metastore ACL support covers wildcard prefix matching, which is a small thing that matters if your Hive or Glue permissions are granted by prefix rather than by exact table name.

## Reading the newer feature work

The v3.41.4 notes are the most recent description of where the product is going, and they read like a pivot toward AI assistance and review workflow.

The headline features are Python cells in DataDocs powered by Pyodide running in the browser, group sharing for DataDocs and lists, a query review flow for requesting and managing review before execution, natural language search over past queries, and SQL completion described as similar to a Copilot. There is also GitHub integration for linking DataDocs to repositories for version control.

The Pyodide detail is the most architecturally interesting one and the one with the clearest limit. Because it runs in the browser, each DataDoc has its own isolated Python namespace rather than a shared server-side interpreter, which removes a whole category of cross-user leakage and means no Python process to operate. It also means no access to your network or your cluster from inside a cell, and that the Python version and available packages are whatever Pyodide ships rather than what you pip install on the server.

Query review is a governance feature, and it is worth reading as the answer to a question every team hits: who is allowed to run a query that costs two thousand dollars. Review before execution, requested and tracked inside the tool, is the mechanism. If your organization needs that, its presence in the notes is a reason to look at this version rather than an older one.

The GitHub integration points at a broader shift. Linking a DataDoc to a repository for version control suggests the authors are addressing the audit question, since a query document that changes without history is hard to review. Combined with the review flow, the direction is a tool that treats analysis as a reviewed artifact rather than a scratchpad.

## Signals about the project's pace

The adoption numbers are substantial: 2292 stars and 301 forks, Apache-2.0 licensed, written in TypeScript with the Python and Flask layer behind it, and a homepage plus a Slack community invite in the readme.

The open issue count is 237, which is high in absolute terms and needs context. A fork count of 301 against 237 open issues suggests deployment intent rather than casual interest, since forking is what you do before you run something internally, and a large self-hosted base generates a steady stream of environment-specific reports. Do not read it as 237 unresolved design flaws.

The most recent push to master is 2026-09-16, and the topic list includes celery, which explains the worker service in the compose file, along with hive, presto, notebook, metastore and charting. So the stack is Flask and Celery on the back, a TypeScript and webpack front end, with Elasticsearch for search, and MySQL or Postgres for state. That is a conventional and well-understood combination, which is part of why running it yourself is a realistic option rather than an adventure.

The repository tree also carries helm, k8s and containers directories alongside the compose file, so there is a Kubernetes path in addition to the local one. If you already run clusters, use the helm chart rather than the compose file, and remember that the compose file is explicitly a development setup with hot reload enabled and the repository bind-mounted.

## Conclusion

Querybook earns a place when your team runs more than one query engine and your analyses are currently scattered across notebooks, docs and dashboards that cannot talk to each other. The value is the pairing: a saved query, its chart and its prose live in one DataDoc that other people can search and rerun. Two things decide it for you. The documentation lives on a separate website rather than in the readme, so budget an hour of reading the setup guide before your first deployment. And the last tagged release is v3.41.4 from April 2025 while the package manifest reads 3.42.1, which means you are deploying unreleased work if you build from master, so pin the tag for production and treat the manifest version as a development counter.

## FAQ

### What is Querybook and what is it used for?

Querybook is a big data IDE developed at Pinterest for discovering, creating and sharing data analyses, queries and tables. It pairs a SQL query editor with autocompletion and hover tooltips with notebook-style documents called DataDocs, which mix rich text, queries and charts in one place. It connects to engines including Presto, Hive, Druid, Snowflake, BigQuery, MySQL, SQLite and PostgreSQL, reads schema from a metastore such as Hive Metastore, AWS Glue or SQLAlchemy inspect, and derives lineage, sample queries and search ranking from past query runs.

### How do you install Querybook for local development?

Install Docker, clone the repository, and run make. The readme states that you can then visit localhost:10001 once the build completes. The compose file defines three containers from one image, a web service that initializes the database and web assets on first run, a worker consuming a queue with a fixed concurrency of 5, and a scheduler for scheduled queries, all gated on MySQL, Redis and Elasticsearch reporting healthy. Detailed configuration lives in the docs_website directory of the repository rather than in the readme.

### Which Querybook versions fix security problems, and do I need both?

You need a build at or past v3.32.0 to have both. v3.31.2 from February 2024 patched a stored XSS vulnerability, and v3.32.0 from March 2024 was a breaking change that enforced an allowed list of CORS origins for websockets to close a cross-site websocket hijacking hole. Since v3.32.0 is the later of the two, upgrading to it or beyond covers both. Plan for the break, because the origin allowlist has to be populated for websocket features such as live query collaboration to keep working.

## Sources

- [License: Apache-2.0](https://github.com/pinterest/querybook/blob/master/LICENSE)
- [pinterest/querybook on GitHub](https://github.com/pinterest/querybook)
- [Project website](https://www.querybook.org)
- [README](https://github.com/pinterest/querybook/blob/master/README.md)
- [Releases](https://github.com/pinterest/querybook/releases)

---

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