Enterprise Design Systems / Developer Experience (DX) / Tooling & Automation

3M Enterprise Icon Library

From manual icon handoffs to an automated code pipeline.

After a restructuring, two 3M icon sets became my responsibility. I replaced a Figma-to-OneDrive handoff with an npm package, a searchable catalog and an automated validator, so developers no longer had to message me for files.

Role
Lead UX Designer & Design System Architect
Team
Solo architecture lead, working with SIBG and Enterprise Core engineering
Timeline
6 Months
Tools
Figma, Figma REST API, TypeScript, Node.js, GitHub Actions, npm, GitHub Pages, LLM-assisted coding

Developers had to message me for every icon.

After 3M restructured, I became the only maintainer of two icon libraries: the Safety & Industrial Business Group (SIBG) set and 3M Corporate’s company-wide set. The icons were usable. Getting them to developers was the problem.

0 iconsHover an icon to see its name and release
Figure 1.0. A sample of the unified library, rendered from the source SVGs. Hover an icon to see its name.

Delivery was manual. I exported SVGs from Figma or Illustrator, built an icon font in IcoMoon, and uploaded the TTF to OneDrive. Any request that didn’t fit that path reached me as a direct message.

  • Every request from every product division arrived in my DMs. A five-minute handoff took one to two days.
  • Developers could only find out that an icon existed if someone had pasted it into a design.
  • In interviews, some developers didn’t know the font existed. Others skipped it because it didn’t work with their frameworks.
  • SIBG drew on a 24 × 24 canvas and named icons by function (safety). Corporate used a 16 × 16 canvas and named them by shape (hard-hat). Scaling icons by hand left blurry half-pixel strokes.

A package, a catalog and an automated build.

I replaced the manual handoff with a pipeline from Figma to production code, and with a catalog that developers can use without a Figma license or a message to me.

Before1–2 days per request
Design filesFigma, Illustrator
IcoMoonHand-built TTF font
OneDriveicon-font.ttf
Developers · 0% font adoption
Got the helmet icon?Need a 24px PNGIs there a truck?Any update?Requests that miss the font go to one designer as direct messages.
Afterno manual steps
FigmaSingle source
REST APIHeadless extract
GitHub Actionsvalidate:strict → build
npm · cds-iconsReact, TSX, SVG, HTML
GitHub PagesIcon Navigator
Developers · self-serve
Figure 2.0. The same request before and after. In the old flow it stalls at OneDrive and turns into direct messages.
npm package (cds-icons)

Tree-shakeable React, TSX, SVG and HTML components with IDE autocomplete, published through the enterprise registry.

Icon Navigator

A searchable catalog on GitHub Pages where developers preview variants, copy snippets and download assets.

Build pipeline

A Node.js build reads Figma’s REST API, normalizes the vectors and publishes to npm on every push through GitHub Actions.

Figma plugins

Audit and migration plugins that let designers replace hundreds of legacy icons without losing color or size overrides.

Searching and filtering

Developers search by what an icon looks like, not by what a department called it. The Navigator filters by keyword, category, release and stroke or fill variant, and each result links to a code snippet and a download. The demo below runs a short tour, then responds to your input.

Corporate Design System
0 / 0 icons

Loading catalog…

Figure 2.1. A rebuild of the Navigator using the production icon source (579 icons at the time of writing).

Exporting

Developers also needed PNGs at several sizes, ICO files for desktop apps, and icons in specific colors. The Navigator handles this in the browser. It recolors the SVG, draws it on a canvas at each size, and packages the results as a ZIP or an ICO file. No server is involved.

  1. 1Source
  2. 2Recolor
  3. 3Rasterize
  4. 4Package
Source · swatch.svg
<svg viewBox="0 0 16 16">
  <path d="…"
    fill="currentColor" />
