# @gromlab/svg-sprites
π¬π§ English | [π·πΊ Π ΡΡΡΠΊΠΈΠΉ](https://github.com/gromlab-ru/svg-sprites/blob/master/README_RU.md)
 
`@gromlab/svg-sprites` is a CLI tool for generating SVG sprites in modern web applications. It combines selected SVG icons into one or more external, cacheable sprites and prepares them for use in the UI.
Each exact mode generates a native typed component for its framework and bundler: Web Component, React, Vue, Svelte, Angular, Astro, Solid, Preact, Qwik, Lit, or Alpine.js. In every case, the SVG remains a separate cacheable asset.
## An SVG sprite as simple as a regular SVG icon
One typed React component is generated for the entire sprite. Choose an icon with the `icon` prop, and your editor will autocomplete every available name.
```tsx
```
The component accepts familiar SVG attributes: dimensions, `color`, `className`, `style`, `aria-*`, and event handlers. If you need an outer container, add `wrapped`.
```tsx
```
You do not have to work with the sprite directly in your application. Use it like a regular SVG icon while benefiting from a single component, autocomplete, and TypeScript validation for every name.
## AI-friendly out of the box
`@gromlab/svg-sprites` is designed to work with AI agents from the start. Add the ready-made skill and ask an agent to configure, migrate, or troubleshoot the package without lengthy instructions or manual documentation research.
[π¬π§ Download AI skill (English)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites.zip)
[π·πΊ Download AI skill (Russian)](https://github.com/gromlab-ru/svg-sprites/releases/latest/download/svg-sprites-ru.zip)
## From SVG to component in three steps
The main example uses the Next.js App Router and Turbopack.
### 1. Specify the icons you need
Create directories for the source icons and the sprite:
```text
assets/
βββ app-icons/
β βββ svg-sprite.config.json
βββ svg-icons/
βββ search.svg
βββ settings.svg
```
Create the sprite configuration:
```json
{
"mode": "next@app/turbopack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
`input` supports directory paths, individual SVG files, and glob patterns.
### 2. Add a generation script
```json
{
"scripts": {
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"prebuild": "npm run sprites"
}
}
```
Create an entry point for the generated API:
```ts
// assets/app-icons/index.ts
export * from './.svg-sprite/index.js'
```
First run:
```bash
npm run sprites
```
The package will generate `AppIcon`, TypeScript types, and a separate SVG sprite.
### 3. Use it like a regular icon
```tsx
// app/page.tsx
import { AppIcon } from '../assets/app-icons'
export default function SearchButton() {
return (
)
}
```
This is a Server Component. The icon does not require a provider, `'use client'`, or manual URL construction.
## Typed React component with autocomplete
Each sprite gets its own ready-to-use component. The `icon` prop is derived from the actual SVG names, so your editor shows the exact list of available icons and TypeScript catches typos immediately.
```tsx
// available icon
// TypeScript error
```
After you add a new SVG icon and run generation again, its name automatically appears in the types and autocomplete. There is no need to maintain components, union types, or a name registry manually.
## Next.js App Router and SSR out of the box
Generated components work in Server Components, SSR, and SSG without `'use client'`.
Using an icon does not turn the page into a Client Component, require a provider, or create an additional hydration boundary.
The same component can be used in `page.tsx`, `layout.tsx`, and both server and client components.
## Multiple sprites instead of one global sprite
Your project is not limited to a single icon set. Create independent sprites for shared elements, individual pages, and large UI modules.
```tsx
```
Each set gets its own typed component and SVG asset, so application sections do not load icons they do not need.
## Store each icon only once
Each SVG icon is stored once in the source library and can be included in any number of sprites. Shared icons do not need to be copied between pages and modules: a single source updates every set.
```text
search.svg ββ¬ββ AppIcon
βββ AnalyticsIcon
βββ EditorIcon
```
Sprites are split for performance, while the source icon library remains unified.
## Browser caching
With a standard Vite, Webpack, or Next.js configuration, each sprite is emitted as a separate versioned SVG file.
As long as the icon set does not change, the browser can reuse its cached copy independently of JavaScript application updates.
Changes to React components do not require downloading the geometry of every icon again.
## JavaScript without SVG bloat
Icon paths remain in external SVG assets and do not add to application chunks.
```text
React code β JavaScript chunks
SVG icons β separate SVG assets
```
JavaScript handles the interface and behavior, while graphics are loaded and cached separately.
## Built-in SVG transformations
During generation, the package automatically prepares source SVG files for use in the UI:
- removes fixed `width` and `height` attributes;
- preserves the existing `viewBox`;
- converts `fill` and `stroke` values to CSS variables;
- adds smooth transitions directly to colored icon elements.
Each transformation can be configured or disabled independently.
## Control every color with CSS
During generation, `fill` and `stroke` colors are automatically converted to `--icon-color-N` CSS variables.
A monochrome icon inherits `currentColor`:
```tsx
```
For a multicolor icon, each color can be changed independently:
```tsx
```
Create themes, states, and hover effects without editing the SVG or making additional copies of the icon.
## SpriteViewer: every sprite on one debug page
`SpriteViewer` renders sprites from every supported exact mode in one place. One Web Component owns the visuals, while React also provides a thin bridge to it.
For each icon, you can see the generated CSS variables and their fallback colors. Change the values directly in the Viewer and see the result immediately.
It also provides ready-to-use examples for the manifest's framework, `