---
title: "Recce OSS: dbt Data Validation Tool"
description: "Case study: leading core architecture on Recce, an open-source dbt data validation tool. Lineage model unification across OSS and Cloud, MUI v9 design system upgrade, snapdom screenshot consolidation, and the pnpm 11 + Node 24 migration."
doc_version: 1
last_updated: 2026-05-24
canonical: https://variable.team/projects/recce-oss
---

<!--
  Source of truth: app/projects/recce-oss/page.tsx. Keep the h1 in sync.
  scripts/check-markdown-drift.ts verifies this in pre-commit.
-->

# Recce OSS

- **Company:** [Recce](https://reccehq.com)
- **Industry:** Data Engineering / Analytics Engineering
- **Dates:** Apr 2025 to Present
- **Project link:** <https://github.com/DataRecce/recce>
- **Stack:** Python, FastAPI, Pydantic, React, Next.js, TypeScript, MUI, React
  Flow, dbt, pnpm

### Merging the lineage model across OSS and Cloud

The OSS app and Cloud app had drifted apart in how they represented dbt
lineage. The API returned one shape, the frontend rebuilt the graph using a
separate algorithm. I introduced Pydantic models (MergedNode, MergedEdge,
MergedLineage) for the wire format, wrote the build_merged_lineage function
on the backend, and rewrote the frontend graph builder from 289 lines down
to 147. Both apps now consume the same response. The work shipped under
DRC-3258 and DRC-3260 with 230 added tests covering manifest unpacking edge
cases.

### Unifying screenshot capture on snapdom

Recce had two competing DOM-to-image libraries in production. One code path
used html-to-image, another used html2canvas-pro. Both had pinned versions
and dynamic imports to work around mutual incompatibilities. Under DRC-2685,
I consolidated both onto @zumer/snapdom, removed the pinned dependencies,
and deleted the library-specific branching. The change closed a steady
source of regressions whenever either upstream shipped a release.

### Upgrading the design system to MUI v9

Material-UI v9 broke Alert styling, removed class keys, and changed several
theme APIs. The automated codemod handled most cases, but several components
needed manual rewrites for the new compound-selector syntax. I shipped the
upgrade across the shared @datarecce/ui package and the main app together,
including components that hadn't been touched in months. The result is a
single major version across the org with no styling regressions in
production.

### Migrating the build to pnpm 11 and Node 24

DRC-3439 standardized the OSS repo on pnpm 11 with Node 24 as the engine
baseline. I updated 6 GitHub workflows, restructured the workspace.yaml
overrides, pinned pnpm with its SHA-512 integrity hash, and documented the
new strictDepBuilds behavior in AGENTS.md so future contributors hit fewer
surprises during onboarding. The follow-up PR review fixes brought the rest
of the developer docs into alignment with the new tooling baseline.

## Sitemap

[Full site index](/sitemap.md)
