Barrel files, wildcard imports, and deep-relative paths can keep your CI pipeline in the red no matter how smart your Nx/Bazel/Turborepo cache is. This guide shows you how to detect five high-impact “build-bloat” smells, track their burndown in Codemod Insights, and reclaim double-digit minutes from every build—without touching your build-tool flags.
Why prune flags can’t fix code-level calories
Nx’s affected:build, Bazel’s remote cache, and Turborepo’s hashing are great at skipping work, but they trust that your source tree is lean.
Code patterns that balloon dependency graphs—barrel re-exports, wildcard imports, fixtures living in src/—force “clean” rebuilds even when nothing meaningful changed.
Getting Started: Baseline your build time
- Grab today’s CI average
gh api repos/:owner/:repo/actions/runs --paginate \\
-q '[.workflow_runs[].run_duration_ms] | add / 60000'
# → prints average minutes per workflow run- Spin up a “CI Diet” dashboard in Codemod Insights
- Go to
**Insights → **
Create Dashboard
and name it
CI Diet. - For each smell below, create a Timeseries widget:
- Rule type:
ast-grep - Edit rule → add ast-grep YAML rule
- Match type:
Match Count(default) - Repo → select your project’s repository
- Query name: use the smell name or any label you prefer
- Optional:
- Group by codeowners
- Filter: add include/exclude glob patterns
- Optional:
create
one Single-Number widget
that holds
all five queries
(A-E) inside itself, then set the formula to
A+B+C+D+E. That widget will show the aggregate bloat count at a glance.
You now have a chart-per-smell that updates on every push—perfect for sharing progress with the team.
The Five Biggest Offenders & Ready-to-Use Rules
Paste each YAML block into Edit Rule when configuring the widget.

#1 Barrel Re-exports
Pattern: export \* from "./lib" Open in Codemod Studio
Impact: Touching any file inside the barrel's folder invalidates every downstream import.
#2 Wildcard Imports
Pattern: import \* as \_ from "lodash", default import of whole libs Open in Codemod Studio
Impact: Pulls whole sub-modules → bigger bundles, more hash misses.
#3 Deep Relative Paths
Pattern: ../../../../utils Open in Codemod Studio
Impact: Signals leaky boundaries; more files marked "dirty."
#4 Test Fixtures Inside src/
Pattern: \_\_fixtures\_\_/ Open in Codemod Studio
Impact: Large JSON/images counted in production hash.
#5 Duplicate CSS-in-JS Blocks
Pattern: CSS-in-JS blocks > 5 KB Open in Codemod Studio
Impact: Re-computes style hash on every consumer.
Each widget instantly shows how many matches live in the repo commit by commit—no builds required.
Mini-Benchmark: How much time can you save?
Capture a clean baseline
Fetch the last 200 successful runs of your main workflow:
WORKFLOW_ID=<your_main_workflow_id> # grab this from the Actions UI
gh api /repos/$ORG/$REPO/actions/workflows/$WORKFLOW_ID/runs \
-q '.workflow_runs[] | select(.conclusion=="success") | .run_duration_ms' \
--paginate > baseline.txtCreate a ci-diet branch and fix the five smells
1. Open Codemod Insights → create a dashboard → add the five ast-grep widgets (barrel, wildcard, deep-path, fixtures, CSS-dup).
2. Sort widgets by match-count so the worst offenders surface first.
3**. In your repo**:
git checkout -b ci-diet4. For each smell (worst offenders first), look for matches (using Run in CLI in Codemod Studio), refactor it (either manually or by creating a codemod with Codemod Studio), commit, repeat until the count drops.
git add -A
git commit -m "CI diet: trim barrel imports" # example message5. Push and open a draft PR:
git push -u origin ci-dietLet CI run at least ten times
Merge a couple of trivial PRs or re-run the workflow so the new branch accrues ~10 runs—enough to smooth out network variance.
Pull the “diet” timings
gh api /repos/$ORG/$REPO/actions/workflows/$WORKFLOW_ID/runs \
-q '.workflow_runs[]
| select(.conclusion=="success" and .head_branch=="ci-diet")
| .run_duration_ms' \
--paginate > diet.txtCrunch the numbers
old=$(jq -s 'add/length' baseline.txt) # average baseline ms
new=$(jq -s 'add/length' diet.txt) # average diet ms
weekly_builds=50 # adjust to match your team
printf "⏱️ Saved %.0f s per build\n" $(( (old-new)/1000 ))
printf "📉 ≈%.1f min reclaimed per week\n" \
$(bc -l <<< "scale=1; ($old-$new)/60000 * $weekly_builds")Example: trimming just 30 s off a pipeline that runs 50 times a week frees ~25 min weekly → ~21 hrs yearly of engineer waiting time.
Ready to try it?
Run a free Insights scan on your repo, paste the barrel-file rule, and see your first bloat metric in < 10 minutes—free-tier available. Get started now
