Jedd Icons

Adding icons

Drop an SVG, add metadata, run one command.

Jedd Icons is built from source-of-truth SVGs in the repo. Adding an icon is easy and involves just three steps: drop the SVG, add metadata, run the build.

Drop the SVG

Save your file at icons/<variant>/<name>.svg using kebab-case, where <variant> is stroke or fill. Icons must fit inside a 24×24 viewBox and use strokes only (no fills on child elements). The canonical root attributes are:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
     fill="none" stroke="currentColor" stroke-width="2"
     stroke-linecap="butt" stroke-linejoin="miter">
  <!-- geometry only: <path>, <circle>, <rect>, <line>, <polygon>, <polyline> -->
</svg>

Child elements should contain geometry attributes only (d, cx, r, points, …) — not presentation attributes like stroke or fill. Those are set on the root <svg> and inherited at render time so the color and strokeWidth props work.

If your SVGs have inline presentation attributes on child elements (common with design-tool exports), pnpm icons:clean strips them automatically and normalizes the root attributes.

Design rules

  • Stay inside the 24×24 viewBox with ~1px padding on each side.
  • Stroke-only — no fill on child elements.
  • Keep geometry flat: no <g> groups, <defs>, or <mask>. The parser is intentionally simple.

Add metadata

Create icons/<variant>/<name>.json next to the SVG. The required fields are $schema, contributors, tags, and categories:

{
  "$schema": "../../icon.schema.json",
  "contributors": ["yourname"],
  "tags": ["search-keyword-1", "search-keyword-2"],
  "categories": ["shapes"]
}

The full set of fields lives in icon.schema.json at the repo root. Useful optional fields:

{
  "aliases": [{ "name": "older-name" }],
  "deprecated": true,
  "deprecationReason": "Use new-name instead"
}

categories is an enum — valid values are listed in icon.schema.json.

Build everything

pnpm icons

This single command runs the full pipeline:

  1. icons:clean — normalizes root <svg> attributes and strips inline presentation attributes from child elements.
  2. icons:check — checks the normalized SVGs and their metadata without changing them, and stops on problems such as transforms, dots too short for Safari, geometry outside the 1px margin, or metadata that doesn't match icon.schema.json.
  3. build — builds @jedd-icons/shared, generates the per-icon TS files, then builds @jedd-icons/core and @jedd-icons/react.
pnpm --filter www-docs dev

Open the gallery, search for your icon by name, and use the sliders to confirm the size / strokeWidth / color / absoluteStrokeWidth props behave.

Individual commands

CommandWhat it does
pnpm iconsFull pipeline: clean + check SVGs, then build all packages
pnpm icons:cleanNormalize source SVGs (strip inline attrs, set root defaults)
pnpm icons:checkCheck source SVGs without changing them; exits 1 on errors
pnpm buildBuild all packages via Turbo
pnpm --filter @jedd-icons/react genRegenerate icon TS files only
pnpm --filter @jedd-icons/react buildBuild the React package
pnpm --filter @jedd-icons/react devWatch & rebuild on changes
pnpm --filter www-docs devRun the gallery / docs site

Changesets

If your change touches a published package (@jedd-icons/react or @jedd-icons/core), add a changeset so it lands in the changelog:

pnpm changeset

Pick the package(s), choose a bump level, and write a one-line summary — that summary becomes the public changelog line. Docs-only, chore, and internal-package changes don't need one.

While the project is on 0.x, breaking changes ride on a minor bump: patch for fixes and new icons, minor for features or breaking changes, major reserved for 1.0.0.