DEV Community

Cover image for Material‑UI Icons Built with SVGD Tooling
Anatolii S.
Anatolii S.

Posted on

Material‑UI Icons Built with SVGD Tooling

I’m delighted to share @svgd/icons-material — a single‑file Material‑UI icon pack I built with SVGD tooling! By leveraging @svgd/cli and @svgd/core, I’ve consolidated all 10,773 MUI icons into one optimised, tree‑shakable package complete with IDE autocomplete previews.


SVGD Tooling: Powering the Pack

  • @svgd/cli
    A flexible command‑line tool that scans your SVG source folders, extracts and optimises path data, and emits JavaScript/TypeScript constants, HTML previews, Markdown tables, and more. Configure input/output, customise plugins, and generate assets in seconds.

  • @svgd/core
    The runtime library that takes those path‑data constants and re‑creates valid SVG elements at render time. It provides TypeScript typings, embedded Base64 previews for instant IDE feedback, and a simple API:

  import { getPaths } from '@svgd/core';
  const paths = getPaths(iconName);
Enter fullscreen mode Exit fullscreen mode

These tools helped me streamline icon generation, reduce bundle size, and offer immediate visual feedback right in the editor.


Why an SVGD Icon Pack?

IDE‑friendly: See Base64‑encoded previews in autocomplete tooltips.
mui icons autocomplete

Fewer requests: One .js and one .ts file instead of thousands of tiny files.
One js and one ts file for mui icons

Zero runtime dependencies: Just string constants. You can use any UI framework.
Just strings constants for mui icons

TypeScript support: Complete .d.ts with embedded previews.
TypeScript support

Faster builds: Reduced bundler overhead.

Tree‑shakable: Import exactly the icons you need—nothing more.


Installation

npm install @svgd/icons-material
# or
yarn add @svgd/icons-material
Enter fullscreen mode Exit fullscreen mode

If you’re using React + MUI:

npm install react @mui/material
Enter fullscreen mode Exit fullscreen mode

Usage Examples

React

import React from 'react';
import { getPaths } from '@svgd/core';
import MuiSvgIcon, { SvgIconProps } from '@mui/material/SvgIcon';
import { Abc } from '@svgd/icons-material';

export function SvgIcon({ icon, ...props }: { icon: string } & SvgIconProps) {
  return (
    <MuiSvgIcon {...props}>
      {getPaths(icon).map((attrs, i) => (
        <path key={i} {...attrs} />
      ))}
    </MuiSvgIcon>
  );
}

// Usage:
<SvgIcon icon={Abc} fontSize="large" color="primary" />;
Enter fullscreen mode Exit fullscreen mode

Vue 3

<template>
  <svg :width="size" :height="size" viewBox="0 0 24 24">
    <path v-for="(attrs, i) in paths" :key="i" v-bind="attrs" />
  </svg>
</template>

<script setup lang="ts">
import { computed, defineProps } from 'vue';
import { getPaths } from '@svgd/core';
import * as icons from '@svgd/icons-material';

const props = defineProps<{ icon: string; size?: number }>();
const paths = computed(() => getPaths(props.icon));
</script>
Enter fullscreen mode Exit fullscreen mode

Angular

// svg-icon.component.ts
import { Component, Input } from '@angular/core';
import { getPaths } from '@svgd/core';

@Component({
  selector: 'svg-icon',
  template: `
    <svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24">
      <path *ngFor="let attrs of paths" [attr.d]="attrs.d" [attr.fill]="attrs.fill" />
    </svg>
  `,
})
export class SvgIconComponent {
  @Input() icon!: string;
  @Input() size = 24;
  get paths() {
    return getPaths(this.icon);
  }
}
Enter fullscreen mode Exit fullscreen mode

Use in your templates:

<svg-icon [icon]="icons.Abc" [size]="32"></svg-icon>
Enter fullscreen mode Exit fullscreen mode

Plain JavaScript

<!DOCTYPE html>
<html lang="en">
<body>
  <div id="root"></div>
  <script type="module">
    import { getPaths } from '@svgd/core';
    import { Abc } from '@svgd/icons-material';

    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('viewBox', '0 0 24 24');
    svg.setAttribute('width', '48');
    svg.setAttribute('height', '48');

    getPaths(Abc).forEach(attrs => {
      const path = document.createElementNS(svg.namespaceURI, 'path');
      Object.entries(attrs).forEach(([k, v]) => path.setAttribute(k, v));
      svg.appendChild(path);
    });

    document.getElementById('root')!.appendChild(svg);
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Dive Deeper

I’d love to hear from you: which icon set would you like to see in a similar format?

Top comments (0)