favsmith
v0.1.0
Published
Local favicon and PWA asset generator
Maintainers
Readme
favsmith
Local-first favicon and PWA asset generation from a single SVG or PNG. No asset uploads. No hosted API. No config file required for one-off runs.
Requirements
- Bun 1.3+
favsmith is a Bun-first CLI. The published bin runs through bun.
The published package ships a Bun-built dist/ entry instead of raw source files.
Install
Run it without installing:
bunx favsmith --helpOr install it globally:
bun add -g favsmith
favsmith --helpQuick Start
| Workflow | Command |
| --- | --- |
| Guided generation in the current terminal | bunx favsmith |
| One-off generation beside a source file | bunx favsmith generate ~/Downloads/logo.svg --standalone --yes |
| Project config setup | bunx favsmith init |
| Project generation into public/ | bunx favsmith generate assets/logo.svg --out public --yes |
Generate a full favicon set beside a source file in your Downloads folder:
bunx favsmith generate ~/Downloads/logo.svg --standalone --yesThat writes to a sibling directory such as:
~/Downloads/logo-favicons/Use project mode when you want a saved config:
bunx favsmith init
bunx favsmith generate assets/logo.svg --out public --yesThe CLI is interactive by default. Use --yes for deterministic, non-interactive runs.
Running favsmith with no command in an interactive terminal starts the guided generate flow.
Commands
| Command | Purpose |
| --- | --- |
| generate [source] | Generate favicon and PWA assets |
| init | Create a favsmith.json with project defaults |
| doctor | Validate a generated output set |
| snippet | Print a framework-specific integration snippet |
| preview | Write a local preview HTML page |
Common generate examples:
bunx favsmith generate ./logo.svg --standalone --yes
bunx favsmith generate ./logo.svg --out ./favicons --yes
bunx favsmith generate ./logo.svg --preset website --yes
bunx favsmith generate ./logo.svg --framework nextjs --yes
bunx favsmith generate ./logo.svg --dry-runStandalone Mode
--standalone is the ad-hoc workflow for generating icons outside an existing project.
In standalone mode, favsmith:
- ignores
favsmith.json - does not derive app metadata from the current working directory
- derives
appNameandshortNamefrom the source filename - defaults
outDirto a sibling*-faviconsdirectory
Example:
bunx favsmith generate ~/Downloads/acme-logo.svg --standalone --yesDefault output:
~/Downloads/acme-logo-favicons/Generated Files
The default modern/PWA preset generates:
| File | Purpose |
| --- | --- |
| favicon.ico | Classic multi-size favicon |
| favicon-16x16.png | Browser favicon |
| favicon-32x32.png | Browser favicon |
| favicon-48x48.png | Larger favicon |
| apple-touch-icon.png | Apple home screen icon |
| android-chrome-192x192.png | Standard Android/PWA icon |
| android-chrome-512x512.png | Large Android/PWA icon |
| maskable-icon-192x192.png | Maskable launcher icon |
| maskable-icon-512x512.png | Maskable launcher icon |
| site.webmanifest | Web app manifest |
| safari-pinned-tab.svg | Safari pinned-tab icon for SVG sources |
| snippet file | Integration markup or framework metadata |
| preview HTML | Local visual preview |
Snippet Targets
favsmith snippet and generated snippet files support:
- plain HTML
- Next.js app router metadata
- Vite
- Astro
- Remix
Presets
| Preset | Output |
| --- | --- |
| website | favicon + Apple touch icon, no manifest |
| modern | default favicon + PWA set |
| pwa | same asset set as modern |
| nextjs | modern set + Next.js snippet |
| vite | modern set + Vite snippet |
| astro | modern set + Astro snippet |
| remix | modern set + Remix snippet |
Example Config
{
"source": "assets/logo.svg",
"outDir": "public",
"preset": "modern",
"framework": "plain-html",
"appName": "My App",
"shortName": "My App",
"themeColor": "#ffffff",
"backgroundColor": "#ffffff",
"background": "transparent",
"optimizeSvg": true,
"safariPinnedTab": "auto",
"pinnedTabColor": "#0f172a",
"maskable": {
"enabled": true,
"paddingPercent": 10
},
"emitManifest": true,
"emitSnippet": true,
"faviconSizes": [16, 32, 48],
"androidSizes": [192, 512],
"maskableSizes": [192, 512]
}Notes
- SVG input is preferred.
- PNG input should be at least
512x512. - SVG optimization runs through SVGO by default. Disable it with
--no-optimize-svgor"optimizeSvg": false. - Safari pinned-tab generation currently requires SVG input.
- Maskable icons are padded automatically by default.
- When the main background is transparent, maskable icons are still rendered onto a solid
backgroundColorcanvas for more robust launcher rendering.
Non-Goals
- historical parity with every old favicon/browser edge case
- hosted image processing
- Windows Metro/browserconfig as a primary workflow
- Safari pinned-tab generation from PNG input
Development
Run the local validation:
bun run lint
bun run check-types
bun testBuild the published artifact:
bun run build
bun ./dist/favsmith.js --helpRewrite formatting with:
bun run formatFor local CLI development:
bun run src/cli.ts --help