npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@denkwerk/favicon-generator

v0.2.6

Published

Generate favicons, touch icons, a web app manifest and browserconfig.xml from an SVG or a Figma node. CLI and Node.js API; also available as a Nuxt module and a Vite, Rollup, Rolldown, webpack and Rspack plugin

Readme

Generates favicons, an Apple touch icon and <head> tags from one SVG, a raster image or a Figma component. Additionally, it can add a web app manifest, a theme color and Windows tiles. The work is done by a native Rust binary; the package ships prebuilt binaries for macOS (arm64, x64), Linux (arm64, x64) and Windows (x64).

pnpm add -D @denkwerk/favicon-generator

Requires Node.js ≥ 22.18 for TypeScript config files.

Usage

favicon-generator -i ./assets/favicon.svg -o ./public/favicons

or, with the same options in a favicon.config.ts next to your package.json, just favicon-generator:

import { defineConfig } from '@denkwerk/favicon-generator'

export default defineConfig({
  input: './assets/favicon.svg',
  output: './public/favicons',
})

Flags override the config file. favicon-generator ./assets/favicon.svg ./public/favicons is short for -i … -o ….

What you get

One command gives you a complete, modern favicon set: favicon.ico (16, 32, 48 px), favicon.svg (SVG input only), favicon-96x96.png, apple-touch-icon.png (180 px, opaque) and favicon.html with these tags:

<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">

Additionally, you can add a web app manifest, a theme color, Windows tiles and legacy sizes with one option each, see Options.

Configuration

Options can be given as flags, in a favicon.config.{ts,mts,cts,js,mjs,cjs,json}, or to generate(); the names are the same everywhere (flags in kebab-case). The config file is looked up in the current directory, then its parents up to the nearest package.json or .git. --config <path> picks a file, --no-config ignores them.

Relative paths in the config are resolved against its directory. JS/TS configs are evaluated with Node.js, so they can compute values, read env vars or export an (async) function; favicon.config.json is read without Node.js and can point "$schema" at ./node_modules/@denkwerk/favicon-generator/schema.json for editor support.

defineConfig reports unknown keys in a config object. For a function, annotate its return type (async (): Promise<FaviconConfig> => ({ ... })) to get the same check.

Options

The additions (in bold) are groups: set one to true for its defaults or to an object with its options; setting any of its options or flags adds it too. false or --no-<group> leaves it out, e.g. the Apple touch icon, which is included by default.

| Option | Flag | Default / effect | | --- | --- | --- | | input | -i, --input, first argument | (required) SVG, PNG, JPEG or WebP, or a Figma link with node-id | | output | -o, --output, second argument | favicons | | pathPrefix | -p, --path-prefix | /; the URL the files are served from | | overwrite | -y, --overwrite | false | | snippets | --snippets | ['html']; also 'json' (favicon-head.json) and 'nuxt' (nuxt-head.ts); [] for none | | themeColor | --theme-color | adds <meta name="theme-color"> and the manifest's theme_color | | appleTouchIcon | --[no-]apple-touch-icon | included: apple-touch-icon.png | | appleTouchIcon.background | --apple-touch-background | #ffffff; behind transparent pixels | | manifest | --[no-]manifest | adds manifest.json, 192/512 px icons, <link rel="manifest"> | | manifest.name | -n, --name | name | | manifest.shortName | --short-name | short_name | | manifest.description | --description | description | | manifest.startUrl | --start-url | start_url | | manifest.scope | --scope | scope | | manifest.display | --display | display: fullscreen, standalone, minimal-ui, browser | | manifest.backgroundColor | --background-color | background_color, also behind maskable icons | | manifest.maskable | --maskable | adds maskable icons (the image at 60 % on backgroundColor), one per icon size | | manifest.crossorigin | --manifest-crossorigin | crossorigin on the manifest <link> | | manifest.iconSizes | --manifest-icon-sizes | icon sizes listed in the manifest (default 192,512) | | manifest.iconPurpose | --manifest-icon-purpose | purpose of those icons, e.g. any maskable | | windows | --[no-]windows | adds browserconfig.xml, tile images, msapplication-* tags | | windows.tileColor | --tile-color | msapplication-TileColor | | legacy | --[no-]legacy | adds 19 PNG sizes, sized Apple touch icons, a 7-frame favicon.ico | | figmaToken | --figma-token, FIGMA_TOKEN | see Figma | | figmaTokenFile | --figma-token-file, FIGMA_TOKEN_FILE | see Figma | | cache | --no-cache | true; see Cache | | cacheDir | --cache-dir, FAVICON_GENERATOR_CACHE_DIR | node_modules/.cache/favicon-generator in the project root, if it has a node_modules |

The manifest contains exactly the fields you set; give it a name or shortName so browsers can offer installing the app.

export default defineConfig({
  input: './assets/favicon.svg',
  output: './public/favicons',
  pathPrefix: '/favicons/',
  themeColor: '#02969c',
  manifest: { name: 'My App', shortName: 'App', display: 'standalone' },
  windows: true,
})

Figma

Use a link to a component (it must contain node-id) as input. The node is exported as SVG through the Figma REST API, which needs a personal access token with the file_content:read scope (Figma → Settings → Security → Personal access tokens). Pass it in the FIGMA_TOKEN env var (e.g. from a gitignored .env.local) or a gitignored figmaTokenFile, not in the config itself.

export default defineConfig({
  input: 'https://www.figma.com/design/<file-key>/<file-name>?node-id=19938-42',
  output: './public/favicons',
})

Cache

While the input and the options are unchanged, the generated files are copied from the cache instead of being rendered again. A Figma export is reused while the Figma file's version is unchanged, which costs one small API request instead of an export and a download; when that request fails (offline, rate limited, no token), the cached export is used with a warning. cache: false / --no-cache turns the cache off, cacheDir / --cache-dir moves it. Without a node_modules in the project root and without cacheDir, nothing is cached.

Node.js API

import { generate } from '@denkwerk/favicon-generator'

await generate({ input: 'assets/favicon.svg', output: 'public/favicons', manifest: { name: 'My App' } }, { cwd: import.meta.dirname })

generate() does not read config files: the object you pass is the whole config. To use a config file from your own tooling, loadConfig() finds and evaluates it with the CLI's rules:

import { loadConfig } from '@denkwerk/favicon-generator'

const { path, config } = await loadConfig({ cwd: process.cwd() }) // path is null if none was found

mergeConfig(config, overrides) puts your own options on top the way CLI flags do: undefined values are skipped, and groups such as manifest are merged key by key.

For Nuxt, the @denkwerk/nuxt-favicon-generator module does all of this at build time: it generates the files, serves them and adds the tags. For Vite, Rollup, Rolldown, webpack and Rspack, @denkwerk/unplugin-favicon-generator emits them with the build.

License

MIT