How to standardise off-brand hex values across an svg icon library
- Step 1Audit your colours first (separate step) — The Hex Swapper doesn't list colours. Extract unique hex values with your own tooling, an SVGO pass, or by running each icon through the CSS Variable Injector (its empty-map mode assigns
--svg-color-Nto each detected colour, revealing what's in the file). - Step 2Compare against your token palette — List the off-brand values: shades that are close to a token but not exact (
#003084vs#003082), legacy hex from prior rebrands, and rounding artifacts. Each becomes afromin your fix list. - Step 3Build a pair per off-brand value — Map each stray hex to the correct token:
#003084 → #003082,#0a2e7a → #003082, and so on. Because matching is literal, every distinct off-brand spelling needs its own pair. - Step 4Run the swap on each icon — Process one SVG at a time (the tool takes a single file per run). Check the 'Colors swapped' count against the number of fills you expected to correct.
- Step 5Review the diff — Open the output source or diff it against the original. A clean, colour-only diff confirms geometry and structure are untouched and only the token correction happened.
- Step 6Lock it in with CI validation — Add a lint step that fails the build if any committed SVG uses a hex outside your approved token set. The swapper fixes today's drift; the lint prevents tomorrow's.
Common drift sources and the fix
How off-brand colours creep in, and the swapper pair that corrects each.
| Drift source | Example | Corrective pair |
|---|---|---|
| Eyedropper near-miss | #003084 instead of token #003082 | #003084 → #003082 |
| Legacy rebrand hex | Old brand #0a2e7a still in an imported icon | #0a2e7a → #003082 |
| Export rounding | #003080 from a lossy tool | #003080 → #003082 |
| Shorthand vs full hex | #fff and #ffffff mixed | One pair (short hex is expanded first) |
| Third-party icon defaults | Vendor set ships #1f2937 | #1f2937 → <your token> |
What this tool is — and isn't
Set expectations before you start. The audit is upstream; the swap is the fix.
| Capability | Hex Swapper | Where it lives instead |
|---|---|---|
| List unique colours in a file | No | CSS Variable Injector (empty-map mode) |
| Cluster near-identical shades | No | Your own audit script |
| Snap a hex to a token value | Yes | — |
| Map a colour to nearest Tailwind class | No | SVG-to-Tailwind (palette mode) |
| Batch a whole folder | No (one file per run) | Runner-backed API loop |
Cookbook
Standardisation scenarios from real icon libraries. Tokens are illustrative.
Snap three near-miss blues to one token
Three icons each carry a slightly different 'brand blue'. Stack three pairs to converge them all on the token in one pass.
Off-brand values found in audit: #003084 (eyedropper) #003080 (export rounding) #0a2e7a (legacy rebrand) Pairs (all -> token #003082): #003084 -> #003082 #003080 -> #003082 #0a2e7a -> #003082 Result: every blue now equals the token exactly.
Normalise a third-party icon to your palette
A vendor icon ships with its own defaults. Map its colours to your tokens before adding it to the library.
Vendor icon: fill="#1f2937" (their dark) fill="#3b82f6" (their accent) Pairs: #1f2937 -> #111827 (your neutral token) #3b82f6 -> #003082 (your brand token) Now the icon matches the rest of your set.
Collapse shorthand and full hex together
Some icons use #fff, others #ffffff, for the same paper-white. Short hex is expanded first, so one pair handles both.
Mixed in the file: fill="#fff" stop-color="#ffffff" Pair: #ffffff -> #fafafa (token off-white) Both become #fafafa (the #fff was expanded internally). Colors swapped: 2
Verify the change count matches the audit
Use the 'Colors swapped' metric as a sanity check that you corrected exactly the number of instances you found.
Audit said: 4 fills use the off-brand #003084. Run pair #003084 -> #003082 Result: Colors swapped: 4 -> matches the audit. If it said 3, one instance is spelled differently (e.g. rgb form) — re-check the source.
A near-shade the swapper won't merge for you
The swapper never decides two shades are 'close enough'. You must explicitly map each one. This is a feature for a strict design system.
#003082 (token) and #003083 (one bit off) The swapper treats these as distinct strings. To merge: add an explicit pair #003083 -> #003082 There is no tolerance/cluster setting — by design.
Edge cases and what actually happens
Expecting the tool to find your colours
Not a featureThe Hex Swapper has no scan/list mode. It only replaces colours you name. Do the audit with your own tooling or the CSS Variable Injector's auto-detect, then feed the off-brand values in as from pairs.
Two shades one bit apart
Distinct#003082 and #003083 are different literal strings; the swapper never merges them on its own. There is no tolerance or clustering. Add an explicit pair for each off-brand shade you want corrected.
Off-brand value stored as rgb()
No matchIf a stray colour is written as rgb(0,48,132) rather than hex, a hex from won't catch it. Normalise the file to hex during export, or add a pair targeting the literal rgb string.
Token value appears in an id or class name
Watch the countBecause matching is text-based, a colour string could collide with a substring in an id, class, or <text> node. If 'Colors swapped' is higher than your audit count, inspect the source for an accidental match.
Library has hundreds of icons
Single-fileThe web tool processes one SVG per run. For a large library, script the runner-backed API to loop the directory with the same token-correction pairs.
Free-tier designer tries to run it
LockedThe tool requires Pro. A free account sees an upgrade overlay. Plan tier access for whoever owns the icon-standardisation task.
Pairs overlap and cascade
By designPairs run top-to-bottom. If you map #a → #b and then #b → #c, the first batch's results get re-swapped by the second. When converging many shades onto one token this is usually harmless, but order deliberately.
Need runtime token binding, not baked hex
Different goalIf tokens should update icons live (a token value change re-colours everything), bake nothing — use the CSS Variable Injector so colours reference var(--token). The swapper is for snapping files to a token at a point in time.
Frequently asked questions
Can the Hex Swapper tell me which colours my icons use?
No — it has no analysis or listing mode. Audit colours separately: an SVGO pass, a custom script, or the CSS Variable Injector's empty-map mode (which assigns --svg-color-N to each detected colour, exposing the palette). Then feed the off-brand values into the swapper as pairs.
Will it merge near-identical shades automatically?
No. There is no tolerance or clustering. #003082 and #003084 are distinct strings; you must add an explicit pair for each off-brand shade you want snapped to the token. This precision is intentional for a strict design system.
How do I fix several off-brand blues at once?
Stack a pair per stray value, all targeting the token: #003084 → #003082, #003080 → #003082, #0a2e7a → #003082. They apply in one pass. Check the 'Colors swapped' count against your audit to confirm coverage.
Does it catch both #fff and #ffffff?
Yes. Short hex is expanded to 6-digit across the document before matching, so a single pair for #ffffff also handles #fff.
What if an off-brand colour is written as rgb()?
A hex from won't match an rgb() string — the tool compares literal text and doesn't convert formats. Normalise the SVG to hex on export, or add a pair whose from is the exact rgb string.
How do I standardise a whole library, not one icon?
The web tool is one file per run. For a library, script the runner-backed Color Swap API: loop the directory, apply the same token-correction pairs to each file, and aggregate the swap counts into your own report.
How do I stop drift from coming back?
Add a CI lint that fails the build if any committed SVG contains a hex outside your approved token list. The swapper corrects existing files; the lint guards new commits. Together they keep the library on-brand.
Is the change safe to review in a PR?
Yes — it's the most reviewable kind of change. Only colour strings are rewritten; paths, IDs, and structure are untouched, so the diff shows exactly which hex values moved to the token.
What about third-party icon sets with their own colours?
Map their default colours to your tokens before adding them. For each vendor colour, add a pair to your token value. After the swap the imported icons match the rest of your set.
Can I instead map colours to Tailwind classes?
If your system is class-based, the SVG-to-Tailwind bridge can snap each colour to the nearest Tailwind palette class (palette mode) via CIE Lab distance — a different way to enforce a constrained palette.
Why is the swap count higher than the colours I targeted?
A literal colour string can collide with text elsewhere — inside an id, a class, or a <text> node. Inspect the source if the count exceeds your audit. Full 6-digit hex collisions are rare but possible.
Do my brand assets get uploaded?
No. Processing runs in your browser, or locally via the runner for scripted runs. Sensitive brand SVGs never reach a JAD server, which matters for unreleased rebrands.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.