Library / SDK
badgen/badgen avatar
badgen/badgen

badgen renders a flat badge as SVG in one call, with no dependencies at all

Fast handcraft svg badge generator.

561 stars38 forksJavaScriptISC

At a glance

What is it?
badgen is a small JavaScript library that turns a label, a status and some colors into an SVG badge string, and it is the generator behind badgen.net. The library has zero dependencies, runs in Node and in the browser, and its API is one function with a handful of options, which makes it easy to embed in a README or a build step.
Who is it for?
Adopt badgen if you generate badges in a build step, in a Node script or in a browser page and want a library with no dependency tree to audit. Do not adopt it as a badge hosting service, since badgen.net is a separate thing that this library merely powers, and note that the colour set is a fixed list of named colours plus RGB values, with no gradients in this library.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 73 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One function, one string, and the whole badge API surface

badgen is described as a fast handcraft svg badge generator, and it is used on badgen.net. The whole API is a single exported function:

javascript
const { badgen } = require('badgen')

// only `status` is required.
const svgString = badgen({
  label: 'npm',      // <Text>
  labelColor: 'ADF', // <Color RGB> or <Color Name> (default: '555')
  status: 'v1.2.3',  // <Text>, required
  color: 'blue',     // <Color RGB> or <Color Name> (default: 'blue')
  style: 'flat',     // 'flat' or 'classic' (default: 'classic')
  icon: 'data:image/svg+xml;base64,...', // Use icon (default: undefined)
  iconWidth: 13,     // Set this if icon is not square (default: 13)
  scale: 1           // Set badge scale (default: 1)
})

The result is a string. There is no DOM element, no canvas, no image object. The function returns SVG markup and you put it wherever SVG is allowed, which for a README means a data URI or an image tag pointing at a service, and for a web page means innerHTML.

Only status is required, and every other option has a documented default. label defaults to empty, labelColor to 555, color to blue, style to classic, icon to undefined, iconWidth to 13 and scale to 1. The comments in the example are part of the documentation, since they record the accepted values for each field.

Two details are easy to get wrong. The labelColor example is a three character hex value without a hash, and the option accepts either a colour name or an RGB value, so both 333 and blue work. And the icon option takes a data URI, not a URL, which means the icon is inlined into the SVG rather than fetched.

The browser build is a script tag, and the palette is a fixed list

The README documents a browser usage path with a script tag:

html
<script src="https://unpkg.com/badgen"></script>
<script>
  var svgString = badgen({ /*...*/ })
</script>

The unpkg entry is pointed at by the package.json field unpkg, which is set to dist/index.browser.js, while the main entry is dist/index.js and the module entry is dist/index.mjs. So the browser bundle is a separate build artefact, not the same file exposed under a different condition.

The colour names are listed rather than discovered. The available set is blue, cyan, green, yellow, orange, red, pink, purple, grey and black, each shown as a rendered example. That is a deliberate constraint of a badge generator whose output has to look the same everywhere, and it is also the main thing to know before you start: if your brand colour is not one of those ten and not an RGB value you supply, you are mixing the two mechanisms.

The related project listed at the end of the README, gradient-badge, exists because this library does not do gradients. A badge with a gradient background is a different generator, which tells you the scope of badgen is deliberately narrow.

The benchmark numbers come from a 2014 machine, and that is the point

The README publishes a benchmark table, and the header line is the interesting part. It says npm run bench on iMac 5K (Late 2014), 3.5G i5, with Node.js 12.11.0.

The numbers that follow are the kind of figure that is usually worth ignoring, and here the machine specification is what makes them useful. A library reporting around a million operations per second on that machine does not need a fast computer to be fast, and the point of publishing the old hardware is to make exactly that argument: the output is cheap because there is nothing to compute.

The reported figures range from roughly 780,000 operations per second for the flat style with long parameters up to about 1,290,000 for the classic style with emoji, across a matrix of two styles and four parameter shapes. The emoji and icon variants are slower than the plain ones, which is what you would expect if the extra work is text measurement and inline image data rather than the badge layout itself.

The README lists fast by design as a feature and points at the benchmarks section, and the zero dependency claim is the mechanism. With no dependencies there is no startup cost to import, no transitive tree to load, and nothing that could dominate the actual work of laying out two pieces of text and a rectangle.

The one caveat a reader should hold onto is that these are the project's own numbers on the project's own machine, from a Node version long out of support. They establish an order of magnitude, not a figure to quote in your own documentation.

The test setup is a native runner plus checked in snapshots

The development section is short and says something about how the project is built.

The test script builds dist/ and runs the suite with Node's native test runner. The build script is vite build, with a postbuild step that runs tsc --emitDeclarationOnly, and the types are shipped from dist/index.d.ts, with the exports map pointing types at that file for both import and require conditions.

The snapshot script updates the checked-in snapshots, and the README mentions a preview app that starts the Vite preview server with live reload at http://localhost:5173/.

The repository layout follows that split. There is a src/ directory for the implementation, a test/ directory, a tap-snapshots/ directory for the checked-in snapshots, a bench/ directory with the benchmark entry point, a preview/ directory for the Vite preview app, and a vite.config.mjs at the root. The scripts in the package.json spell out the flow: bench runs node bench/index.js, preview runs vite, snaptests sets TAP_SNAPSHOT=1 before npm test, and prepack runs the build.

