Fluent UI System Icons

repository·main·Indexed 27 days ago

https://github.com/microsoft/fluentui-system-icons

A collection of modern icons from Microsoft for use across Android, iOS, macOS, Flutter, and web via SVG. The library includes support for multiple sizes (16, 20, 24, 28, 48) and styles (regular, filled, selector). It provides platform-specific implementations, including VectorDrawable resources for Android, a Flutter package, and Swift support for iOS and macOS via CocoaPods or Carthage. Additional tools include @fluentui/eslint-plugin-react-icons and @fluentui/react-icons-atomic-webpack-loader for optimizing React bundles.

Tokens
29.1K
Snippets
99
Records
159
Agent score
94%

What's inside Fluent UI System Icons

  1. Understand Fluent UI System Icon styles and variants

    main

    The @fluentui/react-icons package provides icons as React components backed by SVG graphics. Icons are available in several styles:

    • Regular: The standard icon style.
    • Filled: A filled version of the icon.
    • Light: A subset of icons available in a light variant.
    • Color: A subset of icons available in a color variant.
    WARNING

    Color icon variants are deprecated due to accessibility issues. Use other variants where possible.

  2. Understand the Fluent UI System Icons versioning strategy

    main

    The library uses a unified release cycle across its monorepo. Unlike standard semantic versioning, both minor features (new icons) and patch updates (bug fixes) are released as PATCH version bumps only.

    • 2.0.X2.0.Y can include new features, icon additions, or breaking changes.
    • Major version bumps (2.X.X3.0.0) are reserved only for significant API redesigns.

    Recommendation: Always review the release notes when upgrading, even for patch versions, to check for icon changes.

  3. Use the Headless API for Fluent UI Icons

    main
    The Headless API is a drop-in replacement for the standard icon API that removes the CSS-in-JS (Griffel) runtime dependency. It uses HTML data-* attribute selectors for styling, making it suitable for any React setup (Vite, Next.js, Remix, etc.) without a CSS-in-JS runtime. It provides smaller JavaScript bundles by moving icon styling to static CSS files.
  4. Configure `@fluentui/react-icons-font-subsetting-webpack-plugin` for atomic imports

    main

    If you are using atomic imports from @fluentui/react-icons/fonts/* or @fluentui/react-icons/headless/fonts/*, you do not need to configure conditionNames. You only need to ensure font files are treated as webpack assets and include the plugin in your plugins array.

    // webpack.config.js
    const {
      default: FluentUIReactIconsFontSubsettingPlugin,
    } = require('@fluentui/react-icons-font-subsetting-webpack-plugin');
    
    module.exports = {
      module: {
        rules: [
          // Treat the font files as webpack assets
          {
            test: /\.(ttf|woff2?)$/,
            type: 'asset',
          },
        ],
      },
      plugins: [
        // Include this plugin
        new FluentUIReactIconsFontSubsettingPlugin(),
      ],
    };
  5. Setup the Headless API for SVG Icons

    main

    The Headless API is a drop-in replacement for the standard icon API that removes the CSS-in-JS runtime dependency by using data-* attribute selectors and a static CSS file.

    To use Headless SVG icons, you must import the headless CSS file in your application entry point to enable base icon layout and high-contrast mode support. Icons are grouped by kind and imported from @fluentui/react-icons/headless/svg/{icon-group}.

    Note: SVG sprites are not currently available in the Headless API.

    import '@fluentui/react-icons/headless/styles.css';
    
    import {
      AccessTime20Filled,
      AccessTime24Filled,
      AccessTime20Regular,
    } from '@fluentui/react-icons/headless/svg/access-time';
    import { Add16Filled, Add20Filled } from '@fluentui/react-icons/headless/svg/add';
    
    function MyComponent() {
      return (
        <>
          <AccessTime20Filled />
          <Add16Filled />
        </>
      );
    }
  6. Configure @fluentui/react-icons-svg-sprite-subsetting-webpack-plugin modes

    main

    The plugin optimizes @fluentui/react-icons/svg-sprite/* entrypoints by stripping unused <symbol> elements from SVGs. You can choose between three operating modes:

    • Atomic mode: Preserves original .svg imports. Each sprite is emitted as a separate, subsetted asset containing only the used symbols.
    • Merged mode: Rewrites .svg imports to a single runtime module. A single merged sprite asset is emitted containing all used symbols from all sources. Requires MergedSpriteRuntimeModule to set a global URL.
    • Inline mode: Rewrites .svg imports to an empty string. The merged sprite is built from symbols used by the HTML entrypoints and injected directly into the <body> tag of the HTML. Requires html-webpack-plugin.

    Mode Comparison Summary:

    AspectAtomicMergedInline
    SVG imports rewritten?NoYes (to mergedSpriteUrlModule)Yes (to inlineSpriteUrlModule)
    Runtime module injected?NoYes (MergedSpriteRuntimeModule)No
    Output assetsN subset sprite SVGs1 merged sprite SVGNone (embedded in HTML)
    HTML injectionOptional preload linksOptional preload linkInline <svg> in <body>
  7. Choose a Rendering Approach

    main

    Icons can be delivered using three different methods, depending on your requirements for bundle size, performance, and styling:

    1. Inline SVG (Default): Each icon is an SVG React component. Requires zero setup and offers full styling flexibility.
    2. Icon fonts: Uses a single font glyph per icon. This is best optimized for scenarios where a large number of icons are rendered on screen simultaneously.
    3. SVG sprites (Preview): Uses browser-cached sprite references. This provides small JavaScript bundles while maintaining pixel-perfect SVG quality.
  8. Optimize @fluentui/react-icons imports with Babel

    main

    For projects not using Webpack, you can use babel-plugin-transform-imports. This requires a helper function to resolve the icon name to its atomic module path.

    1. Create a helper file (e.g., fluent-icons-transform.js) containing the resolveFluentIconImport logic.
    2. Configure .babelrc.js to use this helper within the transform-imports plugin.
    // @filename fluent-icons-transform.js
    
    /**
     * Resolves a @fluentui/react-icons import name to its atomic module path.
     * @param {string} importName - The named export being imported.
     * @param {string} [target='svg'] - The target subpath (e.g. 'svg', 'svg-sprite', 'fonts', 'headless/svg', 'headless/fonts').
     * @returns {string} The resolved module path.
     */
    function resolveFluentIconImport(importName, target = 'svg') {
      if (importName === 'useIconContext' || importName === 'IconDirectionContextProvider') {
        return '@fluentui/react-icons/providers';
      }
    
      const match = importName.match(/^(.+?)(\d+)?(Regular|Filled|Light|Color)$/);
      if (!match) {
        return '@fluentui/react-icons/utils';
      }
    
      return `@fluentui/react-icons/${target}/${kebabCase(match[1])}`;
    }
    
    function kebabCase(str) {
      return str.replace(/[a-z\d](?=[A-Z])|[a-zA-Z](?=\d)|[A-Z](?=[A-Z][a-z])/g, '$&-').toLowerCase();
    }
    
    module.exports = { resolveFluentIconImport };
    // @filename .babelrc.js
    const { resolveFluentIconImport } = require('./fluent-icons-transform');
    
    module.exports = {
      presets: [
        // ... your preset configuration
      ],
      plugins: [
        [
          'transform-imports',
          {
            '@fluentui/react-icons': {
              // Change the second argument to match your target:
              //   'svg' | 'svg-sprite' | 'fonts' | 'headless/svg' | 'headless/fonts'
              transform: (importName) => resolveFluentIconImport(importName, 'svg'),
              preventFullImport: false,
              skipDefaultConversion: true,
            },
          },
        ],
      ],
    };
  9. Build the remove-unused-fluent-icons binary

    main

    To build the remove-unused-fluent-icons tool from source, navigate to the tool's directory and use the Swift build command with the release configuration. After building, copy the resulting binary to the root of the tool directory and rename it to run.

    cd ios/remove-unused-fluent-icons
    swift build -c release
    yes | cp .build/release/remove-unused-fluent-icons run