Skip to content

Getting started

How to run dbt-bouncer#

  1. Generate dbt artifacts by running a dbt command:

    • dbt parse to generate a manifest.json artifact (no database connection required!).
    • dbt compile --write-catalog to generate a catalog.json artifact (necessary if you are using catalog checks). On dbt 1.x, use dbt docs generate — the --write-catalog flag does not exist there.
    • dbt run (or any other command that implies it e.g. dbt build) to generate a run_results.json artifact (necessary if you are using run results checks).

dbt compile executes nothing, so it writes a run_results.json with zero results. Generate the catalog before, or into a different --target-path than, the command that produces your run_results.json.

  1. Create a config file (dbt-bouncer.yml, dbt-bouncer.toml, or a [tool.dbt-bouncer] section in pyproject.toml), details here. Alternatively, you can run dbt-bouncer init to generate a basic configuration file.

  2. Run dbt-bouncer to validate that your conventions are being maintained.


Installing with Python#

Install from pypi.org:

pip install dbt-bouncer # or via any other package manager

Run:

dbt-bouncer --config-file <PATH_TO_CONFIG_FILE>
Running dbt-bouncer (X.X.X)...
Loaded config from <PATH_TO_CONFIG_FILE>...
Validating conf...

dbt-bouncer also supports a verbose mode, run:

dbt-bouncer --config-file <PATH_TO_CONFIG_FILE> -v
INFO: Running dbt-bouncer (0.0.0)...
DEBUG: config_file=PosixPath('<PATH_TO_CONFIG_FILE>')
DEBUG: config_file_source='COMMANDLINE'
DEBUG: Config file passed via command line: <PATH_TO_CONFIG_FILE>
DEBUG: Loading config from <PATH_TO_CONFIG_FILE>...
INFO: Loaded config from <PATH_TO_CONFIG_FILE>...

When parsing artifacts, dbt-bouncer displays a summary table of discovered resources:

            Parsed artifacts for
            'dbt_bouncer_test_project'
╭──────────────────┬─────────────────┬───────╮
│ Artifact         │ Category        │ Count │
├──────────────────┼─────────────────┼───────┤
│ manifest.json    │ Exposures       │     2 │
│                  │ Macros          │     3 │
│                  │ Nodes           │    12 │
│                  │ Seeds           │     3 │
│                  │ Semantic Models │     1 │
│                  │ Snapshots       │     2 │
│                  │ Sources         │     4 │
│                  │ Tests           │    36 │
│                  │ Unit Tests      │     3 │
│ catalog.json     │ Nodes           │    13 │
│                  │ Sources         │     0 │
│ run_results.json │ Results         │    51 │
╰──────────────────┴─────────────────┴───────╯

Trade-offs

Best for: manual runs, quick one-off validation, local development, scripting.

Watch out: manual — easy to forget before committing or opening a PR.


Running as an executable using uv#

Run dbt-bouncer as a standalone Python executable using uv:

uvx dbt-bouncer --config-file <PATH_TO_CONFIG_FILE>

Trade-offs

Best for: environments or machines without a persistent Python install.

Watch out: slightly slower than a local install due to ephemeral environment creation.


Pre-commit hooks / prek#

dbt-bouncer ships an official pre-commit hook that runs automatically before each commit. Add it to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/godatadriven/dbt-bouncer
    rev: vX.X.X # Check https://github.com/godatadriven/dbt-bouncer/releases for the latest version
    hooks:
      - id: dbt-bouncer
        args: ["--config-file", "<PATH_TO_CONFIG_FILE>"] # Optional

Alternatively, use a local hook (requires dbt-bouncer to be available in your environment):

- repo: local
  hooks:
    - id: dbt-bouncer
      name: dbt-bouncer
      entry: dbt-bouncer # --config-file <PATH_TO_CONFIG_FILE>
      language: system
      pass_filenames: false
      always_run: true

For full setup details see the FAQ.

Trade-offs

Best for: catching violations immediately during development, before code is pushed to remote.

