Turn a folder of SVG files into type-safe, cacheable SVG sprites.
Zero client JavaScript, deterministic output, and adapters for Next.js Server Components, Astro, Vue and Svelte.
const home = <Icon name="home" />; // <svg><use href="/icons/icons.f84bac71.svg#i-home"/></svg>
const nope = <Icon name="nope" />; // type error: "nope" is not an icon name- Icons that render right, with no config. Each icon is mono (follows
currentColor) or multicolor (keeps its colors). Gradients, masks and filters render in Chromium, Firefox and WebKit. - Zero client JS. The browser fetches one hashed sprite and caches it.
- Type-safe names. A wrong icon name fails
tsc. - No bundler plugin required. It is a CLI that writes files, so it works with Turbopack, webpack and Vite. Vite users can add the optional
svgworm/viteplugin to rebuild icons insidevite dev. - Deterministic. The same input gives byte-identical output on every OS.
Requires Node ^22.20 || >=24.11, and React 19 for @svgworm/react. The example uses Next.js App Router.
1. Install and set up
pnpm add -D svgworm && pnpm add @svgworm/react && pnpm svgworm init
# npm: npm install -D svgworm && npm install @svgworm/react && npx svgworm initinit asks a few questions (or takes --yes), writes svgworm.config.json, adds predev and prebuild scripts, and creates components/icon.tsx (src/components/icon.tsx when src/ exists). When icons/ is missing or empty, it adds a sample icons/svgworm.svg. Then it builds once, so the app runs and type-checks before you add an icon.
2. Add your icons and build
Put SVG files in icons/ (delete the sample) and run pnpm svgworm (or npx svgworm). The build prints what it did (abridged):
svgworm: build done
icons 8 (5 mono, 3 multicolor)
delivery use 6, img 2, mask 0
output 3.5 KiB (sprite 2.2 KiB, stack 1.3 KiB)
time 15 ms
3. Use the component in any Server Component
import { Icon } from '@/components/icon';
export const Nav = () => (
<nav>
<Icon name="home" />
<Icon name="home" title="Go home" width={32} height={32} />
</nav>
);Tip
Names come from the file paths: home is icons/home.svg, lower-cased with - between words, and a wrong name is a type error. The icon is aria-hidden unless you pass title or label.
Commit public/icons/ and svgworm/ and run svgworm check in CI, or ignore both folders and rely on the predev/prebuild scripts. The Next.js guide weighs the two.
Also works with Astro, Vue (Nuxt) and Svelte (SvelteKit): svgworm init detects them and writes a React-free Icon.astro, Icon.vue or Icon.svelte, see the Astro, Vue and Svelte guides. Doing it by hand, long-term caching, and basePath are in the Next.js guide. A complete app, built with Turbopack and checked for zero client JS in CI, is in examples/next-app-router.
| If you... | Use |
|---|---|
| Have your own icon folder in a Next.js App Router app | svgworm |
| Want one tree-shaken component per icon and accept the JS cost | SVGR |
| Need several sprites or a webpack plugin today | @neodx/svg |
| Use Vite and all your icons are single-color | vite-plugin-icons-spritesheet |
The full comparison has spike numbers and says where each tool is the better choice.
- Next.js guide: manual setup, caching for a year,
basePath - Astro guide: the generated
Icon.astro, caching,base - Vite guide: Vite + React, the optional
svgworm/viteplugin,base, caching, examples/vite-react - Vue guide: the generated
Icon.vuefor Vue and Nuxt,base - Svelte guide: the generated
Icon.sveltefor Svelte and SvelteKit (static/),paths.base - Icon component: props, the markup per delivery, sizing and coloring
- How it works: sprite, stack, delivery forms, manifest, determinism
- ⌨️ CLI: commands, flags, exit codes,
checkin CI,watch - Config:
svgworm.config.jsonand its JSON Schema - Output contract: exact shape of the generated files
- Comparison: SVGR, @neodx/svg and others, with the numbers behind each claim
- Migrate from SVGR:
npx svgworm migrate svgrrewrites the imports into<Icon name="…" /> - Troubleshooting: blank icons, 404s, wrong colors, collisions, every diagnostic code
Read llms.txt. Everything is non-interactive: flags, --json, stable exit codes, and a JSON Schema for the config. The agent skill walks an agent through setting svgworm up in a Next.js app and fixing each error code:
npx skills add jmlweb/svgworm --skill svgworm-nextjsFor an Astro site, use --skill svgworm-astro.
Note
0.x, on npm since 2026-10-13. Before 1.0 the output contract and flags can still change in a minor version; each change is in the changelog.
Issues and pull requests are welcome. Start with CONTRIBUTING.md and AGENTS.md. Background lives in docs/vision.md and the ADRs.