So the snapshot testing is the primary correctness mechanism, which makes sense for a library whose entire output is a rendered image. A badge that differs by one pixel is a bug, and a text diff on the SVG catches what a unit test on the option handling would not. The trade-off is that snapshots are sensitive to any change in rendering, including a font metric change, so a cosmetic tweak upstream shows up as a snapshot diff rather than a silent behaviour change.

The package publishes only the dist directory, and a prepack hook runs the build so the published tarball always contains fresh output, with a separate pack:check script that runs npm pack in dry run mode.

Where a hosted badge service is the better answer

The obvious alternative is not another library, it is not generating the badge at all. A hosted service takes a URL and returns the image, and the README says badgen is used on badgen.net for exactly that. The difference in approach is where the SVG comes from. With badgen as a dependency, the badge is a build artefact, committed to your repository, with no network call at read time and no third party in the path of your README. With a hosted service, the badge is a request per view, and the service is in the path.

That distinction matters for a project badge specifically, because project badges are usually embedded in a README on a public repository, which is exactly the case where you do not want a third party service in the render path, and where a broken service is a broken README.

The second limit is scope. badgen renders one flat label and status with one background colour per side. There are no gradients in this library, no custom fonts beyond the ones it ships, and the related project listed in the README, gradient-badge, exists to cover that gap. If you need a badge with a gradient, you are in the territory of a different generator.

The third is the licence question, and here the repository is inconsistent in a way you should check yourself. The repository listing records the licence as ISC, while the package.json records it as MIT, and the README's badge points at a license file in the repository. The difference between ISC and MIT is small, but since the badge rendering ends up in your README, the terms under which you redistribute it are worth a minute of your own reading. That is a licensing note rather than legal advice.

A current release line and a small but real surface area

The maintenance picture is straightforward. The last push was on 2026-08-10 and the repository is not archived. The release history shows v3.3.1 on 2026-05-08 and v3.3.2 on 2026-05-10, with v3.2.3 from 2023-07-21 before that, so the 3.3 line is where the recent work is and the project is currently at 3.3.2 in the package metadata.

The dependency footprint is the other thing to note, and it is the project's headline feature rather than an accident. The devDependencies are the toolchain, with typescript, vite and the benchmark library, plus @types/node, and there is no runtime dependency list at all. The runtime cost of adding badgen to a project is one package and no transitive tree.

That makes the upgrade story simple too. A library with no dependencies cannot break your build through a transitive major version bump, which is the usual reason a small utility is still a maintenance liability years later. The remaining upgrade risk is the rendering behaviour itself, which is what the snapshot tests guard.

For a reader deciding whether to use it, the shape is easy to summarise. One function, ten colour names or an RGB value, two styles, an optional inline icon, an optional scale, and a string of SVG out. If that is all you need, a dependency free generator that runs at a million operations a second on a decade old laptop is a good trade. If you need badges to be rendered by someone else's server so that they stay consistent without a build step, then badgen.net is the thing to look at instead, and this library is what it happens to be built on.

Editorial conclusion

Adopt badgen if you generate badges in a build step, in a Node script or in a browser page and want a library with no dependency tree to audit. Do not adopt it as a badge hosting service, since badgen.net is a separate thing that this library merely powers, and note that the colour set is a fixed list of named colours plus RGB values, with no gradients in this library. Verify first which style you want, since classic and flat produce different geometry, that your chosen colours are either a name from the documented list or an RGB value, and whether the emoji and icon handling in the browser build matches what you need.

Frequently asked questions

How do I use the badgen library to generate a badge?

Install it with npm install badgen, then call the exported badgen function with a label, a status and optional colors, style, icon, iconWidth and scale. Only status is required, and the function returns the SVG as a string, so you can write it to a file or inject it into a page.

What colours and styles does badgen support?

Colors can be a named colour or an RGB value, and the named set is blue, cyan, green, yellow, orange, red, pink, purple, grey and black. The style is either flat or classic, with classic as the default. Gradients are not part of this library, they are covered by the separate gradient-badge project.

Can I use badgen in a browser?

Yes. The README shows a script tag pointing at the unpkg build, which is served from dist/index.browser.js, and the package exposes separate main, module and unpkg entries. The package is described as running in node and browser.

How is the badgen package tested?

The test script builds dist/ and runs the suite with Node's native test runner, and there is a script that updates the checked-in snapshots. The repository has a tap-snapshots/ directory, a bench/ directory with the benchmark entry point, and a preview/ directory for the Vite preview app that serves on http://localhost:5173/.

What licence is badgen released under?

The repository listing records the licence as ISC, while the package.json records it as MIT, and the README badge points at a license file in the repository. The last release listed is v3.3.2 from 2026-05-10 and the last push was on 2026-08-10.

Official sources

  1. badgen/badgen on GitHub
  2. Issues
  3. License: ISC
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/badgen-badgen.svg)](https://hysenlabs.com/projects/badgen-badgen)

Was this useful?