IcoMoon SVG sprites: export, anatomy and the <use> element
You do not have to generate a font at all. The same selection you would feed the font
generator can leave the IcoMoon app as a single SVG sprite: select your icons, open the
Generate SVG & More tab, hit Download, and the zip contains
symbol-defs.svg — one file where every icon is a
reusable <symbol>. Any page that inlines or
links that file can render any icon with a three-line
<use> snippet. Below: what the export actually
contains, how the sprite is structured, the browser caveats, and an honest answer to the
sprite-or-font question.
Exporting SVG from the app instead of a font
In the app, build your
selection exactly as you would for a font — the
app tutorial covers importing
and selecting. Then, instead of Generate Font, switch to the Generate SVG & More tab in
the bottom bar. The Preferences dialog on that screen controls the
icon- id prefix and lets you toggle extras like PNG
renders. Download gives you a zip whose two files matter here:
symbol-defs.svg (the sprite) and
demo.html (open it to verify every symbol before you
touch your codebase). Keep selection.json from the
same zip — re-importing it later restores names and settings, so you can regenerate the
sprite or even switch to a font export from the identical selection.
Anatomy of symbol-defs.svg
The sprite is nothing exotic — a hidden outer
<svg> wrapping a
<defs> block of symbols:
<svg aria-hidden="true"
style="position:absolute; width:0; height:0; overflow:hidden">
<defs>
<symbol id="icon-home" viewBox="0 0 32 32">
<path d="M32 19 16 6 0 19v-5L16 1l16 13z"/>
<path d="M28 18v13h-8v-9h-8v9H4V18l12-10z"/>
</symbol>
<symbol id="icon-pencil" viewBox="0 0 32 32">
<path d="M27 0a5 5 0 0 1 4 8l-2 2-7-7 2-2a5 5 0 0 1 3-1z"/>
</symbol>
<!-- one <symbol> per icon you selected -->
</defs>
</svg>
Three details are load-bearing. First, each
<symbol> carries its own
viewBox, so icons scale independently no matter what
size box you draw them into. Second, symbols render nothing by themselves — that is what
makes the file safe to inline at the top of
<body> without visual side effects. Third, the
id attribute is the entire public API: rename ids in
the app before exporting, because every consumer references them literally. The paths for
the free set are the same ones published in the
IcoMoon-Free repository
(© Keyamoon, GPL / CC BY 4.0).
Rendering icons with <use>
There are two reference styles, and the difference matters more than it looks:
<!-- A: sprite inlined at the top of <body> — reference by id -->
<svg class="icon" width="24" height="24" aria-hidden="true" focusable="false">
<use href="#icon-home"></use>
</svg>
<!-- B: sprite kept as a file — same-origin only -->
<svg class="icon" width="24" height="24" role="img" aria-label="Home">
<use href="symbol-defs.svg#icon-home"></use>
</svg> Variant A (inlined sprite, fragment-only reference) is the bulletproof option: no extra request, no origin rules, works in every browser that renders SVG. Variant B keeps your HTML clean and lets the sprite cache across pages. Either way, size and color come from ordinary CSS:
.icon {
width: 1em; /* scales with surrounding text */
height: 1em;
fill: currentColor; /* inherits the text color */
vertical-align: -0.125em; /* optical baseline alignment */
} Cross-browser notes
The big one: <use> will not load external
references across origins — pointing it at a sprite on a different domain or CDN fails
silently, with no console error in most browsers. Serve the file same-origin or inline it.
IE 11 does not support external references at all; if you still support it, the
svg4everybody polyfill rewrites variant B into inline content. And while the modern
href attribute works in all evergreen browsers,
WebKit builds from before roughly 2018 only understood
xlink:href — adding both attributes is a harmless
belt-and-braces move if your analytics show old Safari traffic.
Icon font vs SVG sprite: the honest comparison
Both exports come from the same selection, so this is purely a delivery-format decision:
| Criterion | Icon font | SVG sprite |
|---|---|---|
| Color | One color per icon, set via CSS color | Multicolor paths preserved; currentColor still works for single-tone |
| Rendering | Drawn as text — font smoothing can blur glyphs at odd sizes | True vector rendering, crisp at every size |
| Accessibility | Private Use Area characters are meaningless to screen readers; needs aria-hidden plus hidden text | Plain markup: role and aria-label go straight on the svg element |
| Payload | All 491 free glyphs travel together — 49 KB as WOFF2 | Only the symbols you exported ship; unused icons never leave the app |
| Failure mode | A 404 on the font file means blank squares everywhere | A missing symbol renders empty but keeps its layout box |
| Legacy browsers | Works wherever @font-face works, including old IE | External references need the svg4everybody polyfill in IE 11 |
| Markup weight | One short CSS class per icon | Three to four lines of SVG per placement |
Which one should you pick?
For a new project in 2026, default to the sprite: better accessibility, sharper rendering,
multicolor support, and you ship only the symbols you use instead of the whole set. Pick
the font when you are feeding an existing pipeline built on icon classes, when the terser
markup genuinely matters, or when legacy browser support is non-negotiable — the
pseudo-element techniques in our CSS guide
only apply to the font route. Because
selection.json round-trips through the app, the
choice is reversible in minutes, not a rewrite. If you just want the complete free set
without running the generator, the
download page has every format
pre-built, and the official
documentation covers
the generator's remaining export options.
Sprites reward icons that were drawn as real vectors. The Ultimate pack — $59 one-time, 1,500+ icons — ships the original SVG sources, so everything on this page applies to it unchanged; the pricing breakdown compares it against the subscriptions.