Generate PNG icons from an SVG or PNG source for iOS and PWA compatibility. A modern, flexible Node.js tool that converts your source logo into all the icon sizes you need for mobile devices and progressive web apps.
- 🎨 Convert SVG or PNG source art to multiple PNG icon sizes
- 🖼️ PNG sources for when you only have raster logo art
- 📱 iOS Apple Touch Icon support
- 🌐 PWA icon generation
- 🖼️ Automatic favicon size generation (16x16, 32x32)
- ⚙️ Configurable quality and compression
- 🎯 CLI with interactive mode
- 📦 ESM module for programmatic use
- ✅ Comprehensive test coverage
- 🚀 Built with modern Node.js (v20+)
# Using pnpm (recommended)
pnpm add @profullstack/favicon-generator
# Using npm
npm install @profullstack/favicon-generator
# Using yarn
yarn add @profullstack/favicon-generator# Using pnpm
pnpm add -g @profullstack/favicon-generator
# Using npm
npm install -g @profullstack/favicon-generatorSimply run the command without arguments to enter interactive mode:
favYou'll be prompted for:
- Source file path (
.svgor.png) - Output directory
- PNG quality (1-100)
- Compression level (0-9)
- Whether to generate additional favicon sizes
# Basic usage with an SVG source
fav -i favicon.svg -o ./icons
# Basic usage with a PNG source
fav -i logo.png -o ./icons
# With custom quality and compression
fav -i logo.svg -o ./public/icons -q 90 -c 7
# Silent mode (no output)
fav -i favicon.svg -o ./icons --silent
# Skip favicon generation
fav -i favicon.svg -o ./icons --no-favicon
# Show help
fav --help
# Show version
fav --version| Option | Alias | Description | Default |
|---|---|---|---|
--input |
-i |
Path to source .svg or .png |
./favicon.svg |
--output |
-o |
Output directory | ./icons |
--quality |
-q |
PNG quality (1-100) | 95 |
--compression |
-c |
Compression level (0-9) | 9 |
--no-favicon |
Skip additional favicon sizes | false |
|
--silent |
Suppress output messages | false |
|
--help |
-h |
Show help message | |
--version |
-v |
Show version number |
import { generateIcons } from '@profullstack/favicon-generator';
const results = await generateIcons({
inputPath: './favicon.svg', // or './logo.png'
outputDir: './icons',
});
console.log(`Generated ${results.icons.length} icons`);import { generateIcons } from '@profullstack/favicon-generator';
const results = await generateIcons({
inputPath: './logo.png',
outputDir: './public/icons',
});
// 'png' for a raster source, 'svg' for a vector one
console.log(results.inputFormat); // 'png'
// A PNG source has no vector equivalent, so no favicon.svg is written
console.log(results.rootFavicons); // { png: ..., ico: ... }import { generateIcons } from '@profullstack/favicon-generator';
const results = await generateIcons({
inputPath: './logo.svg',
outputDir: './public/icons',
quality: 90,
compressionLevel: 7,
generateFavicon: true,
faviconSizes: [16, 32, 48],
verbose: true,
});
// Access generated files
results.icons.forEach((icon) => {
console.log(`${icon.name}: ${icon.path}`);
});import { generateCustomIcons } from '@profullstack/favicon-generator';
const customSizes = [
{ size: 48, name: 'icon-48.png' },
{ size: 96, name: 'icon-96.png' },
{ size: 144, name: 'icon-144.png' },
];
const results = await generateCustomIcons('./favicon.svg', './icons', customSizes, { quality: 95 });import { generateIcons, DEFAULT_ICON_SIZES, BACKGROUNDS } from '@profullstack/favicon-generator';
// Use default icon sizes
const results = await generateIcons({
inputPath: './favicon.svg',
outputDir: './icons',
iconSizes: DEFAULT_ICON_SIZES,
});
// Available background colors
console.log(BACKGROUNDS.transparent); // { r: 255, g: 255, b: 255, alpha: 0 }
console.log(BACKGROUNDS.white); // { r: 255, g: 255, b: 255, alpha: 1 }
console.log(BACKGROUNDS.black); // { r: 0, g: 0, b: 0, alpha: 1 }Generate PNG icons from an SVG or PNG source file.
Parameters:
options(Object):inputPath(string, required): Path to the source.svgor.pngfilesvgPath(string, optional): Deprecated alias forinputPath, still accepted (and it may point at a.png)outputDir(string, required): Output directory for generated iconsiconSizes(Array, optional): Array of{size, name}objects. Defaults toDEFAULT_ICON_SIZESquality(number, optional): PNG quality (1-100). Default:95compressionLevel(number, optional): Compression level (0-9). Default:9generateFavicon(boolean, optional): Generate additional favicon sizes. Default:truefaviconSizes(Array, optional): Array of favicon sizes. Default:[16, 32]verbose(boolean, optional): Enable verbose logging. Default:true
Returns: Promise
{
icons: [
{ size: 64, name: 'icon-64.png', path: './icons/icon-64.png' },
// ...
],
faviconSizes: [
{ size: 16, path: './icons/favicon-16.png' },
// ...
],
outputDir: './icons',
inputPath: './favicon.svg',
inputFormat: 'svg', // 'svg' or 'png'
rootFavicons: {
png: './icons/favicon.png',
svg: './icons/favicon.svg', // omitted for a PNG source
ico: './icons/favicon.ico'
}
}| SVG source | PNG source | |
|---|---|---|
| Scaling | Rasterized losslessly at every size | Resampled; upscaling softens the image |
favicon.svg |
Written (copy of the source) | Not written — no vector equivalent |
Primary <link rel="icon"> |
/favicon.svg (image/svg+xml) |
/favicon.png (image/png) |
| Recommended input | Any square viewBox | Square, at least 512x512 |
A PNG source smaller than the largest requested icon, or one that isn't square, logs a warning: icons are still generated (upscaled and padded to fit), but the result will be softer than vector art. Supply the highest resolution you have.
Helpers for validating a source path before calling generateIcons.
import { isSupportedInputFile, getInputFormat } from '@profullstack/favicon-generator';
isSupportedInputFile('logo.png'); // true
isSupportedInputFile('logo.jpg'); // false
getInputFormat('logo.png'); // 'png'
getInputFormat('logo.svg'); // 'svg'
getInputFormat('logo.jpg'); // nullGenerate icons with custom sizes.
Parameters:
inputPath(string): Path to the source.svgor.pngfileoutputDir(string): Output directorycustomSizes(Array): Array of{size, name}objectsadditionalOptions(Object, optional): Additional options (quality, compressionLevel, etc.)
Returns: Promise (same as generateIcons)
The package generates the following icon sizes by default:
- 57x57, 60x60, 72x72, 76x76
- 114x114, 120x120, 144x144
- 152x152, 180x180
- 192x192, 256x256, 384x384, 512x512
- 16x16, 32x32
After generating your icons, add them to your HTML <head> section. See the complete example in examples/html-head-template.html.
<head>
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16.png" />
<!-- Apple Touch Icons (iOS) -->
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon-180x180.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/icons/apple-touch-icon-152x152.png" />
<link rel="apple-touch-icon" sizes="144x144" href="/icons/apple-touch-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="120x120" href="/icons/apple-touch-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/icons/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/icons/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/icons/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/icons/apple-touch-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="57x57" href="/icons/apple-touch-icon-57x57.png" />
<!-- Web App Manifest (PWA) -->
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#ffffff" />
<!-- iOS Web App -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="Your App" />
</head>Create a manifest.json file for Progressive Web App support. See examples/manifest.json for a complete example:
{
"name": "Your App Name",
"short_name": "App",
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
],
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffffff"
}- iOS: Uses Apple Touch Icons (automatically adds rounded corners)
- Android/PWA: Uses icons from manifest.json
- Windows: Uses msapplication meta tags
- Modern Browsers: Prefer an SVG favicon with PNG fallbacks; with a PNG source,
favicon.pngplus the sized PNGs cover every browser
# Clone the repository
git clone https://github.com/profullstack/favicon-generator.git
cd favicon-generator
# Install dependencies
pnpm install# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage# Lint code
pnpm lint
# Fix linting issues
pnpm lint:fix
# Format code
pnpm format
# Check formatting
pnpm format:check- Node.js >= 20.0.0
- ESM support
MIT © profullstack
Contributions are welcome! Please feel free to submit a Pull Request.
If you encounter any issues or have questions, please file an issue on the GitHub repository.
See CHANGELOG.md for release history.