</svg>
Rasterize · canvas → PNG ×0
Package · ZIP
    ·

    Each size is drawn on a canvas in your browser and zipped into a real file.

    Figure 2.2. The export steps. The tiles and byte counts are generated in your browser, and the download button saves the file.

    Developers needed a way to find and install icons.

    The brief was to merge the SIBG set into Corporate and redraw the missing icons. Developer interviews showed that new artwork wouldn’t change their situation. They had enough vectors and no practical way to find or install them.

    The briefWhat I found
    Merge SIBG into Corporate and redraw the missing icons.Delivery was the problem, not the artwork. Polished vectors don’t help while developers still message someone for each file.
    Publish an icon font to OneDrive.Developers use tree-shakeable packages. A font adds download weight, has no TypeScript types and can’t be styled in code.

    I treated Figma as a content source instead of a handoff file. Engineers get icons through npm and GitHub Pages, and designers migrate legacy files with plugins.

    What each group ran into

    GroupWhat I sawWhyWhat I changed
    Front-end engineersPasted inline SVGs into code instead of using the font.The font shifted rendering, had no React types and increased bundle size.Shipped cds-icons with typed, tree-shakeable components.
    Contract developersAsked for files over Slack.They had no Figma seat and no way to browse the library.Shipped the Navigator with SVG download and code copy.
    Design system teamQA was disorganized during the 600-icon migration.Each icon needed checks for size, padding, radius and metadata.Built a Status Tracker widget that tracks color, radius, sizing, layers, naming and tags.
    Product designersDelayed library updates.They feared broken layouts, and swapping a component reset custom colors.Wrote a migration plugin that copies overrides to the new component.

    Five decisions, most enforced by code.

    I maintained over 600 icons alone, so I couldn’t review each one by hand. I turned most decisions into rules that a machine can check.

    Decision 1: Name icons by shape

    In the old system, searching for “helmet” returned nothing because the icon was named safety. Engineers search by what an icon looks like, so I standardized on shape-based names. chart-trend-up-arrow replaces sales.

    Synonyms go in each component’s description field in Figma. The truck icon, for example, carries commerce, delivery, shipping, logistics, freight. The build script parses that field into a JSON index for the Navigator’s fuzzy search. Searching for “helmet” in Figure 2.1 finds hard-hat this way.

    Decision 2: Two routes to the same icons

    Contract and front-end developers had no enterprise Figma seats, and non-developers had no enterprise GitHub access. Engineers use the Navigator on GitHub Pages for snippets, bundle previews and downloads. PMs and designers use a Figma component library inside the workspace they already have. Figma is the source for both.

    Decision 3: One grid for every icon

    Shrinking 24 × 24 icons to 16 × 16 by hand put strokes on fractions of a pixel, and compound icons such as status badges had no common rule. Every icon is now drawn in Icon Studio, a 16 × 16 frame with one pixel of padding and strokes on whole or half units.

    Compound icons follow a second template, Sub-Icon Studio. An 8 × 8 modifier sits in the bottom-right corner and cuts a small knockout out of the icon beneath it. The sub-icon set is not released yet.

    Icon Studio

    256px | 1:1616 × 16

    16 × 16 frame · 1px padding · 14 × 14 live area

    Figure 3.0. Icon Studio and Sub-Icon Studio, drawn with the swatch icon and the unreleased sub-icon set.

    Decision 4: Validate the rules in CI

    Written guidelines get skipped under deadline, and a reviewer can’t reliably spot a hard-coded hex value inside a path. The 20 rules in docs/constitution.md run as npm run validate:strict on every pull request, and a failing rule blocks the build. Five of them:

    • Rule 3: every icon declares viewBox=“0 0 16 16”. Legacy 0 0 17 16 files are normalized by script first.
    • Rule 4: fill and stroke can only be none, currentColor or inherit. Hex, rgb and named colors fail.
    • Rule 7: fill variants use the -fill suffix and a matching component name, such as HardHatFill.
    • Rule 12: icons are decorative by default, and consumers add a title when the icon carries meaning.
    • Rule 18: each component is a separate file with no side effects, so apps bundle only the icons they use.
    cds-icons — pull request #214
    Figure 3.1. A pull request with one hard-coded color is blocked, then fixed. The pull request is invented, and the counts come from the live catalog.

    Decision 5: Migrate files without losing overrides

    Replacing more than 600 deprecated icons by hand would have stopped design work, and Figma’s component swap resets custom colors when the inner layer names differ. I wrote the Icon Enforcer plugin in TypeScript. A rulebook generator (npm run generate:rulebook) produced 302 legacy-to-new pairings. The plugin scans a selection or page, stores each instance’s fill and size, swaps in the new component, and reapplies the overrides.

    </>Icon Enforcer

    Icon Enforcer

    Scan the selection or entire page to get started.

    Run a scan to find deprecated icons.
    Figure 3.2. A rebuild of Icon Enforcer. Turn “Keep size” and “Keep overrides” on or off before replacing to see what each one preserves.

    Results

    600+
    Legacy icons consolidated across three releases (1.6: 332, 1.7: 245, 1.8: 31)
    < 60s
    Time from needing an icon to using it in code, down from one to two days
    0
    Routine Slack requests for PNG or SVG files
    • Icon requests now come through an Icon Studio template as structured contributions instead of ad-hoc asks.
    • GitHub Actions delivers each release to engineering automatically, which ended IcoMoon exports and unversioned OneDrive folders.
    • The SIBG library is retired, and its assets are standardized into the corporate set.

    What I learned

    Hardest challenge

    Publishing inside an enterprise. I had to work through internal GitHub compliance, repository permissions and release pipelines, which are outside a design lead’s usual scope.

    Key takeaway

    Governance is an infrastructure problem more than a policing one. Developers and designers adopted the npm package and plugins because they made their work easier.

    Next step

    Release Sub-Icon Studio: 8 × 8 modifiers on 16 × 16 icons, to standardize compound icons such as status badges and operational indicators.

    Related notes

    Next
    Answerama
    Full resolution preview