Somewhere between my third ad popup and the seventh “premium feature” paywall, I hit that classic developer breaking point: if every SVG tool only does one thing I need, I’m going to end up doing all the things myself anyway. So I made a cup of coffee, opened a fresh repo, and said the words that have launched many side projects and a few regrettable weekends: I’ll just build my own.
What followed started as a tiny utility for editing paths and turned into a fast, shareable, developer‑friendly SVG path editor I actually use daily. Here’s how (and why) it came together.
My workflow got silly. One tab for path editing, another for optimization, a third for measurements—and still jumping into my editor to hand‑tweak curves. Each tool had strengths, but the rough edges (ads, feature gates, imprecision) slowed actual making. The moment I needed to quickly iterate on icons while understanding the underlying path structure, I realized I was spending more time switching tools than drawing.
I picked Next.js 14 with the App Router because it let me move fast without fighting the stack:
The component architecture stays clean and layered:
- Canvas layer: Pure SVG manipulation and rendering
- UI layer: shadcn/ui components built on Radix primitives
- State layer: React Context for global state management
- Utility layer: Pure functions for path calculations and transformations
Instead of pulling in Redux/Zustand out of habit, I used focused React contexts to keep concerns tight and renders cheap:
This split kept performance predictable and the codebase understandable. Each context owns a domain; components only subscribe to what they need.
SVG paths look simple—M 10,10 L 20,20 C 30,30 40,40 50,50
—until you start manipulating them programmatically. Then it’s coordinate transforms, curve math, winding rules, and many, many edge cases.
I built lib/path-utils.ts
to handle the heavy lifting:
The first feature that unlocked everything was shareable, state‑encoded URLs:
// Compress and encode state for sharing
const compressedData = LZString.compressToEncodedURIComponent(
JSON.stringify(pathsData)
);
const shareUrl = `${baseUrl}?share=${compressedData}`;
I could send someone a link and they’d see exactly what I saw—no uploads, accounts, or servers. Then it clicked: generate OpenGraph images from the actual SVG in the URL. Now links show a real preview of the work. It feels like magic the first time.
As I used it, I kept smoothing the places I personally felt friction:
For fun (and because prototyping should be fast), I tried generating paths from text using Grok via Vercel’s AI SDK:
// AI generates SVG path from text description
const result = await generateObject({
model: xai('grok-beta'),
prompt: `Generate an SVG path for: ${description}`,
schema: pathSchema,
});
It’s not a silver bullet, but for simple icons it’s a surprisingly good head start. “A simple house icon” becomes something you can tweak, instead of a blank canvas.
SVG manipulation can bog down fast, so I optimized early:
elementFromPoint
where it shines.Undo/redo can balloon memory if you’re careless. The history system uses:
Good tools respect momentum. Shortcuts make it feel fast:
Start simple, reveal power as needed:
It’s desktop‑first, but it holds up on tablets:
Deploys to Vercel with minimal ceremony:
The best features came from fixing my actual day‑to‑day annoyances. Needed complexity metrics? Built measurement. Wanted frictionless sharing? Encoded state in the URL. Scratching your own itch keeps scope honest.
Geometry and transforms without types is pain. Type safety caught bugs early and made refactors calm instead of scary.
State‑encoded URLs and dynamic OG images weren’t “net new” tech—just smart combinations. Great UX often comes from connecting existing pieces in a new way.
SVG performance debt compounds. A little care up front saved a lot of retrofits later.
Roadmap items I’m excited about:
This started as a weekend fix and became a tool I reach for constantly. It replaces a whole stack of single‑purpose apps and makes sharing dead simple. I’ve made it publicly available and free to use so other developers and designers can benefit in their own workflows—whether that’s the state management approach, the URL‑based sharing, or the dynamic OG image generation.
The source isn’t open right now. I may open‑source select parts in the future if there’s interest; in the meantime, feedback and feature requests are very welcome.
And yes, I use it regularly. There’s a special kind of satisfaction in shipping something that removes your own friction—and then discovering other people like it too.
Try it here: svg-editor.griffen.codes. It’s free to use. If you’ve been juggling three tools to get one SVG right, give it a spin—it might save you a few tabs (and maybe a few choice words).