How to Add a README Badge: The Complete shields.io-Style Guide
Learn what a README badge is, how shields.io styles work, the common build, version, license, and downloads badges, and exactly how to paste badge markdown into your README.
How to Add a README Badge: The Complete shields.io-Style Guide
Open almost any popular GitHub repository and the first thing you see, before the project description, is a row of small colored pills: build passing, version 1.4.0, license MIT, downloads 2M/month. These are README badges, and they do a surprising amount of work for how little space they take up. A new visitor reads that row in under a second and walks away knowing the project builds cleanly, ships releases, is safe to depend on legally, and has real users.
I added my first badge by copy-pasting a URL I didn't understand from someone else's README and editing the words until they matched my project. It worked, but I had no idea what I was doing. This guide is the explanation I wish I'd had: what a badge actually is, how the shields.io style system works, which badges matter, and how to drop them into your README correctly.
What a README badge actually is
A badge is just an image. That's the whole secret. When you write  in a Markdown file, your README renderer fetches that URL and displays the returned SVG inline. The "badge service" — shields.io is the dominant one — reads the path of the URL (badge/build-passing-brightgreen), renders a small SVG with a gray left label, a colored right message, and ships it back.
Two kinds of badges exist. Dynamic badges point at a live endpoint: img.shields.io/npm/v/react queries the npm registry on every request and renders whatever the current version is. Static badges encode the text directly in the URL and never change. A license MIT badge is static — your license isn't going to flip to GPL between page loads — so re-fetching it from a remote server on every visitor's page view is pure overhead. That distinction is the single most useful thing to internalize, and it's the case where generating the SVG locally and committing it to your repo genuinely beats the live service.
How the shields.io style system works
shields.io ships five visual styles, and matching them is what makes a custom badge sit flush in a row instead of looking like it wandered in from another website:
- flat — the default. 20px tall, subtle top-edge gradient, rounded 3px corners.
- flat-square — same proportions, no corner radius, no gradient. Cleaner on dense rows.
- plastic — the old glossy look with a stronger gradient. Rarely used in new projects.
- for-the-badge — tall (28px), uppercase, bold. The "shouty" style for hero rows.
- social — GitHub's own follow/star button look, with a little drop shadow.
One technical detail trips people up: badge width. The SVG isn't a fixed size — it auto-sizes to fit the text. shields.io estimates text width at roughly 6.6 pixels per Verdana-family character and pads the label and message blocks around that. This is also why spaces in a badge URL are encoded as _ (underscore) and a literal underscore becomes __ (double underscore) — the path can't contain raw spaces, so build_passing in the URL renders as build passing on the badge. Get the encoding wrong and your badge text breaks; get the style wrong and it just looks slightly off next to its neighbors.
The badges worth having
You don't need twelve. A tight, honest row of four or five beats a wall of decoration. The ones that earn their place:
- build —
build passing/build failing. Wire this to your CI so it reflects reality; a hardcodedpassingbadge on a broken project erodes trust fast. - version —
version 1.4.0ornpm v1.4.0. Tells dependants what's current. - license —
license MIT. The fastest legal answer a potential user needs. - coverage —
coverage 95%. A credible signal that tests exist and matter. - downloads —
downloads 2M/month. Social proof, when the numbers are good.
Keep colors in shields.io's muted palette: #4c1 (brightgreen) for passing, #e05d44 (red) for failing, #007ec6 (blue) for neutral info. Bright neon colors scream "one-off custom badge" and clash with the row.
A real example: generating a license badge
Say you want a static license MIT badge committed to your repo so it never depends on shields.io being up. Using the GitHub README Badge Generator, you pick the license MIT preset, choose the flat style, set the right block to brightgreen, and copy the Markdown output. Here's exactly what comes out:
[](https://opensource.org/licenses/MIT)
The [](...) shape is a linked image: the inner  is the badge image, and the outer [...](url) wraps it so clicking the badge opens the license page. You save the generated SVG to assets/badge-license.svg, commit it, and the badge now loads from the same origin as your README — no DNS lookup, no HTTP round trip to an external service, no broken image when shields.io has a bad day. If you'd rather keep a live version, the same tool exports HTML <img>, AsciiDoc image:badge.svg[...], and reStructuredText for PyPI projects, since markdown badges silently don't render on PyPI package pages.
Pasting badges into your README
Badges go at the very top, immediately under the # Project Name heading and before the description paragraph. Put each badge's Markdown on the same line separated by spaces so they render in one row:
# My Project
[](https://github.com/me/proj/actions) [](https://github.com/me/proj/releases) [](https://opensource.org/licenses/MIT)
One sentence describing what this project does.
A few things that bite people. GitHub caches images through its camo proxy, so if you update an SVG and the old one still shows, append ?v=2 to bust the cache. Never paste the camo.githubusercontent.com/... URL itself — it's GitHub-specific and breaks on GitLab, Codeberg, and every other host. And don't mix styles in one row: a 28px for-the-badge next to a 20px flat badge makes the line look broken.
Where this fits
Badges are one piece of a README that converts visitors into users. The same generator's batch mode handles a monorepo's 30 packages in one paste, and once your badge row looks right you'll want the body to match — a clean feature comparison reads best as a real table, which the Markdown Table Generator builds for you without hand-aligning pipes. Everything stays plain Markdown and SVG, so it renders identically on GitHub, GitLab, Bitbucket, Codeberg, and Gitea.
Start with four badges that tell the truth, encode them correctly, keep one style per row, and commit the static ones. That row is the first impression your project gets — make it load fast and say something real.
Made by Toolora · Updated 2026-06-13