sketchyicons

Packages

One geometry source, one package per target. Nothing is generated from Lucide twice, which is what keeps a glyph identical whichever package you install it from.

How they relate

The generator runs once, against a specific upstream release, and writes @sketchyicons/data. Everything else is a template over that file. A framework package never sees Lucide, and a bug fixed in the geometry is fixed everywhere at once.

the chain
lucide geometry
  └─ generator  (bow, drift, validate)
       └─ @sketchyicons/data        committed JSON, the source of truth
            ├─ @sketchyicons/static  svg files and a sprite
            ├─ @sketchyicons/react
            └─ @sketchyicons/react-native

@sketchyicons/data

The drawn geometry, one named export per glyph, 1500+ of them, in the same node shape Lucide uses. No framework, no dependency, no build step. Reach for it when you are rendering icons yourself: a canvas, a PDF, a server side image, a framework nobody has written a template for yet.

It is also the only package whose diff is worth reading. An upstream geometry bump shows up here as changed path strings and nowhere else, which is why it is committed rather than built.

data
import { Feather, iconNames } from "@sketchyicons/data";

// Feather -> [["path", { d: "M14.7 18.11A2 2 0 0 1 …" }], …]
// iconNames -> ["a-arrow-down", "a-arrow-up", …]

for (const [, { d }] of Feather) canvas.stroke(new Path2D(d));

@sketchyicons/static

One SVG file per glyph, plus a sprite. This is the one that makes the set usable outside JavaScript entirely: Flutter, SwiftUI, a Figma import, a Rails view, plain HTML.

  • icons/feather.svg for a single file, dropped in wherever you keep assets.
  • sprite.svg when you want one request and <use href="#feather" /> at the call site.

Both are generated from data, so a glyph is byte for byte the same whether you import the component, read the JSON or drop in the SVG.

Framework packages

One component per icon, generated, never written by hand. If changing one prop meant editing 1500+ files, the architecture would be wrong.

Published

  • @sketchyicons/reactpeers: react@^18 || ^19
  • @sketchyicons/react-nativepeers: react@^18 || ^19, react-native-svg@>=13
  • @sketchyicons/vuepeers: vue@^3
  • @sketchyicons/angularpeers: @angular/core@^21, @angular/common@^21
  • sketchyiconsno peer dependencies

Not yet

Each of these is a generation template over the same data rather than a design question, so adding one is a build step and not a rewrite.

  • @sketchyicons/svelteSvelte
  • @sketchyicons/solidSolid
  • sketchyiconsFlutter on pub.dev

What a version number means

  • An upstream geometry bump is at least a minor, never a patch. Nobody taking a patch upgrade expects their icons to change shape.
  • All packages are versioned together and released from one repository, so the numbers line up across targets.
  • Tags carry the package name, as in @sketchyicons/react@1.2.0. A bare v1.2.0 would be ambiguous across the set.
Install one