C.W.K.
Stream
Lesson 01 of 05 · published

Icons and Branding — The Four PNGs That Actually Matter

~9 min · icons, branding, manifest, assets

Level 0Extension Curious
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Chrome shows your icon in five places at four sizes, and a single 128 PNG scaled to 16 looks like static. Lesson 1 is producing the right four PNGs, then the side notes — disabled-state grayscale, dark-mode considerations, Web Store badge variants."

The Four Sizes Chrome Asks For

  • 16 — toolbar favicon next to chrome://extensions URLs, and the URL bar when relevant.
  • 32 — Windows scaling and some platform-specific surfaces.
  • 48 — the extension management page (chrome://extensions card).
  • 128 — Chrome Web Store listing, install prompt, sometimes used on the New Tab page.

Provide all four as separate PNGs. Chrome can scale a single image but the result is visibly worse than pixel-tuned variants — especially the 16, where antialiased detail from a 128 turns into mush.

Designing for the Sizes

The 16 is the hardest. Less than 250 pixels total, often shown next to dark UI chrome. Practical constraints:

  • One strong silhouette. Multi-element logos disappear at 16; pick the single most recognizable shape.
  • High contrast against both white and dark backgrounds. Chrome's UI flips depending on dark mode.
  • Avoid thin strokes. A 1-pixel line at 16 anti-aliases into a gray smear; 2-pixel minimum.
  • Test in actual context. Open chrome://extensions on a Mac with dark mode; if your icon hides into the page, you need a stronger silhouette.

The 128 has the most room but is also the most public — the Web Store screenshot shows it at full size. Treat it as your hero asset; the smaller sizes derive from it.

The Manifest Declaration

Two places to list icons:

  • icons (top-level) — used by chrome://extensions and the Web Store. Object keyed by size.
  • action.default_icon — used in the toolbar. Usually mirrors the top-level icons.

You can declare both with the same paths; Chrome reads them as separate fields but you don't need two sets of files.

Disabled State

When you call chrome.action.disable(tabId), Chrome greys out your icon automatically — no separate disabled asset needed. The default greyscale conversion works for most icons. If yours has elements that disappear in greyscale (low-contrast colors), provide a manual setIcon with a hand-tuned grey variant.

Dark Mode

Chrome doesn't auto-flip your icon for dark mode. If your icon is dark-on-transparent, it's invisible against Chrome's dark toolbar. Two options:

  • Outline approach — keep the icon mostly stroke-based with no solid fills. Works on both backgrounds.
  • Programmatic swap — listen for matchMedia('(prefers-color-scheme: dark)') in the SW, call chrome.action.setIcon with a light variant when needed. More work; rarely worth it for v1.

ClipDeck v1 uses the outline approach for the 16 — paperclip outline, brand color stroke, no fill. Reads cleanly on both light and dark Chrome.

The Web Store Asset Pack

The Chrome Web Store needs more than the extension icons — store-only assets you upload separately:

  • 128 × 128 store icon — same as the manifest icon at 128.
  • 440 × 280 small promo tile — appears in store search results.
  • 1400 × 560 marquee promo — featured-extension surfaces (rare for indie extensions; design it anyway).
  • Screenshots — 1280 × 800 or 640 × 400. At least one; up to five. These are the most-viewed asset; treat them as marketing.

Have the screenshot set ready before submission. Web Store reviewers count screenshot quality toward 'is this real software,' and bare manifest-only listings get rejected for not communicating what the extension does.

Four PNGs at 16 / 32 / 48 / 128, one strong silhouette, contrast for both backgrounds. The 128 is your hero; the 16 is your test for whether the design survives at extension-bar scale.
Generate the four sizes from one master. Design once at 128 or higher in a vector tool (Figma, Sketch, Illustrator). Export with the four canvas sizes set explicitly, optimizing each separately — at 16 you'll usually need to hand-tweak the silhouette so it reads. A pixel-perfect 16 takes 10 minutes that no amount of "just resize the 128" will save.

Code

manifest.json — both top-level and action icon declarations·json
{
  "icons": {
    "16": "icons/16.png",
    "32": "icons/32.png",
    "48": "icons/48.png",
    "128": "icons/128.png"
  },
  "action": {
    "default_icon": {
      "16": "icons/16.png",
      "32": "icons/32.png",
      "48": "icons/48.png",
      "128": "icons/128.png"
    },
    "default_title": "ClipDeck",
    "default_popup": "popup.html"
  }
}
Shell — quick generation of icon variants (hand-tune the 16 separately)·bash
# Generate the four PNG sizes from a 1024 master via ImageMagick
magick clipdeck-master.png -resize 128x128 icons/128.png
magick clipdeck-master.png -resize 48x48 icons/48.png
magick clipdeck-master.png -resize 32x32 icons/32.png
magick clipdeck-master.png -resize 16x16 icons/16.png

# Smarter: design 16 separately (hand-tuned silhouette), then scale up only for previews
# magick clipdeck-master-16-hand.png icons/16.png

External links

Exercise

Produce four PNG files at 16/32/48/128 from your existing icon master (or generate placeholder ones from a public-domain favicon). Drop them at clipdeck/icons/. Declare them in manifest.json's top-level icons AND action.default_icon (first code block). Reload the extension. Look at four places to confirm each size lands correctly: (1) toolbar — uses 16/32, (2) chrome://extensions card — uses 48, (3) chrome://extensions Details page — uses 128, (4) the URL bar when chrome://extensions/?id=... is open — uses 16. If any of those looks blurry or stretched, the wrong size loaded; check the manifest paths and that each PNG is actually at the declared resolution.
Hint
If the toolbar icon looks blurry on a high-DPI Mac, your 32 might be a scaled 16 — re-export a real 32 from the master. If the chrome://extensions card looks pixelated, the 48 is the issue. Chrome chooses sizes deterministically per surface; pick a problem surface and find the file the manifest says it loads. The Chrome Web Store rejects submissions with mismatched declared-size-vs-actual-pixel-dimensions, so honest sizes matter for the eventual submission.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.