See what your eye sees.
A side project that visualises the gap between geometric and optical centre — and helps designers ship icon sets that actually feel balanced.
Context
I work with icon sets constantly. Drawing them, picking them, swapping them out. And the same annoyance kept coming back: you centre an icon in its frame, it's mathematically dead-on, and it still looks off. So you nudge it a pixel or two until it feels right. Fine for one icon. Completely unsustainable across a whole library.
IconAlign came out of wanting to quantify that feeling. Just show me, on screen, where the geometric centre is versus where my eye thinks the weight lives.
The problem
You centre an icon in its box and it still looks wrong. A triangle pulls right, a play button sits low, anything asymmetric just drifts. Everyone nudges by feel, every time, with no common baseline.
Do that across 60 icons and the whole set starts looking sloppy. And good luck catching it in a code review. There's no line to point at, just a nagging feeling that things are off.
Role
Design + build (solo)
Timeline
Weekend project, ongoing
Stack
React · TypeScript · Canvas API · client-side image analysis
Live site
iconalign.comResearch & insights
I dug into a few icon sets I trust (Phosphor, Lucide, SF Symbols) and measured where the visual mass actually sits relative to the bounding box. A few patterns stood out:
Mass beats geometry
The good sets consistently offset asymmetric icons by 2–6% from their bounding box centre. It's deliberate, not accidental.
It's a set-level problem
One slightly off icon? Nobody notices. Five in a row in a toolbar? That's what makes a UI feel cheap.
Nothing existed for this
Tons of articles about optical balance. Not a single in-browser tool that would just tell you the answer for your specific icon.
Design decisions
The whole thing is built around one idea: answer the question before the designer finishes asking it.
One canvas, two dots. You drop an icon in, you see both centres overlaid. That's it. No panels, no settings drawer, no onboarding tooltip. The visual is the answer.
Two modes because there are two questions. "Is this icon balanced?" and "Does this set feel consistent?" Single mode and Compare mode. Same analysis engine underneath so the numbers stay coherent.
Everything stays in the browser. Most icons people want to check are unreleased work. Even a "private" server upload is enough friction to kill the impulse. No account, no upload, no privacy policy to squint at.
Suggest, don't override. The tool shows you a recommended offset. It never applies it for you. Optical balance is still a judgement call. I just wanted to make the judgement faster.
Technical approach
The "optical centre" is basically the centre of mass of whatever pixels are actually visible, weighted by how opaque and how bright they are. The implementation is pretty straightforward:
1. Drop it in
PNG or SVG onto the canvas. Everything from here happens locally. Nothing leaves your machine.
2. Crunch the pixels
Rasterise at high res, walk every pixel, weight by alpha × luminance, average out to find the optical centre. Geometric centre comes from the trimmed bounding box.
3. See the answer
Both centres rendered right on the icon. You get a pixel-nudge suggestion and can export a re-anchored version if you want it.
Compare set mode
Once single-icon mode worked, the natural follow-up was: what about a whole set? Compare mode lets you drop in multiple icons, pick one as your reference, and see everything else re-anchored to match it. Letting you choose the reference ended up being the crucial piece. Without it, "matched" doesn't mean anything.
1. Drop in your set
Throw in the icons you want to compare, including whichever one you want as the baseline.
2. Pick your reference
Tap the icon whose weight and footprint the rest should match.
3. See the matched set
Toggle the matched view to preview everything aligned to your reference, then download the adjusted files.
Why this matters
When optical balance is right, nobody notices. When it's wrong, the whole UI feels off. A fast visual answer turns 'I think this looks weird' into an actual decision, and a 60-icon set into something that feels intentional.
Challenges
SVGs lie. A surprising number of icon SVGs have dead whitespace baked into the viewBox. That made bounding-box calculations useless until I added a trim step. Honestly, that one fix improved accuracy more than tweaking the weighting formula did.
Stroke vs fill. Outline icons and filled icons read totally differently to the eye. Running them both through the same formula gave confident but wrong results for strokes. Switching to alpha-only weighting for those fixed it.
Trust requires proof. Two dots on an icon wasn't enough. People wanted to see the offset in actual pixels plus a preview of the corrected version before they'd believe it. That feedback ended up shaping the whole export flow.
Outcome
It's live, it's free, there's no login. Two modes, one screen, one drop zone. You get your answer in seconds.
0
Accounts required
100%
Runs in-browser
2
Modes shipped
<5s
Upload to answer
What I learned
It's way easier to defend a visual call when you can point at something. Half my design feedback used to be "this feels off." Now I can point at a specific pixel offset. Better conversation.
Saying no to features is what makes side projects ship. No account, no settings, no roadmap. Every "should I add…" got a "no, it's done." That's the only reason it's actually live.
Small and specific beats broad and flexible. Nobody wanted a design system plugin. They wanted to know if their icon was crooked. Building for exactly that one question made the whole thing work.
Made by Jenny Zhang