Extension Icon Design That Actually Works at 16 Pixels

AppBooster Team · · 12 min read
Collection of minimal colorful app icons on a grid

Most developers design their extension icon last. They spend weeks on the popup UI, the background service worker, the content script injection — and then, with an hour left before submission, they open Figma and throw together something at 512px that looks fine on their Retina MacBook.

Then they wonder why nobody clicks install.

Here is the reality: your 16px toolbar icon is the version that runs in users’ heads. It is the icon Chrome renders next to the address bar, the one glanced at 50 times a day, the one that makes someone think “oh right, I have that extension” — or not. The 128px Web Store version is a one-time impression. The 16px version is your brand.

This guide covers the exact specifications, design constraints, and manifest wiring you need to get it right.


The Four Sizes and What Each One Does

Chrome requires icons in four sizes. Each serves a distinct purpose. Treat them as four separate design problems, not one icon resized four times.

SizeWhere it appearsWhat matters most
16pxToolbar, favicon in tabsShape readability, high contrast
32pxWindows taskbar, retina 16pxSlightly more detail allowed
48pxExtensions management page (chrome://extensions)Color and form recognition
128pxChrome Web Store listing, installation dialogFull brand expression

Your manifest.json declares all four:

{
  "manifest_version": 3,
  "name": "Your Extension",
  "version": "1.0.0",
  "icons": {
    "16": "icons/icon-16.png",
    "32": "icons/icon-32.png",
    "48": "icons/icon-48.png",
    "128": "icons/icon-128.png"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon-16.png",
      "32": "icons/icon-32.png"
    }
  }
}

Two separate icon declarations matter here. The top-level icons field covers general Chrome UI contexts. The action.default_icon specifically controls the toolbar button. Both need to point to the same files in most cases, but they are not automatically linked — skip one and Chrome falls back to whatever it finds, or nothing.

PNG only. Chrome’s extension security sandbox does not render SVGs as extension icons. This is not a preference or a soft guideline — SVGs simply will not work. Every design tool you use needs to export PNG at the end of the pipeline.


Pixel grid showing a simple icon shape at 16x16 resolution

Design at 16px First. Then Scale Up.

This is the most counterintuitive part of extension icon design, and the most important.

The default workflow for most designers: create something beautiful at 512px, export downscaled versions. The result at 16px is a blurry smear of your original intent.

The correct workflow: open a 16x16 canvas. Design within it. Every pixel you place is deliberate. Then scale up and add detail at larger sizes.

At 16px, you have 256 pixels total. That is not a metaphor for constraint — it is a literal constraint. Here is what works and what does not:

Works:

  • Single bold shape (circle, square, letter, arrow)
  • Two-color contrast: foreground shape against background
  • Geometric forms with straight edges and 45-degree diagonals
  • One recognizable symbol from your product’s visual language

Does not work:

  • Text (unreadable below 32px at most)
  • Gradients (compress to a muddy midtone)
  • More than three colors (visual noise)
  • Thin strokes under 2px (disappear against light and dark backgrounds)
  • Rounded details that require sub-pixel rendering to read correctly

The minimum stroke width at 16px is 2 pixels. Any thinner and Chrome’s rendering engine will either drop the stroke entirely or anti-alias it into illegibility depending on the background color behind the toolbar.

Edges must be pixel-aligned. If your shape edge falls between two pixels, you get anti-aliasing blur. Zoom into your 16px canvas at 3200% in your design tool before exporting. Every edge should land on a full pixel boundary.


Color Rules for Small Sizes

Three colors maximum at 16px. This is not aesthetic minimalism — it is a technical constraint driven by the rendering surface size.

The palette structure that works:

  1. Background — transparent (recommended) or a single solid color
  2. Primary shape — your main symbol, highest contrast color
  3. Accent (optional) — one small detail to add depth or meaning

Transparent backgrounds are strongly preferred. Chrome renders extension icons against the toolbar, and toolbar colors vary across operating systems, themes, and user preferences. A white background icon looks fine on dark mode Chrome but creates a jarring white box on a custom dark toolbar. Transparent backgrounds let the icon adapt.

There is no API to detect the current toolbar color. Chrome does not expose this information to extensions. You cannot programmatically swap icon variants based on toolbar theme. Design for both light and dark contexts simultaneously using contrast and transparency.

