Skip to content
Axialis Developer Network

Guide

One icon system across web, Windows, macOS & Linux

Design one source icon set and export it to web SVG, Windows ICO, macOS ICNS, and Linux hicolor theme — with consistent naming, sizing, and visual coherence.

Updated

  • #icon-system
  • #ico
  • #icns
  • #svg
  • #linux
  • #cross-platform
  • #packaging
  • #favicon

Shipping an application across platforms means shipping icons in four different formats, at anywhere from four to ten different sizes, named according to three different conventions, installed into three different directory structures. The temptation is to treat each platform as a separate art project. That approach creates visual inconsistency, multiplies maintenance burden, and guarantees that somebody will ship the wrong asset to the wrong target at least once.

The better model is a single source of truth — a master SVG or a structured icon set — from which all platform-specific outputs are derived. This guide covers what each platform expects, how to keep a set coherent across them, and how to name and structure everything so the derivation process is repeatable.

The per-platform requirements at a glance

Platform Format Minimum required sizes Notes
Web (UI icons) SVG — (vector, scales freely) Must use viewBox; currentColor for theming
Web (favicon) ICO 16×16, 32×32 Include 48×48 for broader coverage; modern browsers also accept PNG
Web (PWA / touch) PNG 192×192, 512×512 Declared in manifest.json; also used for macOS Safari pinned tabs
Windows app icon ICO 16, 32, 48, 256 px 32-bit RGBA; ICO container holds all sizes in one file
macOS app icon ICNS 16, 32, 128, 256, 512 pt at 1× and 2× 10 images total; 1024×1024 for App Store / Finder previews
Linux app icon PNG in hicolor 16, 24, 32, 48, 64, 128, 256, 512 px Installed to /usr/share/icons/hicolor/<size>/apps/; also provide SVG in scalable/

These are the minimum sets. Many production apps include additional sizes for edge cases (Windows 24px for DPI scaling, macOS 64px for specific list views). Start with the minimums; add extras if QA surfaces blurriness.

Starting from a single source

The economics of maintaining multiple icon sets — even just two platforms — push hard toward a single master. Every visual tweak has to happen once, not four times. Every regression has to be caught once.

What the master should be

Your master should be a vector file: either a single SVG per icon, or an icon file format that stores multiple sizes alongside one another. The master works at the largest size you will ever need (practically: 1024×1024 for app icons, or 512×512 if you do not target the macOS App Store) and every smaller size is exported from it.

The master file should:

  • Use viewBox="0 0 [W] [H]" with no width/height attributes (so it scales cleanly to any export size).
  • Avoid effects that do not scale — thin hairline strokes that look good at 512px become invisible at 16px. Design cross-platform app icons with visible forms at small sizes in mind.
  • Be clean before it enters the derivation pipeline. See cleaning SVGs before you ship for what "clean" means in practice.

Small-size hinting

Below about 32px, most icons need some manual attention. Strokes thin enough to look elegant at 256px disappear at 16px. The convention is to design separate "small" versions of the icon — simplified outlines, thicker strokes, fewer details — and use the small version only for the 16px and 24px exports.

This is not optional for Windows: the Windows Shell uses the 16px icon extensively (Explorer list view, taskbar overflow), and a blurry downscaled 256px icon at 16px is immediately visible to users. Build the 16px variant explicitly.

Web: SVG for UI, ICO and PNG for identity

Web icons split into two distinct jobs:

UI icons (navigation, actions, decorations in your interface) should be SVG, inline-embedded or via <use>, with currentColor for theming. Size is irrelevant because they are vector. One file serves all contexts.

Identity icons (favicon, PWA icon, social card image) need specific bitmap exports because they are consumed by browser chrome, OS launchers, and external services — none of which can inherit CSS from your page. For this category you build from the master and export PNGs and ICO files at specific sizes.

A complete favicon family from a single source:

<!-- In <head> -->

<!-- Legacy browsers: ICO with 16, 32, 48 px embedded -->
<link rel="icon" href="/favicon.ico" sizes="any">

<!-- Modern browsers prefer SVG (fully scalable, respects prefers-color-scheme) -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml">

<!-- Apple devices (home screen bookmark) -->
<link rel="apple-touch-icon" href="/apple-touch-icon.png"><!-- 180×180 -->

