Building an icon library for React (EOS-Icons)

Vinayak Sharma
5 min readAug 24, 2021

I worked on developing an Icon library for React and Vue 2/3 during my Google Summer of Code’2021 with the EOS Design system (Python software foundation).

In this blog, I will walk through the entire process of developing an Icon library for React that supports tree-shaking aka dead code elimination. Tree-shaking is a necessary factor for an icon library or for a library that has multiple components.

Currently, EOS delivers icons via a set of well-documented methods, which chiefly include EOS-Icons Package (source), CDN, or direct download of icons in SVG/PNG formats from https://eos-icons.com/. I have developed an npm package that will deliver EOS Icons to its users as an independent component library. This will enable EOS to independently deliver its icons to various frameworks (e.g. React, Vue and Angular). Do check this page https://eos-icons.com/docs in case you plan to use EOS-Icons in your next web project.

Fetching Icons (SVG files)

The first step for building an Icon library is to fetch all the required SVG icons that you want to include in your library. In my case it was EOS-Icons, EOS maintains a set of outlined, filled, and animated icons in an npm package (https://www.npmjs.com/package/eos-icons).

There are multiple ways to do this step. The easiest one is to simply copy-paste all your SVG icons into a folder, but it might become a hectic approach if you have numerous frequently updated icons.

I used gulp for automating this process for copying different types of SVG from eos-icons to svg folder. The three different types of SVG -Outlined, Filled, and Animated are moved into separate folders under the svg folder to identify them easily during the final build. The gulp automation also helps in moving common function folders that are later utilized by the final SVG components.

Converting SVG into React components

The next process involves fetching all the SVG data in a sequential manner and converting them into a React component. For doing this task I used the fs readfile function for reading all the SVG files sequentially. Later this SVG data was inserted into a React component template and written as a “.tsx” file. The SVG data also gets modified at this step for supporting various different props. Here is a look at SVG(1K_Filled) before modification:

After modification:

The above modification allows us to control various different attributes of SVG like rotate, translate (Flip), Fill (color), className, and size.

After modifying the SVG, it is added to a React template that already has a Flip function as well as various different size values for handling size aliases like xs, s, base, m, l, xl, xxl, and xxxl. The default size is set to “m” which is 18px.

The following React template is used, the data variable holds the SVG data.

An index.tsx file also gets created during the execution of this script, the index.tsx file is responsible for exporting all the icons at the root level.

Icon Common Component

EOS-icons has two variants of icon, which is filled and outlined. The above script generates Icon components that hold the SVG value for either filled or outlined, in the following format — EOS_ICON_THEME

In order to provide the user with more level of control, we have added an extra component on top of the two themes (outlined/filled) by adding a common component. The common component has its name in the following way — EOS_ICON

This component has one extra prop compared to the single theme component, which is the theme prop. By default, the theme prop is equal to filled but upon supplying a string to the theme prop the user can easily change the variant of the icon.

Building the package

The components are completely built-in TypeScript but in order to support JavaScript-based React projects, it required a TypeScript build config for producing files that are supported by JavaScript. The two main build commands produce the project in commonjs (cjs) format as well as esnext format under lib and es folder respectively. These are the folders that will be published on npm and utilized by the users.

Testing the final package

One of the most important parts of a project is the tests that can be utilized to verify if or not the final build is working as expected. The advantage of having tests set up is that all of the future commits will have to go through the tests before getting merged in the codebase. This helps in making the final component package highly reliable.

The decision for picking JEST as the testing framework was largely based on the ease of testing React components that JEST provides. In an early PR, I added tests using snapshots which later turned out to be a not-so-good idea for testing. Later it was switched to a more robust way of testing by using the toHaveAttribute property for checking if the props are being applied to the SVG or not. The test suite consists of 4 different types which are — filled, outlined, common, and animated. This helps in verifying the state of the different types of SVGs.

Using the EOS-Icons React

After publishing the package to npm the last step is to produce the package in a React-based project.

The first step in order to use any npm package is to run the install command

The next and final step is to import the icons you wish to use into your React project!

To read more about props supported and size chart, kindly refer to — https://eos-icons.com/docs

Check out - https://github.com/EOS-uiux-Solutions/eos-icons-react to know more about EOS-Icons React, Do ⭐ star the repo and use it in your next React/Vue project!

Refer to storybook — for trying out the icon component — https://storybook.eos-icons.com

EOS-Icons — https://eos-icons.com

--

--