Color contrast at small sizes works differently than at large sizes. At 128px, a subtle difference in hue reads clearly. At 16px, only luminance contrast matters. Use a color contrast checker on your foreground/background pair and target a minimum ratio of 4.5:1 — the WCAG AA threshold for small text applies equally to small icons.

Avoid gradients at 16px and 32px entirely. When a gradient compresses down to 16px, the transition becomes two or three pixels wide and reads as a flat color with blurry edges. Save gradients for the 128px Web Store icon where they have room to exist.


Close-up of a designer's hand working on icon grid in design software

The 128px Store Icon: Different Rules

The Chrome Web Store displays your 128px icon in the listing, in the installation dialog, and in featured collections. This is marketing real estate. Different design rules apply.

Chrome’s unofficial but consistently observed convention for store icons: 96px of actual content inside 16px of padding on each side. This gives the icon visual breathing room and prevents it from looking cramped against neighboring listings.

At 128px you can use:

  • Gradients and shadows (rendered at full resolution)
  • More detailed iconography
  • Brand colors with full saturation
  • Subtle depth effects

What still does not work at 128px:

  • Realistic photography or photo textures (store reviews flag these as low effort)
  • Small text below 14px (unreadable on mobile store views)
  • Borders that mimic the rounded rectangle container Chrome adds automatically

Chrome adds its own rounded corners to your 128px icon in the Web Store UI. Do not bake rounded corners into your PNG unless you want double-radius corners. Export a square icon and let Chrome handle the mask.

The ExtensionBooster icon generator handles this automatically — it applies the right padding grid and exports all four sizes from a single source, including a correctly padded 128px version.


Badges: The Fifth Icon Problem

Badges are the red notification dots Chrome renders over your toolbar icon. They are not part of your icon files. They are rendered by the browser engine on top of your 16px icon using the chrome.action.setBadgeText API.

// Set a badge
chrome.action.setBadgeText({ text: "3" });
chrome.action.setBadgeBackgroundColor({ color: "#E53E3E" });

// Clear the badge
chrome.action.setBadgeText({ text: "" });

The badge renders in the bottom-right corner of your 16px icon. It covers approximately 6x6 pixels of your icon — roughly 14% of the total surface area. Design your icon shape so that the bottom-right corner is expendable. Do not place a critical part of your symbol in the zone a badge will cover.

Badge text is limited to 4 characters, but anything over 2 characters is too small to read in the badge at 16px. Use “9+” instead of “12”, ”!” instead of a full word.

Distinguishing badge notifications from the icon itself matters. If your icon is red and your badge is red, users cannot tell at a glance whether there is a notification. Contrast your badge color against your dominant icon color. Most extensions use red or orange badges — if your icon is those colors, switch your badge to a dark neutral or blue.


Manifest Wiring for Dynamic Icon States

Some extensions need to change their icon based on state — active vs. inactive, enabled vs. paused, signed in vs. signed out. Chrome supports this through chrome.action.setIcon().

// Switch to inactive state icon
async function setInactiveState() {
  await chrome.action.setIcon({
    path: {
      "16": "icons/icon-inactive-16.png",
      "32": "icons/icon-inactive-32.png"
    }
  });
}

// Switch back to active state icon
async function setActiveState() {
  await chrome.action.setIcon({
    path: {
      "16": "icons/icon-16.png",
      "32": "icons/icon-32.png"
    }
  });
}

setIcon() accepts path (file paths) or imageData (raw pixel data from a canvas). The path approach is simpler for static state switching. The imageData approach is necessary if you need to render dynamic content — a progress ring, a live counter drawn into the icon, a color that changes based on data.

For imageData rendering:

function drawCounterIcon(count) {
  const canvas = new OffscreenCanvas(16, 16);
  const ctx = canvas.getContext("2d");

  // Background circle
  ctx.fillStyle = "#4F46E5";
  ctx.beginPath();
  ctx.arc(8, 8, 7, 0, Math.PI * 2);
  ctx.fill();

  // Number — only works for 1-2 digit counts
  ctx.fillStyle = "#FFFFFF";
  ctx.font = "bold 8px sans-serif";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.fillText(String(count), 8, 9);

  return ctx.getImageData(0, 0, 16, 16);
}

