SVG to TypeScript/TSX Converter
raw JSON →svg-to-ts is a build tool that converts SVG icons into TypeScript or TSX files, facilitating the creation of tree-shakable icon libraries. It processes SVG files, applies optional SVGO optimization, and generates various output formats: a single TypeScript file exporting a constants object, multiple individual named constant exports, or separate files for each icon, optimized for lazy loading. It also automatically generates corresponding TypeScript types and interfaces for the icon sets. The current stable version is 12.0.0. The project maintains a consistent release cadence, often introducing major versions annually driven by updates to underlying tools like SVGO or advancements in TypeScript language features. Its key differentiators include robust SVGO integration for automatic optimization, broad support for Angular, React, and vanilla TypeScript/JavaScript environments, and the flexibility to produce diverse output structures tailored to different application architectures and lazy-loading strategies. This makes it a versatile solution for authors of component and icon libraries, as well as single-page application developers.
Common errors
error error TS2307: Cannot find module './my-icon.js' or its corresponding type declarations. ↓
.mjs extension: import { MyIcon } from './my-icon.mjs'; error TypeError: Cannot read properties of undefined (reading 'config') at SVGO.optimize ↓
svgoConfig object in the svg-to-ts configuration. Refer to the SVGO v3 documentation for the updated configuration syntax. error error TS1005: 'const' or 'let' expected. ↓
3.8 or higher: npm install typescript@^3.8. Warnings
breaking Version 12.0.0 drops support for TypeScript versions older than 3.8. Projects using `svg-to-ts` must upgrade to TypeScript 3.8 or newer to ensure compatibility and leverage new language features like `type` keyword usage in generated helpers. ↓
breaking Since versions 9.0.0 and 11.0.0, `svg-to-ts` generates ESM files with a `.mjs` extension instead of `.js`. Additionally, import/export statements within compiled files now explicitly use the `.mjs` extension. This change enhances compatibility with Node.js ESM loader and modern bundlers, but requires updating import paths in consuming applications. ↓
breaking Version 10.0.0 upgraded SVGO to version 3, which introduced significant changes to its configuration format. Existing `svgoConfig` options in your `svg-to-ts` configuration may become incompatible or behave differently. ↓
gotcha By default, `svg-to-ts` might generate icon names based on filenames, which can lead to naming collisions or unidiomatic names. It's crucial to manage naming conventions explicitly to maintain a clean and consistent icon library. ↓
Install
npm install svg-to-ts yarn add svg-to-ts pnpm add svg-to-ts Imports
- GeneratedIconEnum wrong
import GeneratedIconEnum from './path/to/generated-icons';correctimport { GeneratedIconEnum } from './path/to/generated-icons'; - ICON_NAME wrong
import * as Icons from './path/to/generated-icons';correctimport { ICON_NAME } from './path/to/generated-icons'; - IndividualIconComponent wrong
import { IndividualIconComponent } from './path/to/icon-name.js';correctimport { IndividualIconComponent } from './path/to/icon-name.mjs';
Quickstart
{
"name": "my-icon-library",
"version": "1.0.0",
"description": "My custom SVG icon library",
"scripts": {
"generate:icons": "svg-to-ts --inputDir ./src/assets/svg --outputDir ./src/app/icons --conversionType constants --prettier --interfaceName IIcons"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"svg-to-ts": "^12.0.0"
}
}
// src/assets/svg/home.svg
// <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
// src/app/icons/index.ts (generated output)
// This file is generated by svg-to-ts. Do not edit this file directly.
// If you want to change the icon names, please use the configuration file.
export const HOME = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>`;
// In your Angular/React/Vanilla TS component:
// import { HOME } from './app/icons';
// function MyHomeIcon() { return <div dangerouslySetInnerHTML={{ __html: HOME }} />; }