Watch out: dbt artifacts must already exist — you need to run dbt parse (or another dbt command), possibly in the prior hook, before this hook can execute. This adds latency to every commit. The hook can also be bypassed with git commit --no-verify.


GitHub Actions#

Run dbt-bouncer as part of your CI pipeline:

name: CI pipeline

on:
  pull_request:
      branches:
          - main

jobs:
    run-dbt-bouncer:
        permissions:
            pull-requests: write # Required to write a comment on the PR
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v6

            - name: Generate or fetch dbt artifacts
              run: ...

            - uses: godatadriven/dbt-bouncer@vX.X
              with:
                baseline: '' # optional, path to a baseline file, so only new failures fail the run
                check: '' # optional, comma-separated check names to run
                config-file: ./<PATH_TO_CONFIG_FILE>
                dry-run: false # optional, defaults to false
                only: manifest_checks # optional, defaults to running all checks
                output-file: results.json # optional, default does not save a results file
                output-format: json # optional, one of: csv, json, junit, sarif, tap. Defaults to json
                output-only-failures: false # optional, defaults to false
                preset: '' # optional, one of: minimal, standard, strict. Replaces config-file
                send-pr-comment: true # optional, defaults to true
                show-all-failures: false # optional, defaults to false
                state: '' # optional, directory of base artifacts, so only new failures fail the run
                verbose: false # optional, defaults to false

Set either config-file or preset, not both. When preset is set, the action runs a bundled preset and does not pass config-file.

The baseline and state paths are resolved relative to the repository root.

A config file resolves artifact paths relative to its own directory. A preset has no file, so it resolves them relative to the repository root and expects target/ there. If your dbt project is not at the repository root, set DBT_PROJECT_DIR and the action passes it through:

            - uses: godatadriven/dbt-bouncer@vX.X
              env:
                DBT_PROJECT_DIR: dbt_project
              with:
                preset: strict

We recommend pinning both a major and minor version number.

Trade-offs

Best for: enforcing conventions on every PR regardless of local developer setup — cannot be bypassed by individual contributors. Supports automated PR comments with violation details.

Watch out: slower feedback loop than local hooks; consumes CI minutes for every push.


Docker#

Run dbt-bouncer via Docker:

docker run --rm \
    --volume "$PWD":/app \
    ghcr.io/godatadriven/dbt-bouncer:vX.X.X \
    --config-file /app/<PATH_TO_CONFIG_FILE>

Trade-offs

Best for: fully isolated, reproducible runs; no Python installation required on the host.

Watch out: requires Docker; slightly heavier startup than a native install.


Programmatic invocation#

dbt-bouncer can be invoked programmatically. run_bouncer returns the exit code of the process.

from pathlib import Path
from dbt_bouncer import run_bouncer

exit_code = run_bouncer(
    config_file=Path("path/to/dbt-bouncer.yml"),
    check="",  # optional, comma-separated check names to run
    dry_run=False,  # optional, print which checks would run without executing
    only="",  # optional, comma-separated categories e.g. "manifest_checks"
    output_file=Path("results.json"),  # optional
    output_format="json",  # optional, one of: "csv", "json", "junit", "sarif", "tap"
    output_only_failures=False,  # optional, only include failures in output
    show_all_failures=False,  # optional, print all failures to console
    verbosity=0,  # optional, increase for more detailed output
)  # additional internal parameters omitted

Trade-offs

Best for: embedding dbt-bouncer into existing Python tooling, test suites, or custom orchestration.

Watch out: requires Python knowledge; not suitable for teams without Python experience.

Skills#

You can install dbt-bouncer AI skills like so:

Vercel Skills CLI#

npx skills add godatadriven/dbt-bouncer
# or just this skill:
npx skills add godatadriven/dbt-bouncer --skill suggesting-dbt-bouncer-checks

Claude Code plugin marketplace#

/plugin marketplace add godatadriven/dbt-bouncer
/plugin install dbt-bouncer@dbt-bouncer-marketplace