Skip to content
Fallow home
All docs pages

Health badges

Show your project's health score and letter grade in your README with a shields.io-compatible badge.

A health badge shows readers your project's code health score in the README. One command writes the SVG.

fallow health --format badge > badge.svg

The badge shows the letter grade and the numeric score in shields.io flat style:

zod: B (71)preact: B (76)svelte: B (73)vite: C (65)

Grades: A (≥85, green) · B (70–84, green) · C (55–69, yellow) · D (40–54, orange) · F (<40, red).

Hosting the badge

Your README needs a stable URL for the SVG. The three options below go from simplest to most reliable. Options 2 and 3 render only for public repositories. See Private repositories.

Option 1: Commit to your repo

Generate the badge and commit it directly:

fallow health --format badge > .github/badges/health.svg
git add .github/badges/health.svg
git commit -m "chore: update health badge"

Then reference it in your README:

![fallow health](.github/badges/health.svg)

This is the simplest approach. The badge changes only when you regenerate it and commit it.

Add a CI step that generates the badge and publishes it to a badges branch:

- name: Generate health badge
  run: fallow health --format badge > badge.svg

- name: Publish badge
  uses: peaceiris/actions-gh-pages@v4
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: .
    publish_branch: badges
    keep_files: true
    include_files: badge.svg

Then reference the badge from the badges branch:

![fallow health](https://raw.githubusercontent.com/your-org/your-repo/badges/badge.svg)

Option 3: Shields.io endpoint

For a dynamic badge from shields.io, generate a JSON endpoint file:

fallow health --format json --score --quiet 2>/dev/null \
  | jq '{schemaVersion: 1, label: "fallow", message: "\(.health_score.grade) (\(.health_score.score | floor))", color: (if .health_score.score >= 85 then "brightgreen" elif .health_score.score >= 70 then "green" elif .health_score.score >= 55 then "yellow" elif .health_score.score >= 40 then "orange" else "red" end)}' \
  > health-badge.json

Host the JSON file, for example in a Gist or on the badges branch. Then use the shields.io endpoint badge:

![fallow health](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/your-org/your-repo/badges/health-badge.json)

The badge renders from the shields.io CDN and always shows the latest score.

Private repositories

raw.githubusercontent.com (Option 2) and the shields.io endpoint (Option 3) render only for public repositories. Neither host can read a private repo, so the badge shows as a broken image. Do not put a personal access token in the URL. That is insecure and against GitHub's terms.

For a private repo, commit the badge into the repository and reference it with a relative link. GitHub renders relative image links for any viewer with read access to the repo:

![fallow health](.github/badges/health.svg)

To update the badge from CI, regenerate it and commit it to a tracked path on your default branch. Do not publish it to a separate badges branch:

- name: Update health badge
  run: |
    fallow health --format badge > .github/badges/health.svg
    git config user.name "github-actions[bot]"
    git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
    git add .github/badges/health.svg
    git diff --quiet --cached || git commit -m "chore: update health badge [skip ci]"
    git push

The job needs permissions: contents: write. A relative link resolves against the branch that the reader views the README on. The badge must be on that branch. A relative link cannot point to a separate orphan badges branch (Option 2), so a private repo commits the badge directly.

Monorepo badges

For workspace packages, scope the badge with --workspace:

fallow health --format badge --workspace my-package > badges/my-package.svg

Technical details

  • Self-contained SVG with embedded Verdana font metrics. The badge makes no external requests
  • Each badge has unique element IDs, so you can inline more than one badge on a page
  • --format badge turns on --score, so you do not need to pass both
  • If fallow cannot compute the score, it prints an error and exits with code 2
  • You can also set the format with the FALLOW_FORMAT=badge environment variable

See also