lightdash/lightdash

Self-serve BI to 10x your data team ⚡️

5,707 stars TypeScript 10 components

13 hidden assumptions · 6-stage pipeline · 10 components

Like any codebase, this fullstack makes assumptions it never checks — most are routine. The ones worth your attention are below.

Self-service BI platform that transforms dbt models into interactive dashboards and analytics

Data enters Lightdash through dbt model compilation (CLI deployment) or live queries (web interface). The system parses dbt YAML files to extract metric definitions, compiles custom formulas into warehouse-specific SQL, executes queries against configured data warehouses, and returns results as interactive charts or raw data. Authentication flows through passport strategies, while authorization uses CASL ability builders to control access to projects and resources.

Under the hood, the system uses 4 feedback loops, 4 data pools, 4 control points to manage its runtime behavior.

A 10-component fullstack. 3406 files analyzed. Data flows through 6 distinct pipeline stages.

Hidden Assumptions

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

If a server returns a malformed Set-Cookie header or cookie values with embedded semicolons/equals, the cookie parsing silently fails or stores corrupted values, breaking session management

Worth your attention first

All API tests fail with connection errors if the target service is down or the URL is wrong, with no retry logic or health checks

Worth your attention first

If session data is corrupted or the user is deleted between login and subsequent requests, authentication silently fails or returns undefined user context

Show everything (10 more)
Scale

The maximum_bytes_billed setting in dbt profiles is sufficient to prevent runaway BigQuery costs, with no runtime validation that query costs stay within this limit

If this fails: Users can accidentally trigger expensive BigQuery queries that exceed their intended budget if the dbt profile setting is misconfigured or missing

packages/cli/src/dbt/targets/Bigquery/index.ts:maximum_bytes_billed
Ordering

Project profiles array contains all current project memberships for the user in consistent order, with no duplicate projectUuid entries that could cause permission conflicts

If this fails: If projectProfiles has duplicates or stale data, the last processed role for each project wins, potentially granting wrong permissions or access to deleted projects

packages/common/src/authorization/index.ts:getUserAbilityBuilder
Domain

The CompileOptions.dialect field always maps to exactly one of the hardcoded warehouse types (postgres, bigquery, snowflake, duckdb), with no support for dialect versioning or custom warehouse types

If this fails: Adding new warehouse support or handling dialect variations requires code changes; unknown dialects throw runtime errors instead of falling back gracefully

packages/formula/src/codegen/index.ts:createGenerator
Environment

All required environment variables for each warehouse type (like FORMULA_TEST_BQ_PROJECT, FORMULA_TEST_SF_ACCOUNT) are set when those warehouses are included in test runs

If this fails: Tests fail with cryptic connection errors if warehouse-specific environment variables are missing, with no clear indication of which variables need to be set

packages/formula-tests/config.ts:getWarehouseConfig
Temporal

The React Query cache invalidation for 'projectCompileLogs' happens atomically and the fresh data will be immediately available for re-rendering

If this fails: If the cache invalidation fails or the backend is slow to respond, users see stale compilation data even after clicking refresh, with success toast shown prematurely

packages/frontend/src/components/CompilationHistory/index.tsx:handleRefresh
Contract

The mapCronExpressionToFrequency function can always parse any cron expression string passed as the 'value' prop, even malformed or custom expressions

If this fails: Invalid cron expressions cause the frequency selector to show incorrect state or crash the component, breaking the scheduling UI

packages/frontend/src/components/CronInput/index.tsx:useEffect
Resource

The fetch() call will complete within reasonable time limits and network errors are properly handled by the underlying fetch implementation

If this fails: Long-running queries or network issues cause tests to hang indefinitely since there's no explicit timeout configuration

packages/api-tests/helpers/api-client.ts:request
Shape

All Lightdash API responses follow the exact shape { status: string, results: T } but only enforces this through TypeScript typing, not runtime validation

If this fails: If the backend returns differently structured responses, TypeScript compilation succeeds but runtime access to response.body.results fails with undefined errors

packages/api-tests/helpers/api-client.ts:Body<T>
Domain

The tier system (fast/tier1/tier2/all) represents increasing complexity and execution time, with DuckDB always being fastest and BigQuery/Snowflake being slowest

