← All projects
Data & ETL

NC Labor Market Dashboard

Python ETL pulls BLS + Census ACS data, ships as a static, filterable React dashboard.

PythonBLS APICensus ACSNext.jsTypeScript

The problem

Public labor data lives in two places that don't talk to each other — BLS (employment and wages by occupation) and Census ACS (geography). To answer "which counties in NC are dense in X occupation" you have to stitch them yourself.

Pipeline

Python ETL scripts in scripts/ pull from the BLS and Census APIs, write raw JSON into data/raw/, then transform and join into data/processed/occupation_dashboard.json. The static site imports the processed file at build time — no server needed, no API key on the client.

To refresh: python scripts/build_occupation_dashboard.py then push. GitHub Actions rebuilds the static site and CloudFront invalidates the cache.

Live dashboard

Total employed

5.2M

Categories

5

Top category

48.8%

Data year

2022

Management, Business, Science & Arts

Workers

2.55M

% of workforce

48.8%

Top counties

Wake County, North Carolina318,509
Mecklenburg County, North Carolina312,161
Guilford County, North Carolina132,614
Forsyth County, North Carolina90,460
Durham County, North Carolina83,332
Buncombe County, North Carolina67,608
Union County, North Carolina66,001
Cabarrus County, North Carolina60,095

Source: U.S. Census Bureau American Community Survey (ACS) · North Carolina · 2022

Hard decisions

Bake the data into the build, don't fetch at runtime. The dataset is small (~50KB) and updates monthly at most. A build- time import means no CORS, no API key in the bundle, and no loading spinner. The cost: a deploy is required to see new data, which is fine for monthly data.

Categorize at ETL time, not in the UI.The five occupation buckets are derived in Python and stored in the JSON. Keeps the React code dumb — it just renders what it's given.