Badge Maker

The standalone SVG badge-rendering library and CLI extracted from Shields.io, with no server dependency.

Library
npm
v6.0.0
27,163stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
83/100Excellent
Development Activity100
Maintenance52
Community80
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture78
Code Quality82
Innovation58
Learning Curve85

badge-maker is the npm package that packages up the actual badge-rendering engine behind Shields.io — the same code that draws the millions of build, version, and license badges embedded in READMEs across GitHub — as a small, dependency-light library and command-line tool. Given a label, message, and optional color/style/logo, it validates the input and returns a ready-to-embed SVG string, with no network call, server process, or image-service dependency required.

It ships both as an importable ESM module (makeBadge()) for programmatic use inside build scripts, static site generators, or custom badge services, and as a badge CLI binary for one-off generation from the terminal or CI pipelines. Because it is maintained inside the shields/shields monorepo, it stays in lockstep with the canonical color palette, named color aliases, and five visual styles (flat, plastic, flat-square, for-the-badge, social) that Shields.io itself renders.

What You Get

  • A single makeBadge(format) function that turns a label/message/color/style object into an SVG string, with a typed ValidationError thrown for malformed input instead of a silent failure
  • A badge CLI binary (badge build passed :brightgreen > mybadge.svg) for generating badges from shell scripts or CI pipelines without writing any code
  • Shields.io’s full named-color palette and aliases (brightgreen, success, critical, informational, etc.) plus support for hex and arbitrary CSS colors, normalized consistently with the main site
  • All five official Shields.io visual styles — flat, plastic, flat-square, for-the-badge, and social — rendered pixel-for-pixel the same as shields.io itself
  • Optional embedded logos (base64 data URLs), left/right click-through links, and an idSuffix option to avoid SVG id collisions when multiple badges are inlined on one page
  • Hand-written TypeScript type definitions (index.d.ts) for the public Format interface and makeBadge signature

Common Use Cases

  • Generating custom status badges (build result, coverage, version) inside a CI pipeline and committing the SVG as a static asset instead of hot-linking to a badge service
  • Building an internal or white-labeled badge service that needs the exact same rendering as Shields.io without depending on shields.io’s uptime or rate limits
  • Embedding dynamically generated badges into a static site generator or documentation build step at build time
  • Producing one-off badges from the command line for READMEs, release notes, or presentations without touching any code

Under The Hood

Architecture The package is a small, side-effect-free pipeline: index.js validates and cleans the caller’s input object (throwing a typed ValidationError for bad fields), then hands a normalized format to make-badge.js, which looks up the requested visual style in a renderer table exported by badge-renderers.js (one function per style: flat, plastic, flat-square, for-the-badge, social) and renders it as a tree of XmlElement/ElementList objects defined in xml.js, which serialize to an XML string that is whitespace-stripped before being returned. color.js is a parallel concern: it normalizes named colors, Shields aliases (e.g. success -> brightgreen), hex, and arbitrary CSS colors, and computes a brightness score used to pick contrasting text/shadow colors. A separate badge-cli.js entry point (the package’s bin) is a thin argv-parsing wrapper around the same makeBadge() call, so the CLI and library share one code path with no duplicated rendering logic. There is no I/O, HTTP server, or persistence anywhere in this package — that responsibility stays in the parent shields/shields monorepo’s server code.

Tech Stack It’s a Node.js ESM-only package ("type": "module", engines.node >= 22) with a deliberately tiny dependency footprint: anafanafo for precise text-width measurement (used to size badge segments correctly) and css-color-converter for parsing arbitrary CSS color strings. Type definitions are a hand-authored index.d.ts rather than a compiled TypeScript build, and the package is published straight from source with no bundler step. It’s dual-licensed MIT/Apache-2.0 (changed from CC0 in the 6.0.0 release) and versioned/released together with the rest of the shields/shields monorepo.

Code Quality Every core module has a co-located spec file — index.spec.js, make-badge.spec.js, color.spec.js, xml.spec.js, and badge-cli.spec.js — exercising validation errors, color normalization edge cases, and asserting the output is well-formed SVG via the is-svg helper. The monorepo runs dedicated GitHub Actions workflows scoped to this subpackage (test-package-lib.yml, test-package-cli.yml) in addition to repo-wide linting and Danger checks, so regressions in badge-maker specifically are caught in CI rather than only as part of the full shields.io test suite. Validation failures raise a distinct ValidationError class rather than generic errors or silent undefined returns, and naming/structure are consistent across the small set of modules.

What Makes It Unique Rather than reimplementing Shields.io’s badge look from scratch, badge-maker is the actual rendering engine extracted verbatim from the service that renders badges across most of GitHub’s ecosystem — using it guarantees pixel-identical output to shields.io with zero network dependency. Its most distinctive design touch is the idSuffix option, added specifically to prevent SVG element-id collisions when several badges are inlined directly into one HTML page rather than referenced as external images — a problem generic SVG-badge libraries built independently rarely account for.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search