Skip to content

jakejarvis/favsmith

Repository files navigation

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 --help

Or install it globally:

bun add -g favsmith
favsmith --help

Quick 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 --yes

That 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 --yes

The 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-run

Standalone 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 appName and shortName from the source filename
  • defaults outDir to a sibling *-favicons directory

Example:

bunx favsmith generate ~/Downloads/acme-logo.svg --standalone --yes

Default 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-svg or "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 backgroundColor canvas 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 test

Build the published artifact:

bun run build
bun ./dist/favsmith.js --help

Rewrite formatting with:

bun run format

For local CLI development:

bun run src/cli.ts --help

About

Local favicon and PWA asset generator

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors