Skip to content

Instantly share code, notes, and snippets.

@Shpigford
Created January 11, 2026 17:24
Show Gist options
  • Select an option

  • Save Shpigford/4fc52b16953540ae268b10e5d7f8c0ae to your computer and use it in GitHub Desktop.

Select an option

Save Shpigford/4fc52b16953540ae268b10e5d7f8c0ae to your computer and use it in GitHub Desktop.
/favicon command for Claude Code — Generates all necessary favicon files, HTML and webmanifest, including updating your layout files with the necessary code.
---
argument-hint: [path to source image]
description: Generate favicons from a source image
---
Generate a complete set of favicons from the source image at `$1` and update the project's HTML with the appropriate link tags.
## Prerequisites
First, verify ImageMagick v7+ is installed by running:
```bash
which magick
```
If not found, stop and instruct the user to install it:
- **macOS**: `brew install imagemagick`
- **Linux**: `sudo apt install imagemagick`
## Step 1: Validate Source Image
1. Verify the source image exists at the provided path: `$1`
2. Check the file extension is a supported format (PNG, JPG, JPEG, SVG, WEBP, GIF)
3. If the file doesn't exist or isn't a valid image format, report the error and stop
Note whether the source is an SVG file - if so, it will also be copied as `favicon.svg`.
## Step 2: Detect Project Type and Static Assets Directory
Detect the project type and determine where static assets should be placed. Check in this order:
| Framework | Detection | Static Assets Directory |
|-----------|-----------|------------------------|
| **Rails** | `config/routes.rb` exists | `public/` |
| **Next.js** | `next.config.*` exists | `public/` |
| **Gatsby** | `gatsby-config.*` exists | `static/` |
| **SvelteKit** | `svelte.config.*` exists | `static/` |
| **Astro** | `astro.config.*` exists | `public/` |
| **Hugo** | `hugo.toml` or `config.toml` with Hugo markers | `static/` |
| **Jekyll** | `_config.yml` with Jekyll markers | Root directory (same as `index.html`) |
| **Vite** | `vite.config.*` exists | `public/` |
| **Create React App** | `package.json` has `react-scripts` dependency | `public/` |
| **Vue CLI** | `vue.config.*` exists | `public/` |
| **Angular** | `angular.json` exists | `src/assets/` |
| **Eleventy** | `.eleventy.js` or `eleventy.config.*` exists | Check `_site` output or root |
| **Static HTML** | `index.html` in root | Same directory as `index.html` |
**Important**: If existing favicon files are found (e.g., `favicon.ico`, `apple-touch-icon.png`), use their location as the target directory regardless of framework detection.
Report the detected project type and the static assets directory that will be used.
**When in doubt, ask**: If you are not 100% confident about where static assets should be placed (e.g., ambiguous project structure, multiple potential locations, unfamiliar framework), use `AskUserQuestionTool` to confirm the target directory before proceeding. It's better to ask than to put files in the wrong place.
## Step 3: Determine App Name
Find the app name from these sources (in priority order):
1. **Existing `site.webmanifest`** - Check the detected static assets directory for an existing manifest and extract the `name` field
2. **`package.json`** - Extract the `name` field if it exists
3. **Rails `config/application.rb`** - Extract the module name (e.g., `module MyApp` → "MyApp")
4. **Directory name** - Use the current working directory name as fallback
Convert the name to title case if needed (e.g., "my-app" → "My App").
## Step 4: Ensure Static Assets Directory Exists
Check if the detected static assets directory exists. If not, create it.
## Step 5: Generate Favicon Files
Run these ImageMagick commands to generate all favicon files. Replace `[STATIC_DIR]` with the detected static assets directory from Step 2.
### favicon.ico (multi-resolution: 16x16, 32x32, 48x48)
```bash
magick "$1" \
\( -clone 0 -resize 16x16 \) \
\( -clone 0 -resize 32x32 \) \
\( -clone 0 -resize 48x48 \) \
-delete 0 -alpha on -background none \
[STATIC_DIR]/favicon.ico
```
### favicon-96x96.png
```bash
magick "$1" -resize 96x96 -background none -alpha on [STATIC_DIR]/favicon-96x96.png
```
### apple-touch-icon.png (180x180)
```bash
magick "$1" -resize 180x180 -background none -alpha on [STATIC_DIR]/apple-touch-icon.png
```
### web-app-manifest-192x192.png
```bash
magick "$1" -resize 192x192 -background none -alpha on [STATIC_DIR]/web-app-manifest-192x192.png
```
### web-app-manifest-512x512.png
```bash
magick "$1" -resize 512x512 -background none -alpha on [STATIC_DIR]/web-app-manifest-512x512.png
```
### favicon.svg (only if source is SVG)
If the source file has a `.svg` extension, copy it:
```bash
cp "$1" [STATIC_DIR]/favicon.svg
```
## Step 6: Create/Update site.webmanifest
Create or update `[STATIC_DIR]/site.webmanifest` with this content (substitute the detected app name):
```json
{
"name": "[APP_NAME]",
"short_name": "[APP_NAME]",
"icons": [
{
"src": "/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
```
If `site.webmanifest` already exists in the static directory, preserve the existing `theme_color`, `background_color`, and `display` values while updating the `name`, `short_name`, and `icons` array.
## Step 7: Update HTML/Layout Files
Based on the detected project type, update the appropriate file. Adjust the `href` paths based on where the static assets directory is relative to the web root:
- If static files are in `public/` or `static/` and served from root → use `/favicon.ico`
- If static files are in `src/assets/` → use `/assets/favicon.ico`
- If static files are in the same directory as HTML → use `./favicon.ico` or just `favicon.ico`
### For Rails Projects
Edit `app/views/layouts/application.html.erb`. Find the `<head>` section and add/replace favicon-related tags with:
```html
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="[APP_NAME]" />
<link rel="manifest" href="/site.webmanifest" />
```
**Important**:
- If the source was NOT an SVG, omit the `<link rel="icon" type="image/svg+xml" href="/favicon.svg" />` line
- Remove any existing `<link rel="icon"`, `<link rel="shortcut icon"`, `<link rel="apple-touch-icon"`, or `<link rel="manifest"` tags before adding the new ones
- Place these tags near the top of the `<head>` section, after `<meta charset>` and `<meta name="viewport">` if present
### For Next.js Projects
Edit the detected layout file (`app/layout.tsx` or `src/app/layout.tsx`). Update or add the `metadata` export to include icons configuration:
```typescript
export const metadata: Metadata = {
// ... keep existing metadata fields
icons: {
icon: [
{ url: '/favicon.ico' },
{ url: '/favicon-96x96.png', sizes: '96x96', type: 'image/png' },
{ url: '/favicon.svg', type: 'image/svg+xml' },
],
shortcut: '/favicon.ico',
apple: '/apple-touch-icon.png',
},
manifest: '/site.webmanifest',
appleWebApp: {
title: '[APP_NAME]',
},
};
```
**Important**:
- If the source was NOT an SVG, omit the `{ url: '/favicon.svg', type: 'image/svg+xml' }` entry from the icon array
- If metadata export doesn't exist, create it with just the icons-related fields
- If metadata export exists, merge the icons configuration with existing fields
### For Static HTML Projects
Edit the detected `index.html` file. Add the same HTML as Rails within the `<head>` section.
### If No Project Detected
Skip HTML updates and inform the user they need to manually add the following to their HTML `<head>`:
```html
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="[APP_NAME]" />
<link rel="manifest" href="/site.webmanifest" />
```
## Step 8: Summary
Report completion with:
- Detected project type and framework
- Static assets directory used
- List of files generated
- App name used in manifest and HTML
- Layout file updated (or note if manual update is needed)
- Note if any existing files were overwritten
## Error Handling
- If ImageMagick is not installed, provide installation instructions and stop
- If the source image doesn't exist, report the exact path that was tried and stop
- If ImageMagick commands fail, report the specific error message
- If the layout file cannot be found for HTML updates, generate files anyway and instruct on manual HTML addition
@tscritch
Copy link

This is sick! Thanks for sharing!

@edhumbling
Copy link

incredible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment