favicon
π―Skillfrom andrehfp/tinyplate
Generates comprehensive favicons and app icons for Next.js projects, automatically detecting app details and creating multi-size icon sets.
Part of
andrehfp/tinyplate(8 items)
Installation
git clone git@github.com:andrehfp/tinyplate.gitSkill Details
"Generate favicons and app icons for Next.js projects. Creates all required sizes, formats, and configures metadata."
Overview
# Favicon Generator
Generate complete favicon sets for Next.js projects.
Workflow
Step 1: Auto-Detect App Information
IMPORTANT: Before asking the user anything, scan the codebase to extract:
```bash
# Check these files in order:
```
#### 1. Package.json
```typescript
// Read package.json for name and description
{
"name": "my-app", // App name
"description": "..." // App description
}
```
#### 2. Next.js Metadata (app/layout.tsx)
```typescript
// Look for metadata export
export const metadata: Metadata = {
title: "App Title", // App name
description: "...", // App description
};
// Or metadataBase, applicationName
```
#### 3. README.md
```markdown
# App Name <- Extract from H1
Description paragraph <- Extract first paragraph
```
#### 4. Tailwind Config (tailwind.config.ts)
```typescript
// Look for custom colors in theme.extend.colors
theme: {
extend: {
colors: {
primary: "#6366f1", // Brand color
brand: { ... }
}
}
}
```
#### 5. CSS Variables (app/globals.css)
```css
:root {
--primary: #6366f1; / Brand color /
--brand-color: ...;
}
```
#### 6. Existing Favicon/Icons
```bash
# Check if icons already exist
public/favicon.ico
public/apple-touch-icon.png
app/icon.tsx
app/icon.png
```
Step 2: Present Findings & Confirm
After scanning, present what was found:
```
I found the following from your codebase:
App name: Striggo
Description: A study platform for professional certification exams
Brand color: #8b5cf6 (from Tailwind config)
Existing icons: None found
Should I generate a favicon based on this? Or would you like to customize?
```
Only ask questions if:
- App name is missing or unclear
- No brand colors found (suggest based on app type)
- User wants to override detected values
Step 3: Choose Generation Method
Based on user input, choose one of these approaches:
---
Option A: Generate from Description (No Source Image)
A1: Text/Initial-Based Icon
Best for: Professional SaaS apps, clean minimal branding.
```typescript
// app/icon.tsx
import { ImageResponse } from "next/og";
export const runtime = "edge";
export const contentType = "image/png";
export const size = { width: 32, height: 32 };
export default function Icon() {
return new ImageResponse(
(
style={{ // Use app's primary brand color background: "linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)", width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 8, color: "white", fontSize: 20, fontWeight: 700, fontFamily: "system-ui, sans-serif", }} > {/ First letter or initials of app name /} S
),
{ ...size }
);
}
```
Create matching apple-icon.tsx:
```typescript
// app/apple-icon.tsx
import { ImageResponse } from "next/og";
export const runtime = "edge";
export const contentType = "image/png";
export const size = { width: 180, height: 180 };
export default function AppleIcon() {
return new ImageResponse(
(
style={{ background: "linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)", width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 40, color: "white", fontSize: 100, fontWeight: 700, fontFamily: "system-ui, sans-serif", }} > S
),
{ ...size }
);
}
```
A2: Emoji-Based Icon
Best for: Fun apps, MVPs, quick prototypes.
```typescript
// app/icon.tsx
import { ImageResponse } from "next/og";
export const runtime = "edge";
export const contentType = "image/png";
export const size = { width: 32, height: 32 };
export default function Icon() {
return new ImageResponse(
(
style={{ background: "#f8fafc", width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 6, fontSize: 24, }} > {/ Choose emoji that represents the app /} π
),
{ ...size }
);
}
```
A3: SVG Icon (Scalable, Dark Mode Support)
Best for: Technical apps, developer tools.
```typescript
// app/icon.tsx
import { ImageResponse } from "next/og";
export const runtime = "edge";
export const contentType = "image/png";
export const size = { width: 32, height: 32 };
export default function Icon() {
return new ImageResponse(
(
style={{ background: "#0f172a", width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 6, }} > {/ Simple geometric shape or symbol /} width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" >
),
{ ...size }
);
}
```
Design Guidelines by App Type
| App Type | Style | Colors | Icon Ideas |
|----------|-------|--------|------------|
| Finance/Banking | Minimal, professional | Blue, green, dark | Letter, shield, chart |
| Productivity | Clean, modern | Purple, blue | Checkmark, layers, grid |
| Social/Community | Friendly, warm | Orange, pink | Heart, people, chat |
| Developer Tools | Technical, dark | Dark gray, cyan | Terminal, brackets, code |
| E-commerce | Bold, trustworthy | Orange, blue | Cart, bag, tag |
| Health/Fitness | Energetic, fresh | Green, teal | Heart, leaf, pulse |
| Education | Approachable | Blue, yellow | Book, cap, lightbulb |
Color Suggestions
Based on app purpose, suggest colors:
```typescript
const colorSchemes = {
professional: "linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%)",
creative: "linear-gradient(135deg, #ec4899 0%, #8b5cf6 100%)",
growth: "linear-gradient(135deg, #059669 0%, #10b981 100%)",
energy: "linear-gradient(135deg, #ea580c 0%, #f59e0b 100%)",
trust: "linear-gradient(135deg, #0284c7 0%, #06b6d4 100%)",
minimal: "#0f172a", // Solid dark
light: "#f8fafc", // Solid light with colored icon
};
```
---
Option B: Generate from Existing Source Image
B1: Using Sharp (Recommended)
```bash
bun add sharp
```
```typescript
// scripts/generate-favicons.ts
import sharp from "sharp";
import { join } from "path";
const SOURCE = "source-icon.png";
const OUTPUT_DIR = "public";
const sizes = [
{ name: "favicon-16x16.png", size: 16 },
{ name: "favicon-32x32.png", size: 32 },
{ name: "apple-touch-icon.png", size: 180 },
{ name: "android-chrome-192x192.png", size: 192 },
{ name: "android-chrome-512x512.png", size: 512 },
];
async function generateFavicons() {
for (const { name, size } of sizes) {
await sharp(SOURCE)
.resize(size, size)
.png()
.toFile(join(OUTPUT_DIR, name));
console.log(Generated: ${name});
}
// Create ICO
await sharp(SOURCE)
.resize(32, 32)
.toFile(join(OUTPUT_DIR, "favicon.ico"));
}
generateFavicons();
```
B2: Using ImageMagick
```bash
brew install imagemagick
# Generate all sizes
convert source.png -resize 16x16 public/favicon-16x16.png
convert source.png -resize 32x32 public/favicon-32x32.png
convert source.png -resize 180x180 public/apple-touch-icon.png
convert source.png -resize 192x192 public/android-chrome-192x192.png
convert source.png -resize 512x512 public/android-chrome-512x512.png
convert source.png -resize 32x32 -define icon:auto-resize=32,16 public/favicon.ico
```
---
Step 3: Create Web Manifest
```json
// public/site.webmanifest
{
"name": "APP_NAME",
"short_name": "APP_SHORT",
"description": "APP_DESCRIPTION",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#PRIMARY_COLOR",
"background_color": "#ffffff",
"display": "standalone",
"start_url": "/"
}
```
Or use dynamic manifest:
```typescript
// app/manifest.ts
import type { MetadataRoute } from "next";
export default function manifest(): MetadataRoute.Manifest {
return {
name: "App Name",
short_name: "App",
description: "App description",
start_url: "/",
display: "standalone",
background_color: "#ffffff",
theme_color: "#6366f1",
icons: [
{
src: "/android-chrome-192x192.png",
sizes: "192x192",
type: "image/png",
},
{
src: "/android-chrome-512x512.png",
sizes: "512x512",
type: "image/png",
},
],
};
}
```
Step 4: Configure Metadata (if using static files)
```typescript
// app/layout.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "App Name",
description: "App description",
icons: {
icon: [
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
],
apple: [
{ url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" },
],
},
manifest: "/site.webmanifest",
};
```
Interactive Flow
When running /favicon:
1. First, scan the codebase (silently):
```bash
# Read these files
cat package.json
cat app/layout.tsx
cat README.md
cat tailwind.config.ts
cat app/globals.css
ls public/favicon app/icon 2>/dev/null
```
2. Present findings:
```
I scanned your codebase and found:
App name: Striggo
Description: A study platform for professional certification exams
Brand color: #8b5cf6 (from tailwind.config.ts)
Existing icons: None
I'll generate a favicon with:
- Letter "S" on purple gradient background
- Professional style (matching education/learning apps)
Proceed with this? Or customize (name/color/style)?
```
3. If info is missing, ask only what's needed:
```
I couldn't detect a brand color. What color should I use?
- Purple (education/learning)
- Blue (trust/professional)
- Green (growth/success)
- Custom hex code
> 1
```
4. Generate:
app/icon.tsx- Dynamic 32x32 faviconapp/apple-icon.tsx- Dynamic 180x180 Apple iconapp/manifest.ts- PWA manifest- Update
app/layout.tsxwith theme colors
Files Checklist
For Dynamic Icons (Option A)
```
app/
βββ icon.tsx # 32x32 favicon (generated)
βββ apple-icon.tsx # 180x180 Apple icon (generated)
βββ manifest.ts # PWA manifest
```
For Static Icons (Option B)
```
public/
βββ favicon.ico
βββ favicon-16x16.png
βββ favicon-32x32.png
βββ apple-touch-icon.png
βββ android-chrome-192x192.png
βββ android-chrome-512x512.png
βββ site.webmanifest
```
Troubleshooting
| Issue | Solution |
|-------|----------|
| Icon not updating | Clear cache, restart dev server |
| Apple icon not showing | Must be exactly 180x180 PNG |
| Dynamic icon 500 error | Check ImageResponse syntax |
| Emoji not rendering | Use system emoji font |
| Gradient looks wrong | Use standard CSS gradient syntax |
More from this repository7
ux-design skill from andrehfp/tinyplate
Optimizes Next.js apps with comprehensive technical SEO infrastructure, generating sitemaps, robots.txt, meta tags, structured data, and canonical URLs.
posthog skill from andrehfp/tinyplate
stripe skill from andrehfp/tinyplate
marketing-copy skill from andrehfp/tinyplate
abacatepay skill from andrehfp/tinyplate
Automates Cloudflare domain configuration by setting up DNS records, integrating Clerk, configuring Vercel, and managing email routing.