If this fails: If warehouse performance characteristics change or new warehouses are added with different performance profiles, the tier classifications become misleading

packages/formula-tests/config.ts:TIER_WAREHOUSES
Contract

The customRoleScopes record contains scopes for every roleUuid referenced in projectProfiles when customRolesEnabled is true, with no missing or orphaned role definitions

If this fails: Missing custom role definitions log console errors and skip permission grants, potentially leaving users with no project access despite having role assignments

packages/common/src/authorization/index.ts:customRoleScopes

Open the standalone hidden-assumptions report for lightdash →

How Data Flows Through the System

Data enters Lightdash through dbt model compilation (CLI deployment) or live queries (web interface). The system parses dbt YAML files to extract metric definitions, compiles custom formulas into warehouse-specific SQL, executes queries against configured data warehouses, and returns results as interactive charts or raw data. Authentication flows through passport strategies, while authorization uses CASL ability builders to control access to projects and resources.

  1. dbt Model Ingestion — CLI reads dbt project files (models/*.sql, schema.yml) and sends them to the backend's compilation service, which parses YAML metadata to extract dimension and metric definitions [dbt project files → Parsed model definitions]
  2. Formula Compilation — Formula parser converts metric expressions into ASTs, then warehouse-specific SQL generators (PostgresSqlGenerator, BigQuerySqlGenerator) produce executable SQL tailored to the target warehouse dialect [Formula strings → Warehouse SQL]
  3. User Authentication — Passport strategies validate login credentials (password, Google OAuth, SAML), create user sessions in PostgreSQL, and construct LightdashUser objects with role information [Login credentials → LightdashUser]
  4. Authorization Check — getUserAbilityBuilder combines the user's organization role with project-specific permissions to create CASL ability objects that control access to charts, dashboards, and data sources [LightdashUser → MemberAbility]
  5. Query Execution — Backend receives query requests via REST API, validates permissions, executes compiled SQL against warehouse adapters (BigQuery, Snowflake, Postgres), and returns structured results [QueryDefinition → QueryResult]
  6. Chart Rendering — Frontend consumes QueryResult data and renders it into interactive charts using visualization libraries, with state management handled by React Query for caching and updates [QueryResult → Chart components]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

ApiResponse packages/api-tests/helpers/api-client.ts
generic wrapper with ok: boolean, status: number, body: T — standardizes all API communication
Created by ApiClient.request(), consumed by all frontend API calls and CLI commands
LightdashUser packages/common/src/types/user.ts
user profile with role: string, organizationUuid: string, userUuid: string, plus authentication state
Populated during login, attached to requests via passport middleware, used for permission checks
TestCase packages/formula-tests/types.ts
test definition with id: string, formula: string, columns: Record<string, string>, expectedRows: Record<string, any>[], warehouses: WarehouseType[]
Loaded from test files, executed against multiple warehouses, results compared for validation
BigqueryTarget packages/cli/src/dbt/targets/Bigquery/index.ts
dbt target config with project: string, dataset: string, schema: string, plus optional auth and performance settings
Parsed from dbt profiles.yml, validated against JSON schema, converted to warehouse credentials
LightdashEmbedEvent packages/iframe-test-app/src/types.ts
cross-frame message with type: string, payload: Record<string, unknown>, timestamp: number
Generated by embedded Lightdash instances, sent via postMessage, logged for debugging iframe integrations
QueryDefinition packages/query-sdk/src/types.ts
query specification with columns: Column[], filters: Filter[], sorts: Sort[] — describes what data to fetch
Built by query SDK, sent to backend, compiled to warehouse SQL, executed to return QueryResult

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

Session Store (database)
Encrypted user session data managed by express-session — stores authentication state and user context across requests
Warehouse Connection Pool (cache)
Maintains active connections to configured data warehouses (BigQuery, Snowflake, etc.) with connection pooling for performance
Compilation Cache (cache)
Caches compiled SQL and dbt model metadata to avoid recompilation on repeated queries
React Query Cache (in-memory)
Frontend query result cache managed by React Query — stores API responses and manages invalidation strategies

Feedback Loops

Delays

Control Points

Technology Stack

TypeScript (runtime)
Primary language across all packages providing type safety for complex BI data models and API contracts
React (framework)
Frontend framework for building the interactive dashboard and chart creation interface
Express (framework)
Backend web server handling API routes, authentication, and dbt compilation orchestration
Passport (library)
Authentication middleware supporting multiple strategies (local, Google OAuth, SAML) for user login
CASL (library)
Authorization framework that builds permission abilities based on user roles and project membership
PostgreSQL (database)
Primary database for storing user sessions, project metadata, and application state
PEG.js (library)
Parser generator for compiling metric formula strings into abstract syntax trees
Mantine (library)
React component library providing UI components for forms, tables, and dashboard elements
Cypress (testing)
End-to-end testing framework for validating complete user workflows across the web application
pnpm (build)
Package manager for monorepo workspace management and dependency resolution
Turbo (build)
Build orchestration tool managing compilation, testing, and deployment across the 14 packages
Docker (infra)
Containerization for deployment with services for database, MinIO object storage, and the main application

Key Components

Package Structure

api-tests (testing)
Integration test suite for the Lightdash API with authentication helpers and test clients.
backend (app)
Core Node.js API server handling authentication, dbt compilation, warehouse connections, and data queries.
cli (tooling)
Command-line tool for deploying dbt projects to Lightdash and managing warehouse connections.
common (shared)
Shared TypeScript types, validation schemas, authorization logic, and utilities used across all packages.
e2e (testing)
End-to-end test suite using Cypress for integration testing across the full application.
formula (library)
Expression parser and SQL compiler that translates metric formulas into warehouse-specific SQL.
formula-tests (testing)
Test framework for validating formula compilation across multiple data warehouses.
frontend (app)
React-based web application providing the main Lightdash user interface for creating dashboards and exploring data.
iframe-test-app (testing)
Test application for validating iframe embedding functionality and cross-frame communication.
query-sdk (sdk)
Client SDK providing programmatic access to Lightdash's query builder and data fetching capabilities.
warehouses (library)
Adapters and connection handlers for various data warehouses (BigQuery, Snowflake, Postgres, etc.).

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Fullstack Repositories

Frequently Asked Questions

What is lightdash used for?

Self-service BI platform that transforms dbt models into interactive dashboards and analytics lightdash/lightdash is a 10-component fullstack written in TypeScript. Data flows through 6 distinct pipeline stages. The codebase contains 3406 files.

How is lightdash architected?

lightdash is organized into 4 architecture layers: Client Applications, API Server, Query Engine, Shared Foundation. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through lightdash?

Data moves through 6 stages: dbt Model Ingestion → Formula Compilation → User Authentication → Authorization Check → Query Execution → .... Data enters Lightdash through dbt model compilation (CLI deployment) or live queries (web interface). The system parses dbt YAML files to extract metric definitions, compiles custom formulas into warehouse-specific SQL, executes queries against configured data warehouses, and returns results as interactive charts or raw data. Authentication flows through passport strategies, while authorization uses CASL ability builders to control access to projects and resources. This pipeline design reflects a complex multi-stage processing system.

What technologies does lightdash use?

The core stack includes TypeScript (Primary language across all packages providing type safety for complex BI data models and API contracts), React (Frontend framework for building the interactive dashboard and chart creation interface), Express (Backend web server handling API routes, authentication, and dbt compilation orchestration), Passport (Authentication middleware supporting multiple strategies (local, Google OAuth, SAML) for user login), CASL (Authorization framework that builds permission abilities based on user roles and project membership), PostgreSQL (Primary database for storing user sessions, project metadata, and application state), and 6 more. This broad technology surface reflects a mature project with many integration points.

What system dynamics does lightdash have?

lightdash exhibits 4 data pools (Session Store, Warehouse Connection Pool), 4 feedback loops, 4 control points, 3 delays. The feedback loops handle cache-invalidation and convergence. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does lightdash use?

5 design patterns detected: Monorepo Package Architecture, Multi-Warehouse Abstraction, API Client with Session Management, Tiered Testing Strategy, Formula AST Compilation Pipeline.

Analyzed on April 20, 2026 by CodeSea. Written by .