- v0.0.103-integrationLatest
- v0.0.102
- v0.0.102-integration
- v0.0.101
- v0.0.101-integration
- v0.0.101-productionalize
- v0.0.97
- v0.0.97-integration
- v0.0.98-productionalize
- v0.0.97-productionalize
- v0.0.96
- v0.0.96-integration
- v0.0.95
- v0.0.95-integration
- v0.0.94
- v0.0.94-integration
- v0.0.93
- v0.0.93-integration
- v0.0.92-integration
- v0.0.92
- v0.0.91
- v0.0.91-integration
- v0.0.90-integration
- v0.0.90
- v0.0.89
- v0.0.89-integration
- v0.0.88
- v0.0.88-integration
- v0.0.86
- v0.0.86-integration
- v0.0.85-integration
- v0.0.85
- v0.0.84
- v0.0.84-integration
- v0.0.83
- v0.0.83-integration
- v0.0.82
- v0.0.81
- v0.0.81-integration
- v0.0.80
- v0.0.80-integration
- v0.0.79
- v0.0.79-integration
- v0.0.78
- v0.0.78-integration
- v0.0.77
- v0.0.77-integration
- v0.0.76
- v0.0.76-integration
- v0.0.75
- v0.0.75-integration
- v0.0.74
- v0.0.74-integration
- v0.0.73
- v0.0.73-integration
- v0.0.72-integration
- v0.0.68
- v0.0.68-integration
- v0.0.67
- v0.0.67-integration
- v0.0.66
- v0.0.66-integration
- v0.0.65
- v0.0.65-integration
- v0.0.64
- v0.0.64-integration
- v0.0.63
- v0.0.63-integration
- v0.0.62
- v0.0.62-integration
- v0.0.61-integration
- v0.0.59
- v0.0.59-integration
- v0.0.58
- v0.0.58-integration
- v0.0.57
- v0.0.57-integration
- v0.0.48-integration
- v0.0.55
- v0.0.47-integration
- v0.0.53
- v0.0.46-integration
- v0.0.51
- v0.0.45-integration
- v0.0.49
- v0.0.44-integration
- v0.0.44
- v0.0.41-integration
- v0.0.42
- v0.0.40-integration
- v0.0.39
- v0.0.39-integration
- v0.0.38
- v0.0.38-integration
- v0.0.37
- v0.0.37-integration
- v0.0.36-integration
- v0.0.35
- v0.0.35-integration
- v0.0.34
- v0.0.34-integration
- v0.0.33
- v0.0.33-integration
- v0.0.32
- v0.0.32-integration
- v0.0.31
- v0.0.31-integration
- v0.0.30
- v0.0.30-integration
- v0.0.28
- v0.0.28-integration
- v0.0.27
- v0.0.27-integration
- v0.0.26
- v0.0.26-integration
- v0.0.25
- v0.0.25-integration
- v0.0.24
- v0.0.24-integration
- v0.0.23-integration
- v0.0.21-integration
- v0.0.19
- v0.0.19-integration
- v0.0.18
- v0.0.18-integration
- v0.0.17
- v0.0.17-integration
- v0.0.16
- v0.0.16-integration
- v0.0.15
- v0.0.15-integration
- v0.0.14
- v0.0.14-integration
- v0.0.13-integration
- v0.0.13
- v0.0.10-integration
- v0.0.11
- v0.0.9-integration
- v0.0.9
- v0.0.8
- v0.0.8-integration
- v0.0.7-integration
- v0.0.6-integration
- v0.0.5-integration
- v0.0.4-integration26
- v0.0.4
- v0.0.3-integration40
- v0.0.3-integration39
- v0.0.3-integration38
- v0.0.3-integration37
- v0.0.3-integration35
- v0.0.3-integration34
- v0.0.3-integration33
- v0.0.3-integration32
- v0.0.3-integration31
- v0.0.3-integration30
- v0.0.3-integration29
- v0.0.3-integration28
- v0.0.3-integration27
- v0.0.3-integration26
- v0.0.3-integration25
- v0.0.3-integration24
- v0.0.3-integration23
- v0.0.3-integration22
- v0.0.3-integration21
- v0.0.3-integration20
- v0.0.3-integration19
- v0.0.3-integration18
- v0.0.3-integration17
- v0.0.3-integration16
- v0.0.3-integration15
- v0.0.3
- v0.0.3-integration14
- v0.0.3-integration13
- v0.0.3-integration12
- v0.0.3-integration11
- v0.0.3-integration10
- v0.0.3-integration9
- v0.0.3-integration8
- v0.0.3-integration1
- v0.0.3-integration0
- v0.0.2-integration0
- v0.0.1
- v0.0.2
- v0.0.1-integration64
- v0.0.1-integration63
- v0.0.1-integration62
- v0.0.1-integration60
- v0.0.1-integration59
- v0.0.1-integration58
- v0.0.1-integration57
- v0.0.1-integration56
- v0.0.1-integration55
- v0.0.1-integration51
- v0.0.1-integration50
- v0.0.1-integration49
- v0.0.1-integration48
- v0.0.1-integration47
- v0.0.1-integration46
- v0.0.1-integration45
- v0.0.1-integration44
- v0.0.1-integration43
- v0.0.1-integration42
- v0.0.1-integration41
- v0.0.1-integration39
- v0.0.1-integration38
- v0.0.1-integration37
- v0.0.1-integration36
- v0.0.1-integration35
- v0.0.1-integration34
- v0.0.1-integration33
- v0.0.1-integration32
- v0.0.1-integration31
- v0.0.1-integration30
- v0.0.1-integration29
- v0.0.1-integration28
- v0.0.1-integration27
- v0.0.1-integration26
- v0.0.1-integration25
- v0.0.1-integration24
- v0.0.1-integration23
- v0.0.1-integration22
- v0.0.1-integration21
- v0.0.1-integration20
- v0.0.1-integration19
- v0.0.1-integration18
- v0.0.1-integration17
- v0.0.1-integration16
- v0.0.1-integration15
- v0.0.1-integration14
- v0.0.1-integration13
- v0.0.1-integration12
- v0.0.1-integration11
- v0.0.1-integration10
- v0.0.1-integration9
- v0.0.1-integration8
- v0.0.1-integration7
- v0.0.1-integration6
- v0.0.1-integration4
Fathym Atomic Icons
Build, optimize, and consume SVG icon sprite sheets with ergonomic, typed icon components for Deno projects. Works standalone or alongside Fathym’s Everything‑as‑Code (EaC) runtime.
Install
Add imports to your deno.json or deno.jsonc using JSR. Pin a version for stability.
{
"imports": {
"@fathym/atomic-icons": "jsr:@fathym/atomic-icons@^0.0.0",
"@fathym/atomic-icons/browser": "jsr:@fathym/atomic-icons/browser@^0.0.0"
}
}Note: You can also use the deno.land URL if preferred, but JSR is recommended for resolution and versioning.
Naming Icons
Prefer semantic names decoupled from the upstream set. For example, map material-symbols:check-circle to check-circle. This keeps usage consistent across the app and makes future set swaps painless.
Quick Start
- Create a config describing your icon set and generation options.
// ./fathym-atomic-icons.config.ts
import { IconSetConfig, IconSetGenerateConfig } from "@fathym/atomic-icons";
export const curIconSetConfig: IconSetConfig = {
IconMap: {
"x-circle": "https://api.iconify.design/bi:x-circle.svg",
"check-circle": "https://api.iconify.design/material-symbols:check-circle.svg",
"exclaim": "https://api.iconify.design/bi:exclamation-circle.svg",
},
Optimize: true, // run SVGO on the generated sheet
};
export const curIconSetGenerateConfig: IconSetGenerateConfig = {
// When true, write typed <XxxIcon /> wrappers and add an import alias.
Exports: true,
// Optional: where generated files go (defaults to ./build/iconset)
// OutputDirectory: "./build/iconset",
IconSet: curIconSetConfig,
// URL path where the sheet is available (static or served).
SpriteSheet: "/iconset/icons",
};- Generate assets via a script and Deno task.
// ./scripts/icons.atomic.ts
import { useFileIconSet, useIconSetComponents } from "@fathym/atomic-icons";
import { curIconSetConfig, curIconSetGenerateConfig } from "../fathym-atomic-icons.config.ts";
// Generate a physical sheet. Adjust the path for your static files setup.
await useFileIconSet("./static/icons.sprite.svg", curIconSetConfig);
// Generate typed components + add a Deno import alias for easy consumption.
await useIconSetComponents(curIconSetGenerateConfig, "");// deno.jsonc
{
"tasks": {
"icons": "deno run -A ./scripts/icons.atomic.ts"
}
}Run: deno task icons
Add build/ to your .gitignore.
- Use your icons.
// Option A: Use the low-level <Icon /> with your sheet
import { Icon } from "@fathym/atomic-icons/browser";
export default function Page() {
return (
<>
<Icon src="/iconset/icons" icon="x-circle" />
<Icon src="/iconset/icons" icon="check-circle" class="text-blue-500 w-[50px] h-[50px]" />
</>
);
}// Option B: Use generated components (added under the alias below)
import { CheckCircleIcon, ExclaimIcon, XCircleIcon } from "$fathym/atomic-icons";
export default function Page() {
return (
<>
<XCircleIcon />
<CheckCircleIcon class="text-purple-500 w-[50px] h-[50px]" />
<ExclaimIcon class="text-purple-500 w-[24px] h-[24px]" />
</>
);
}When Exports is true, useIconSetComponents writes an import alias to your deno.json(c):
{
"imports": {
"$fathym/atomic-icons": "./build/iconset/icons/.exports.ts"
}
}Serving the Sprite Sheet
- Static: Commit or copy the generated
./static/icons.sprite.svgand reference it via<Icon src="/icons.sprite.svg" ... />. - EaC runtime: This package also provides an EaC processor/handler that can serve the sheet dynamically at the
SpriteSheetpath. If you are using Fathym’s runtime, wire upEaCAtomicIconsProcessorwith yourIconSetconfig and route pattern. (See thesrc/pluginfolder for details.)
Icon Sources
Any SVG can go into the sprite sheet. Good sources:
- Icônes: https://icones.js.org/
- Simple Icons: https://simpleicons.org/
- Flowbite Icons: https://flowbite.com/icons
API Reference (quick)
IconSetConfig:{ IconMap: Record<string, string | URL>; Optimize?: boolean }useFileIconSet(outputPath, config): Renders and writes an SVG sheet, runs SVGO whenOptimizeis true.IconSetGenerateConfig:{ IconSet, SpriteSheet, Exports?, Imports?, OutputDirectory?, Generate? }useIconSetComponents(config, root): Generates typed icon components and (optionally) adds an import alias to your Deno config.rootshould be the path prefix used when resolvingSpriteSheet(often""for absolute paths).- Browser exports:
@fathym/atomic-icons/browserexposes{ Icon, type IconProps, type JSX }.
Tips
- Keep names semantic and stable (
check-circle,x-circle, etc.). - Pin package versions in
deno.json(c)for reproducible builds. - If you change
SpriteSheet, re-run theiconstask so generated components point to the correct path.
Acknowledgements
Thanks to the authors whose posts informed parts of this implementation: