favicon

📁 andrehfp/tinyplate 📅 Jan 22, 2026
9
总安装量
6
周安装量
#31483
全站排名
安装命令
npx skills add https://github.com/andrehfp/tinyplate --skill favicon

Agent 安装分布

windsurf 4
claude-code 4
opencode 3
cursor 3
antigravity 2

Skill 文档

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:

# Check these files in order:

1. Package.json

// Read package.json for name and description
{
  "name": "my-app",           // App name
  "description": "..."        // App description
}

2. Next.js Metadata (app/layout.tsx)

// Look for metadata export
export const metadata: Metadata = {
  title: "App Title",         // App name
  description: "...",         // App description
};

// Or metadataBase, applicationName

3. README.md

# App Name              <- Extract from H1
Description paragraph   <- Extract first paragraph

4. Tailwind Config (tailwind.config.ts)

// Look for custom colors in theme.extend.colors
theme: {
  extend: {
    colors: {
      primary: "#6366f1",    // Brand color
      brand: { ... }
    }
  }
}

5. CSS Variables (app/globals.css)

:root {
  --primary: #6366f1;        /* Brand color */
  --brand-color: ...;
}

6. Existing Favicon/Icons

# 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.

// 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(
    (
      <div
        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
      </div>
    ),
    { ...size }
  );
}

Create matching apple-icon.tsx:

// 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(
    (
      <div
        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
      </div>
    ),
    { ...size }
  );
}

A2: Emoji-Based Icon

Best for: Fun apps, MVPs, quick prototypes.

// 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(
    (
      <div
        style={{
          background: "#f8fafc",
          width: "100%",
          height: "100%",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          borderRadius: 6,
          fontSize: 24,
        }}
      >
        {/* Choose emoji that represents the app */}
        🚀
      </div>
    ),
    { ...size }
  );
}

A3: SVG Icon (Scalable, Dark Mode Support)

Best for: Technical apps, developer tools.

// 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(
    (
      <div
        style={{
          background: "#0f172a",
          width: "100%",
          height: "100%",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          borderRadius: 6,
        }}
      >
        {/* Simple geometric shape or symbol */}
        <svg
          width="20"
          height="20"
          viewBox="0 0 24 24"
          fill="none"
          stroke="white"
          strokeWidth="2"
        >
          <path d="M12 2L2 7l10 5 10-5-10-5z" />
          <path d="M2 17l10 5 10-5" />
          <path d="M2 12l10 5 10-5" />
        </svg>
      </div>
    ),
    { ...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:

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)

bun add sharp
// 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

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

// 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:

// 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)

// 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):

# 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?
1. Purple (education/learning)
2. Blue (trust/professional)
3. Green (growth/success)
4. Custom hex code
> 1

4. Generate:

  • app/icon.tsx – Dynamic 32×32 favicon
  • app/apple-icon.tsx – Dynamic 180×180 Apple icon
  • app/manifest.ts – PWA manifest
  • Update app/layout.tsx with 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 180×180 PNG
Dynamic icon 500 error Check ImageResponse syntax
Emoji not rendering Use system emoji font
Gradient looks wrong Use standard CSS gradient syntax