<!-- PWA manifest -->
<link rel="manifest" href="/manifest.json">
// manifest.json (partial)
{
  "icons": [
    { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
    { "src": "/favicon.svg", "sizes": "any",            "type": "image/svg+xml" }
  ]
}

For a complete walkthrough of favicon and app icon families — including the apple-touch-icon sizes, maskable icon considerations, and how to generate all of these from one master — see the guide on favicon and app-icon families.

Windows: ICO format

Windows uses .ico files for application icons. An ICO file is a container that holds multiple PNG or BMP images at different sizes in a single file. Windows selects the most appropriate size at render time — the Shell never scales a size it has; it only falls back to scaling when the needed size is absent.

The four sizes that matter most for a modern Windows app icon:

  • 16×16 — Explorer list view, taskbar overflow, small toolbar buttons
  • 32×32 — Desktop shortcut (standard DPI), dialog title bars
  • 48×48 — Desktop shortcut (medium DPI), file open dialogs
  • 256×256 — Desktop shortcut (high-DPI / 4K), Explorer large icon view, Properties dialog

All layers should use 32-bit RGBA (not indexed color). The 256px layer is typically stored as a compressed PNG within the ICO container to keep file sizes reasonable.

The naming convention for Windows app icons is simply AppName.ico (or app.ico). Resources embedded in an executable (RC_ICON) also need the ICO file, but the naming there is defined by your resource compiler.

macOS: ICNS format

macOS uses .icns files, which similarly contain multiple representations. A complete ICNS for a modern macOS app contains 10 images — five logical point sizes, each at both 1× and 2× resolution for Retina displays:

Point size 1× export 2× export
16 pt 16×16 px 32×32 px
32 pt 32×32 px 64×64 px
128 pt 128×128 px 256×256 px
256 pt 256×256 px 512×512 px
512 pt 512×512 px 1024×1024 px

The 1024×1024 image is required for App Store submission and for the macOS Finder's large preview column.

macOS app icons conventionally have a rounded-rectangle canvas (the "squircle" shape that Apple enforces for App Store icons). The shape itself is a system mask applied at render time on modern macOS versions — you do not need to bake a rounded corner into your ICNS. Your icon should fill a square canvas. However, many teams still apply a squircle shape in their masters because it helps designers see the final visual result during review.

The .iconset format (a folder named AppName.iconset containing PNGs with standardized names like icon_16x16.png, icon_16x16@2x.png) is the source format; macOS iconutil compiles it into an ICNS. Most third-party tools abstract this step.

Linux: hicolor theme and .desktop files

Linux desktop environments follow the freedesktop.org Icon Theme Specification. The standard fallback theme — the one that applies when a theme-specific icon is not found — is hicolor. Installing your icon into hicolor guarantees it appears in any desktop environment, regardless of the active icon theme.

The directory structure for application icons under hicolor is:

/usr/share/icons/hicolor/
  16x16/apps/myapp.png
  24x24/apps/myapp.png
  32x32/apps/myapp.png
  48x48/apps/myapp.png
  64x64/apps/myapp.png
  128x128/apps/myapp.png
  256x256/apps/myapp.png
  512x512/apps/myapp.png
  scalable/apps/myapp.svg

The freedesktop.org specification notes that you should install at minimum a 48×48 PNG. In practice, providing 16, 32, 48, 128, 256, and 512 px, plus an SVG in scalable/, gives good coverage across all common desktop environments (GNOME, KDE, XFCE, etc.) and scales to HiDPI displays.

After installing icons, the hicolor theme cache must be updated. Package managers handle this via post-install hooks; if you are distributing outside a package manager, the gtk-update-icon-cache command updates the cache.

The .desktop file

Linux applications are registered with the desktop environment via a .desktop file placed in /usr/share/applications/. The Icon field references the icon by name (without path or extension), and the desktop environment resolves it through the icon theme lookup chain:

# /usr/share/applications/myapp.desktop
[Desktop Entry]
Type=Application
Name=My App
Exec=/usr/bin/myapp %U
Icon=myapp
Categories=Graphics;

The Icon=myapp value tells the desktop environment to find an icon named myapp in the active icon theme. Because you installed myapp.png and myapp.svg into hicolor, this lookup will succeed even if the user is running a theme that does not include a custom version of your icon.

Keeping a set visually coherent

Visual coherence across platform outputs is harder than it sounds. A stroke-based icon that reads cleanly as an SVG at 24px often looks spindly or weak at 512px when used as a macOS app icon. Conversely, an app icon designed to look rich and detailed at large sizes tends to turn into visual noise when used as a 16px ICO.

Practical rules for maintaining coherence:

  • Design your app icon and your UI icon as related but distinct objects. The app icon is a brand mark with depth, shadow, and decoration appropriate to its display size. The UI icon is a functional glyph. They share the same visual language, not the same file.
  • Use the same grid and proportional system. If your UI icons follow a 24×24 grid with 2px strokes, your app icon's forms should feel like they came from the same design hand — even if they have more detail.
  • Validate at every target size before shipping. Export each size, view it at 100% in the context it will appear, and check that it is legible and intentional-looking. A tiny version of your logo that blurs into an unrecognizable blob is worse than a simplified, purposefully designed small icon.
  • Name files consistently. A system where myapp-16.png and myapp_16x16.png and myapp@16.png all exist in different places for different platforms is a maintenance trap. Choose one naming convention and apply it across the pipeline.

A naming convention that works across all platforms

Output Suggested filename Notes
Web SVG (UI) icon-[name].svg Used inline; filename is documentation
Web favicon favicon.ico, favicon.svg Fixed names; expected by browsers at root
Web PWA icon-192.png, icon-512.png Size-suffixed; declared in manifest
Windows [AppName].ico Matches application executable name
macOS source [AppName].iconset/ Folder compiled by iconutil
macOS output [AppName].icns Placed in AppName.app/Contents/Resources/
Linux PNG [lowercase-app-id].png Matches the Icon= value in .desktop; lowercase, no spaces
Linux SVG [lowercase-app-id].svg Same name, scalable/ directory

Keeping the Linux icon name lowercase and space-free is important: the Icon field in .desktop files is case-sensitive, and names with spaces require quoting that not all desktop environments handle correctly.

The pipeline in practice

A working cross-platform icon pipeline looks like this:

  1. Master source — one high-resolution master (SVG or layered file) per icon, stored in version control.
  2. Cleanup pass — automated SVG optimization runs on every commit; see cleaning SVGs before you ship.
  3. Export step — a build task (or a dedicated tool) generates every target: SVG UI icons, ICO, ICNS, and hicolor PNGs. This step is deterministic and scripted — no one exports icons by hand.
  4. QA check — exported files are visually verified at each size on each platform. Ideally automated via pixel-diff or a screenshot-based check.
  5. Packaging and delivery — the right files land in the right places: web assets in your CDN, .ico and .icns in the application bundle, Linux PNGs in the distribution package. For the packaging side of this, see the guide on packaging and final delivery.

Every step should be repeatable from the master. If someone has to manually export an ICO and drop it into a folder, the pipeline has a gap.