Swoozh Icons
A library of 1,773 icons for fashion and e-commerce. Every icon has two styles, outline and filled, drawn on a 24 px grid with a 1.5 px line. All formats are generated from the same SVG source, so an icon looks the same everywhere.
| Package | Use it for |
|---|---|
@swoozh/icons | SVG files, sprites, path data and icons.json metadata |
@swoozh/icons-react | React components |
@swoozh/icons-vue | Vue 3 components |
@swoozh/icons-svelte | Svelte component plus icon data |
@swoozh/icons-element | <swoozh-icon> custom element, any framework or none |
@swoozh/icons-font | Icon font (WOFF2, TTF) with CSS classes |
swoozh/icons (Elm) | Elm SVG functions |
Icon names are kebab-case, like shopping-bag or wash-30. In JavaScript they become PascalCase (ShoppingBag, Wash30) and in Elm camelCase (shoppingBag).
Search all names on the icon library.
SVG files
Every icon is a single path filled with currentColor, so it takes the text color of its parent.
npm install @swoozh/icons
node_modules/@swoozh/icons/dist/svg/outline/shopping-bag.svg
node_modules/@swoozh/icons/dist/svg/filled/shopping-bag.svg
Paste the markup inline, or use it as an image (an image cannot inherit the text color):
<img src="svg/outline/shopping-bag.svg" width="24" height="24" alt="Shopping bag">
SVG sprite
One file per style holds every icon as a <symbol>. Reference an icon by name with <use>.
<svg width="24" height="24" aria-hidden="true">
<use href="/sprite-outline.svg#shopping-bag"/>
</svg>
React
npm install @swoozh/icons-react
import { ShoppingBag, Hanger } from '@swoozh/icons-react';
export function CartButton() {
return (
<button>
<ShoppingBag size={20} />
<Hanger variant="filled" color="#5b3df5" title="Wardrobe" />
</button>
);
}
| Prop | Default | |
|---|---|---|
variant | "outline" | "outline" or "filled" |
size | 24 | Width and height, number or CSS length |
color | "currentColor" | Fill color |
title | Accessible name. Without it the icon is aria-hidden |
Any other prop (className, style, onClick, …) goes to the <svg>, and refs are forwarded.
Each icon is a separate named export, so bundlers only include the icons you import.
Vue
npm install @swoozh/icons-vue
<script setup>
import { ShoppingBag } from '@swoozh/icons-vue';
</script>
<template>
<ShoppingBag variant="filled" :size="20" class="cart-icon" />
</template>
Same props as React: variant, size, color and title.
Svelte
npm install @swoozh/icons-svelte
<script>
import { Icon, ShoppingBag } from '@swoozh/icons-svelte';
</script>
<Icon icon={ShoppingBag} variant="filled" size={20} />
Works with Svelte 4 and 5. The icon data exports are tree-shakeable.
Web component
One script registers <swoozh-icon>. It works in plain HTML and in any framework. The script contains every icon, so use it when convenience matters more than bundle size.
<script type="module" src="node_modules/@swoozh/icons-element/dist/swoozh-icon.js"></script>
<swoozh-icon name="shopping-bag"></swoozh-icon>
<swoozh-icon name="hanger" variant="filled" size="32" label="Wardrobe"></swoozh-icon>
Attributes: name, variant (outline or filled), size (default 24) and label (accessible name). The color follows color in CSS.
Elm
elm install swoozh/icons
import SwoozhIcons exposing (Variant(..))
import Svg.Attributes as A
view =
SwoozhIcons.shoppingBag Filled [ A.width "32", A.height "32", A.class "cart-icon" ]
Every icon has the type Variant -> List (Svg.Attribute msg) -> Svg msg. Attributes you pass override the defaults (24×24, currentColor).
Icon font
npm install @swoozh/icons-font
<link rel="stylesheet" href="node_modules/@swoozh/icons-font/dist/swoozh-icons.css">
<i class="swz swz-shopping-bag"></i>
<i class="swz swz-filled swz-hanger"></i>
There are two font families: Swoozh Icons for outline and Swoozh Icons Filled for filled. Both use the same code points from U+E000 upward, and the code points never change between releases
(see codepoints.json). Set the size with font-size. A size that is a multiple of 24 px keeps the lines sharpest.
Plain JavaScript
import { ShoppingBag, toSvg } from '@swoozh/icons';
ShoppingBag.outline // SVG path data
document.querySelector('#cart').innerHTML = toSvg(ShoppingBag, { variant: 'filled', size: 20 });
@swoozh/icons/icons.json lists every icon with its category and search tags, which helps if you build your own icon picker.
Accessibility
- Decorative icons are rendered with
aria-hidden="true", which is the default everywhere. - For icons that carry meaning on their own, such as an icon-only button, pass
title(React, Vue, Svelte, JavaScript) orlabel(web component), or give the button anaria-label. - Icon fonts are read by some screen readers. Keep the
<i>empty and addaria-hidden="true"when the icon is decorative.
Design guidelines
| Grid | 24 × 24 px, with live area 2.75–21.25 px |
| Line | 1.5 px, butt caps, miter joins |
| Styles | Outline (line) and Filled (solid with knock-outs) |
| Badges | Many icons have corner variants (-plus, -check, -heart, -return, …) for states like add, done or favourite |
| Sizes | Sharpest at 24, 48 and 72 px. 16 and 20 px also work for UI. |
The source of truth is the SwoozhIcons Figma library. The packages ship strokes converted to filled outlines, so stroke width cannot be changed with CSS. Every format renders identically, from the SVG files to the font.
Building from source
npm install
npm run export # Figma → icons/{outline,filled}/*.svg, icons.json, codepoints.json (needs the Figma bridge)
npm run build # icons/ → packages/*/dist, packages/elm/src, site/data
The icons/ folder is checked in, so npm run build works without Figma. Code points are stored in icons/codepoints.json and only grow, so font users never see an icon change places.