badge: put a beta badge on your app icon from the command line
Add a badge to your app icon
At a glance
- What is it?
- badge is a small Ruby gem that adds a beta badge to a tvOS, iOS or Android app icon, either by running it in the project root or through a fastlane plugin, with options for a custom overlay, a dark variant, keeping the alpha channel and pulling a shields.io label onto the icon. It overwrites your icon files in place, and it depends on ImageMagick.
- Who is it for?
- The gem is worth installing if you ship beta builds to TestFlight and want the icon to say so without a designer in the loop, and the fastlane plugin makes it a one line addition to a release lane. It is the wrong choice if you need anything beyond a badge on an icon, since that is the whole product, and it is the wrong choice if ImageMagick is not welcome on your build machine.
- Can I use it commercially?
- Yes. MIT 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?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A badge, and nothing else
badge is a gem that helps to add a badge to a tvOS, iOS or Android app icon, and the readme says it plainly: yes that's it. It is built to easily integrate with fastlane, and there is a matching fastlane plugin published as a separate gem, fastlane-plugin-badge, with the same parameters. The reason a tool like this exists is a small but real annoyance in mobile release work. When you send a build to TestFlight, a beta tester sees an icon that looks exactly like the production app, and if several people have both on their home screen they cannot tell them apart. The convention in the iOS world is a small ribbon or dot on the corner of the icon, and this gem applies it to a whole set of icon files in one command. The tool is a Ruby gem rather than a script, the licence is MIT, and the project credits ThomasMirnig, KrauseFx and the fastlane project.
The glob is the part that catches people
Installing the gem is the usual Ruby incantation:
sudo gem install badgeAfter that you run badge in your project's root folder, and it searches the subfolders for your asset catalog app icon set and adds the badge to the icons. For anything other than an iOS asset catalogue, the icons are found with a glob, and the readme is emphatic about the shape of that path. You need the parameter --glob "/**/*.appiconset/*.{png,PNG}" to adjust where the icons are, and you have to use a / in the beginning of the custom path even if you are not starting from the root path. The example given is that if your icons are in res/ios/beta/Appicon/*, the call would be badge --glob "/res/ios/beta/Appicon/*". That leading slash requirement is the single most common source of confusion, and it exists because the glob is matched from the root of the tree rather than relative to the current directory. The tool can also be pointed at Android icons, tvOS icons or any other iconset.
It overwrites your icon files, so keep the alpha channel deliberately
The warning in the readme is short and deserves to be read twice. Be careful, it actually overwrites the icon files. There is no dry run and no output directory, so the tool works in place, which is convenient when your icons are already under version control and a problem when they are not. The related option is the alpha channel. To keep the alpha channel in the icons you use --alpha_channel, which matters when your overlay or your artwork relies on transparency and you do not want it flattened away. The other visual options are --dark, which produces the dark variant and can be combined with --alpha, and --custom, which takes a path to your own overlay image so you can use a badge that is not the default one. The whole set is listed with badge --help, which is where you find out that there are more parameters than the readme describes.
The shields.io integration, and a default that changed in 0.4.0
The shield option puts a shields.io label on the icon, and the workflow is to copy the string of the shield from the shields.io URL, for example --shield "Version-0.0.3-blue". The readme warns that the response from shields.io sometimes takes a long time and can time out, and gives the remedy, adjusting the timeout with --shield_io_timeout 10, which matters because the tool is calling a public service over the network during a build. The placement is controlled with --shield_gravity, whose choices are NorthWest, North, NorthEast, West, Center, East, SouthWest, South and SouthEast, and the appearance with --shield_parameters "colorA=abcdef&style=flat", a string of key value pairs separated by ampersands as specified on shields.io. Two flags control the badge and the shield separately: --no_badge hides the beta badge completely when you only want the shield, and --shield_no_resize puts the shield on the icon without resizing it to fill. That last one exists because of a change in version 0.4.0, where the shield graphic will always be resized to aspect fill the icon instead of just being added on top.
One line inside a fastlane lane
The fastlane plugin is the recommended route for a release pipeline, and it takes the same parameters as the gem. The readme shows a complete lane so the placement is obvious, and the add_badge call is the part you copy:
lane :appstore do
increment_build_number
cocoapods
add_badge(dark: true) #or
#add_badge(alpha: true) #or
#add_badge(custom: "/Users/HazA/Desktop/badge.png") #or
#add_badge(shield: "Version-0.0.3-blue", no_badge: true)
xctool
snapshot
sigh
deliver
sh "./customScript.sh"
slack
endThe ordering in the lane is the interesting part, because the badge is applied after the build number is incremented and before xctool builds the archive, so the icon that ships in the beta build is the badged one. It also comes before the delivery steps, so the artifact that reaches TestFlight carries the badge. If you use it this way, remember that the file overwrite happens in your working tree, so the next build without a badge call will use the previously badged icons unless your icons are restored from version control first.
ImageMagick is the real dependency
The common problems section names one thing, and it is the one that will bite you. If Jenkins has problems finding imagemagick on your Mac, add the following environment variable to your job, which is PATH=$PATH:/usr/local/bin, and make sure imagemagick is installed on your machine, for example with brew install imagemagick on a Mac. So the gem is small, but the tool it wraps is not, and in a CI environment the path to the ImageMagick binaries is the usual source of a failed job. That is the whole troubleshooting section, which is a fair reflection of the tool's size. For a project that only needs to composite a small overlay onto a set of PNGs, that is a reasonable trade, but it is a trade, and it is the thing to weigh against the alternative of doing the same thing with a few lines of your own image processing code.
The repository, and a release history with a gap
The tree is small, with the gemspec at the root, lib and bin for the code, a test directory and an assets directory holding the sample icons. The Makefile is where the project documents itself best. There is a smoke target that runs test/smoke.sh, and a create-assets target whose comment says it recreates all assets for the readme. What it does is instructive, because it shows the tool being used on its own sample icons with every combination of options, copying a fittrack icon and a TestFlight icon into a new file, running bin/badge with a glob on the copy, with --dark, with --alpha, and with the shield variants including the no-resize one. The documentation images in the readme are therefore generated, not drawn, which means they cannot drift from the behaviour of the code. The version history is the odd part. The releases are 0.8.6 and 0.8.7 from January 2018, and then 0.13.2 on 2026-04-24, with the last push on the same day, so the project was quiet for a long stretch and has recently been picked up again. The gem is published on RubyGems, there is a fastlane plugin badge, and uninstalling is sudo gem uninstall badge.
Editorial conclusion
The gem is worth installing if you ship beta builds to TestFlight and want the icon to say so without a designer in the loop, and the fastlane plugin makes it a one line addition to a release lane. It is the wrong choice if you need anything beyond a badge on an icon, since that is the whole product, and it is the wrong choice if ImageMagick is not welcome on your build machine. Before you run it, read the glob rules and the overwrite warning, keep a copy of your original icon set, and pin the gem version, since the release history is unusual, with a 2018 line and then a 2026 release.
Frequently asked questions
What does the badge gem do?
It adds a beta badge to a tvOS, iOS or Android app icon. You run it in your project root and it searches the subfolders for your asset catalogue app icon set, or you point it at another location with a glob. It is built to integrate with fastlane.
How do I install and run badge?
Run sudo gem install badge, then call badge in your project root. For icons outside an iOS asset catalogue, or for Android, tvOS or any other iconset, use the --glob parameter, for example badge --glob "/res/ios/beta/Appicon/*". The path must start with a slash even when it is not a root path.
Does badge overwrite my icon files?
Yes, the readme warns that it actually overwrites the icon files. To keep the alpha channel in the icons you use the --alpha_channel option, and there is a --custom option if you want to use your own overlay image instead of the default badge.
How do I add a shields.io label to the icon?
Copy the shield string from the shields.io URL and pass it with --shield, for example --shield "Version-0.0.3-blue". You can set the position with --shield_gravity, the appearance with --shield_parameters, raise the timeout with --shield_io_timeout, hide the beta badge with --no_badge and restore the old non-resizing behaviour with --shield_no_resize.
Can I use badge inside a fastlane lane?
Yes, through the fastlane-plugin-badge gem, which takes the same parameters. A lane calls add_badge with options such as dark, alpha, custom or shield, and the call is placed after increment_build_number and before the build and delivery steps.
Official sources
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.
[](https://hysenlabs.com/projects/hazat-badge)Was this useful?