Updated on Jun 3rd, 20218 min readreactjavascriptgraphics

React SVG Icons With No Artistic Abilities

Are you sick of the same old icons you have been using in your projects lately? Do you lack the artistic ability to draw a stick figure? If you answered yes (or no), please continue reading.

My SVG Issue

Since I began building things with JavaScript I have been using essentially the same icon set over and over. I often work with React and Styled Components so my go-to icon library has been Styled Icons. Styled Icons contains the same familiar icon sets we have probably all used at some point: Font Awesome, Material Design, Boxicons, etc.

Even though there are thousands of choices and all of these icon collections are great in their own right, I got to the point where I couldn't find the right icons for my use cases and all my projects sort of looked the same. I thought creating my own icon set was way out of reach due to my complete lack of artistic talent. Turns out I was wrong.

The solution to my problem was Scalable Vector Graphics, or SVG. To get started, all that is required is some kind of SVG editor. Here is a list of 7 free SVG editors. My personal preference is Boxy SVG, but Adobe Illustrator is also a solid program.

The great part about working with SVG is that mathematical skills can be just as important than artistic skills. Boxy SVG has a ton of settings and taking the time to familiarize yourself with them is worthwhile. Here are the basic steps I take to create my icons.

How I Design Custom SVG Icons

I used the Circle and the Pie tool to create this

Step 1 - Draw an Icon

  • Change the dimensions of the canvas to 50px by 50px
  • Geometry options help size and position elements
  • Backgrounds will be transparent unless you set the fill attribute
  • Make one 120 degree pie piece
  • Copy and Paste it two times
  • Rotate the pieces to fit
  • Put a circle on top of that
  • The inner circle has a 1px white stroke
  • Match colors with a Color Dropper Tool

Step 2 - Optimize your SVG

  • Save your icon as an svg file
  • Go to OMGSVG
  • Toggle the Show Original button to see the difference
  • Image / Markup tabs while both change based on settings
  • I generally use the default settings including Prettify Markup
  • Copy and Paste markup into your project
  • Drop all the xmln stuff since we are using these with inline HTML
  • Add a width attribute to the SVG or use CSS to style

// Cleaned up SVG markup
<svg width='200' viewBox='0 0 50 50'>
  <path
    d='M15.362 4.281a23 23 0 0 1 32.478 23.07l-22.898-2.16z'
    fill='#e94435'
  />
  <path
    d='M47.882 27.292a23 23 0 0 1-36.496 15.97l13.638-18.52z'
    fill='#35a755'
  />
  <path
    d='M11.569 43.37a23 23 0 0 1 4.762-39.552l9.037 21.15z'
    fill='#fabd05'
  />
  <circle cx='25' cy='25' r='8' stroke='#fff' fill='#3f84f3' />
</svg>

Step 3 - Create a Reusable React Component

One benefit of React is component reusability. We can leverage the functional nature of react to parameterize the name of an icon. This essentially abstracts the SVG markup into a single file and we can represent icons throughout an application with <Svg name='google' />.

  • Svg component will take name as props
  • The name prop will tell Svg what markup to return
  • Use React.Fragment shorthand <></>
  • Add as many icons as you need
  • Use like any other React component
Svg.js
import React from 'react'

// Pass any additional props via destructuring ...rest
function Svg({ name, ...rest }) {
  // Helper function to return inner svg elements
  // Each icon has its own case
  // Throws error if no name prop is present
  const getPath = (n) => {
    switch (n) {
      case 'google':
        return (
          <>
            <path
              d='M15.362 4.281a23 23 0 0 1 32.478 23.07l-22.898-2.16z'
              fill='#e94435'
            />
            <path
              d='M47.882 27.292a23 23 0 0 1-36.496 15.97l13.638-18.52z'
              fill='#35a755'
            />
            <path
              d='M11.569 43.37a23 23 0 0 1 4.762-39.552l9.037 21.15z'
              fill='#fabd05'
            />
            <circle cx='25' cy='25' r='8' stroke='#fff' fill='#3f84f3' />
          </>
        )
      default:
        throw Error('name is required!')
    }
  }

  return (
    <svg viewBox='0 0 50 50' {...rest}>
      {getPath(name)}
    </svg>
  )
}

export default Svg

Step 4 - Using React Props

  • Set size via passing a width / height prop or via CSS
  • Pass fill or stroke as a prop to change colors
  • Check out these Chromium icons

Step 5 - Add More Icon Names

  • Add dot as a new case in a switch statement
  • Return a basic circle
  • Pass fill as a props
  • Set black as a default parameter
Svg.js
function Svg({ name, fill = 'black' }) {
  const getPath = (n) => {
    switch (n) {
      case 'dot':
        return (
          <>
            <circle cx='25' cy='25' r='8' fill={fill} />
          </>
        )
      case 'google':
        return (
          <>
            <path
              d='M15.362 4.281a23 23 0 0 1 32.478 23.07l-22.898-2.16z'
              fill='#e94435'
            />
            <path
              d='M47.882 27.292a23 23 0 0 1-36.496 15.97l13.638-18.52z'
              fill='#35a755'
            />
            <path
              d='M11.569 43.37a23 23 0 0 1 4.762-39.552l9.037 21.15z'
              fill='#fabd05'
            />
            <circle cx='25' cy='25' r='8' stroke='#fff' fill='#3f84f3' />
          </>
        )
      default:
        throw Error('name is required!')
    }
  }

  return <svg viewBox='0 0 50 50'>{getPath(name)}</svg>
}
Dot.js
<>
  <Svg name='dot' />
  <Svg name='dot' fill='rebeccapurple' />
  <Svg name='dot' fill='orangered' />
  <Svg name='dot' fill='greenyellow' />
</>

Final Thoughts

Now you know how to make your own icons and turn them into a simple and reusable React component. Hopefully, you agree with my premise that minimal artistic ability is required. I could even argue that the most important skill is understanding the features of your SVG editor.

There is a time investment here but I use working on these icons as a break from the more mind crunching code of my projects. I think the end results are websites and applications that look more authentic and are more engaging for the user.

Benjamin Brooke Avatar
Benjamin Brooke

Hi, I'm Ben. I work as a full stack developer for an eCommerce company. My goal is to share knowledge through my blog and courses. In my free time I enjoy cycling and rock climbing.