Skip to main content
Metabase is organized into clear frontend and backend sections, with additional directories for testing, configuration, and drivers. Understanding the structure will help you navigate and contribute to the codebase effectively.

Repository overview

metabase/
├── frontend/           # Frontend application (TypeScript/React)
├── src/               # Backend source code (Clojure)
├── test/              # Backend tests (Clojure)
├── modules/           # Database drivers and extensions
├── e2e/               # End-to-end tests (Cypress)
├── docs/              # Developer documentation
├── resources/         # Static resources and config
├── bin/               # Build and utility scripts
└── enterprise/        # Enterprise features

Frontend structure

The frontend is located in /frontend and uses TypeScript, React, Redux, and Mantine UI.

Frontend organization

frontend/
├── src/
│   ├── metabase/
│   │   ├── api/              # RTK Query API definitions
│   │   ├── components/       # Shared components
│   │   ├── ui/              # Mantine-based UI library
│   │   ├── query_builder/   # Query builder feature
│   │   ├── dashboard/       # Dashboard feature
│   │   ├── home/            # Home page
│   │   ├── admin/           # Admin settings
│   │   └── ...
│   └── metabase-types/      # TypeScript type definitions
├── test/                    # Frontend tests
└── __support__/             # Test utilities and mocks

Key frontend directories

The main application code, organized by feature:
  • api/ - All API endpoints using RTK Query
  • query_builder/ - Visual query builder logic
  • dashboard/ - Dashboard creation and viewing
  • ui/ - Reusable UI components built on Mantine
  • components/ - Shared components across features
  • lib/ - Utility functions and helpers
TypeScript type definitions:
  • api/ - Types matching backend API responses
  • store/ - Redux store shape types
  • types/ - General application types

Frontend tech stack

  • TypeScript - Primary language (migrating from JavaScript)
  • React 18 - UI framework
  • Redux Toolkit - State management
  • RTK Query - Data fetching and caching
  • Mantine - UI component library
  • Emotion - CSS-in-JS (legacy, being phased out)
  • Jest - Unit testing
  • Cypress - End-to-end testing

Backend structure

The backend is located in /src and written in Clojure.

Backend organization

src/
├── metabase/
│   ├── api/              # REST API endpoints
│   ├── models/           # Database models
│   ├── driver/           # Core driver interface
│   ├── driver.sql/       # SQL driver abstractions
│   ├── driver.sql-jdbc/  # JDBC driver abstractions
│   ├── query_processor/  # MBQL query processing
│   ├── sync/            # Database sync and metadata
│   ├── db/              # Application database access
│   ├── mbql/            # MBQL query language
│   ├── util/            # Utility functions
│   └── ...

Key backend directories

REST API endpoint definitions. Each file defines routes for a specific resource:
  • database.clj - Database connection endpoints
  • card.clj - Question/card endpoints
  • dashboard.clj - Dashboard endpoints
  • table.clj - Table metadata endpoints
Toucan2 models for the application database:
  • database.clj - Database connections
  • card.clj - Saved questions
  • dashboard.clj - Dashboards
  • user.clj - User accounts
Core driver interface and implementations. Drivers provide:
  • Database capabilities and features
  • Schema introspection (sync)
  • MBQL to native query compilation
  • Query execution
MBQL query processing pipeline:
  • Query preprocessing and middleware
  • Permission checking
  • Query optimization
  • Result post-processing

Backend tech stack

  • Clojure 1.12 - Primary language
  • Ring - HTTP server abstraction
  • Compojure - Routing
  • Toucan2 - ORM for application database
  • Honey SQL - SQL query generation
  • clojure.test - Testing framework

Database drivers

Drivers are organized as separate modules in /modules/drivers/:
modules/drivers/
├── postgres/
│   ├── deps.edn
│   ├── resources/
│   │   └── metabase-plugin.yaml
│   ├── src/metabase/driver/postgres.clj
│   └── test/
├── mysql/
├── mongodb/
├── bigquery/
└── ...

Driver components

1

deps.edn

Defines driver dependencies (JDBC drivers, client libraries, etc.)
2

metabase-plugin.yaml

Plugin manifest with driver metadata, connection properties, and initialization steps
3

src/metabase/driver/<name>.clj

Driver implementation with multimethod implementations for driver interface
4

test/

Driver-specific tests and test data definitions
Learn more about building drivers.

Testing structure

Backend tests

Located in /test/metabase/, mirroring the source structure:
test/
├── metabase/
│   ├── api/              # API endpoint tests
│   ├── models/           # Model tests
│   ├── query_processor/  # Query processor tests
│   ├── driver/           # Driver interface tests
│   └── test/
│       └── data/         # Test data and fixtures

Frontend tests

New unit tests are placed alongside the components they test. Legacy tests are in /frontend/test/.
frontend/
├── test/                 # Legacy test location
│   ├── __support__/      # Test utilities
│   └── metabase/
└── src/metabase/
    └── components/
        ├── Button.tsx
        └── Button.unit.spec.tsx  # ✅ New pattern

End-to-end tests

Cypress tests in /e2e/:
e2e/
├── test/
│   ├── scenarios/
│   │   ├── question/     # Query builder tests
│   │   ├── dashboard/    # Dashboard tests
│   │   └── admin/        # Admin tests
│   └── support/          # Cypress helpers
└── runner/               # Test runner scripts

Build and configuration

Build scripts

Located in /bin/:
  • build.sh - Build complete Metabase JAR
  • build-drivers.sh - Build all database drivers
  • build-driver.sh - Build single driver
  • dev-install - Automated development setup

Configuration files

# Clojure dependencies and aliases
:deps {...}
:aliases {
  :dev {...}
  :test {...}
  :drivers {...}
}

Enterprise features

Enterprise Edition code is in /enterprise/:
enterprise/
├── backend/
│   └── src/metabase_enterprise/  # Enterprise backend features
└── frontend/
    └── src/metabase-enterprise/   # Enterprise frontend features

Resources and static files

resources/
├── frontend_client/    # Compiled frontend assets
├── migrations/        # Database migrations
├── modules/           # Clojure module configs
└── embedding-sdk/     # Embedding SDK resources

Documentation

  • /docs - Developer documentation (source files)
  • /.claude - AI coding assistant skills and conventions
  • README.md - Project overview and quick start

Naming conventions

Frontend

  • Components - PascalCase (e.g., QueryBuilder.tsx)
  • Hooks - camelCase with use prefix (e.g., useQuery.ts)
  • Utils - camelCase (e.g., formatDate.ts)
  • Constants - UPPER_SNAKE_CASE (e.g., MAX_RESULTS)

Backend

  • Namespaces - kebab-case (e.g., metabase.query-processor)
  • Functions - kebab-case (e.g., process-query)
  • Multimethods - kebab-case (e.g., mbql->native)

Working with the codebase

Finding code

Backend API endpoints are in /src/metabase/api/. Each resource has its own file.Frontend API definitions using RTK Query are in /frontend/src/metabase/api/.
Search in /frontend/src/metabase/ by feature name. Components are organized by the feature they belong to.
Driver implementations are in /modules/drivers/<driver-name>/ for built-in drivers, or /src/metabase/driver/ for core driver interfaces.

Next steps

Build docs developers (and LLMs) love