chrome.action.setIcon({
  imageData: {
    "16": drawCounterIcon(myCount)
  }
});

One caution with imageData: the canvas renders text using the system font stack, which varies across operating systems. Test on Windows, macOS, and Linux if text inside the icon matters. The sans-serif family renders noticeably differently across platforms at 8px.


Flat design icon set displayed on a dark background

Branding Consistency Across Sizes

The goal is not pixel-perfect reproduction across all four sizes. The goal is consistent recognition.

A user who sees your 128px icon in the Web Store should immediately recognize the 16px icon in their toolbar. That recognition relies on:

  1. Shape identity — the core symbol stays the same across sizes, even if simplified
  2. Color signature — dominant hue stays consistent regardless of size
  3. Silhouette — the outer shape of your icon reads identically at all sizes

A common mistake: using a detailed, multi-element illustration at 128px and an unrelated simple shape at 16px. The sizes feel like two different products. Users who install from the store and then look at their toolbar do not connect them.

The right approach: define your 16px version first (the stripped-down core), then build 48px and 128px versions that are detailed expansions of the same visual idea.

Test your icon in context before shipping:

  • Pin your extension in Chrome and look at the toolbar icon next to a tab’s favicon
  • Switch Chrome between light mode and dark mode and verify both work
  • Compare your icon against neighboring extension icons in the toolbar — does it hold up?
  • Zoom the browser to 150% (common on Windows with HiDPI displays) and check pixelation

The comparison test is underrated. If your icon looks like a visual copy of an existing popular extension’s icon, users will confuse them. Distinctiveness at 16px is a competitive requirement, not a design preference.


The Common Mistakes, Listed Directly

Using a screenshot of your UI as the icon. Screenshots compress into unrecognizable noise below 64px. Never do this.

Designing only the 128px version. Chrome will scale it down. The result will be blurry. See the first section of this guide.

White background instead of transparent. It will look like a white square on dark-themed browsers.

Thin decorative strokes. They disappear. Minimum 2px at 16px, minimum 3px at 32px.

Ignoring the badge coverage zone. If you have a notification badge, your icon’s bottom-right corner will be obscured. Account for it.

Submitting without testing on Windows. macOS renders icons slightly differently due to font rendering and antialiasing. A toolbar icon that looks crisp on macOS can look muddy on Windows. Test both.

Forgetting to declare icons in both icons and action.default_icon. Chrome uses different fallback chains for each. An icon missing from action.default_icon might show a default gray puzzle piece in the toolbar even if icons is fully declared.


Generating and Exporting: The Practical Pipeline

If you are working in Figma:

  1. Create frames at 16px, 32px, 48px, and 128px
  2. Design each independently — do not use the same components scaled
  3. Export as PNG with no background (transparent)
  4. Name them icon-16.png, icon-32.png, icon-48.png, icon-128.png

If you want to skip the multi-size design process, ExtensionBooster’s icon generator takes a single source image and produces all four sizes with correct padding, pixel alignment, and transparent background handling built in. It is faster than the manual Figma approach for developers who are not designers.

For the manifest, double-check that every declared path resolves relative to the extension root, not relative to the manifest file location. A common packaging error is placing icons in a subdirectory but declaring them as flat paths in the manifest.


Developer reviewing icon designs on a large monitor with design tools open

What Good Looks Like

The best extension icons share a few properties: they are simple enough to read at arm’s length at 16px, distinctive enough to not be confused with similar tools, and consistent enough that the toolbar version and the store version feel like the same product.

Grammarly’s green circle. 1Password’s keyhole. LastPass’s asterisk. All of these are immediately recognizable at 16px because they chose one shape, one dominant color, and they never compromised that decision for detail.

Your icon is not decoration. It is the only persistent visual presence your extension has in the user’s browser. The toolbar is premium real estate. Design for that 16px rectangle like it is the most important design surface in your product — because for user retention and recall, it is.

Get the technical implementation right with the manifest snippets above, get the design constraints right with the pixel-aligned, high-contrast approach outlined here, and your extension will hold its own in a toolbar full of competing icons.

The rest is shipping.

Share this article

Build better extensions with free tools

Icon generator, MV3 converter, review exporter, and more — no signup needed.

Related Articles