Using Codecov Flags for Component‑Level Coverage in Monorepos
Learn how Codecov Flags let you track coverage per component in a monorepo, set separate thresholds, and avoid misleading project‑wide numbers.
25 Jul 2025, 23:23 UTC

The problem: one coverage number hides component health
In a monorepo where backend services, frontend UI, and integration tests live side‑by‑side, a single project‑wide coverage percentage can be misleading. A drop in a critical service may be offset by gains in experimental code, and the overall number stays green while a key component regresses.
Thesis: Codecov Flags give you per‑component coverage dashboards and status checks
By labeling each coverage upload with a flag, Codecov treats the flag as a separate entity: it gets its own dashboard, trend graph, and pull‑request comment. Teams can enforce different thresholds per flag, and the configuration lives in the repository’s codecov.yml.
How flags work
- Define flags under the
flags:key incodecov.yml. Each flag can optionally setcarryforward: trueto reuse the last known coverage when the flag isn’t uploaded in a commit. - In CI, after generating a coverage report (lcov, cobertura, etc.), run the Codecov uploader with
-F 'flagname'. You can upload multiple flags in the same run by repeating the option or passing a comma‑separated list. - Flags are independent of path grouping; combine them with the
components:section if you want path‑based filtering as well.
Worked example: backend and frontend flags
# codecov.yml
flags:
backend:
carryforward: true
frontend:
carryforward: true
Assume two directories: service-a/ (backend) and web/ (frontend). In your CI pipeline you might have:
# backend tests
cd service-a
npm test -- --coverage
# upload backend coverage
codecov -F 'backend' -f 'coverage/lcov.info'
# frontend tests
cd ../web
npm test -- --coverage
# upload frontend coverage
codecov -F 'frontend' -f 'coverage/lcov.info'
After each upload, Codecov shows two separate flags: backend and frontend, each with its own percentage and trend. If a commit only touches the frontend, the backend flag will retain its last known value because of carryforward: true, preventing a false drop to zero.
Trade‑off and limitation
Flag names are case‑sensitive and must match exactly between codecov.yml and the -F argument; a typo creates an orphaned flag that never receives data. Moreover, carryforward can hide real regressions if a component’s tests are accidentally skipped—monitor upload frequency via the Codecov API or the "Uploads" tab to catch missing flags.
On the free tier, private repositories are limited to a small number of flags (often five) and historical flag data may be retained for a shorter period. Check your plan’s limits before committing to many fine‑grained flags.
Checking that flags are working
- Visit the repository on Codecov and look for the "Flags" dropdown near the top‑right; you should see
backendandfrontendlisted. - Open a pull request that touches only one component; the PR comment should show a status check for the relevant flag and a "no change" message for the other.
- Optionally, run a GraphQL query against the Codecov API:
{
commit(owner: "your-org", repo: "your-repo", branch: "main") {
flags {
name
coverage
}
}
}
The response should return each flag with its latest coverage percentage.
Actionable closing
Start with two flags that map to your most important logical components, enable carryforward to avoid noisy zeros, and enforce per‑flag thresholds in your branch protection rules. As the project grows, add more flags or combine them with components for path‑based granularity, and periodically audit upload frequency to ensure carryforward isn’t masking real gaps.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.