React SVG Icons With No Artistic Ablility

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.
Example Boxicons Chromium icon
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 I haven't tried any others 🙄.
The great part about working with SVGs is that mathematical skills are 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
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
Hints
- 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 and open your file. This web app is a cool utility that simplifies the markup required to render your svg.
- Change settings and 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
but customize when needed
The more complex your SVG the more dramatic the optimization
Original

Optimized

An SVG remains sharp despite scaling up size
- 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 takename
as props- The
name
prop will tellSvg
what markup to return - Use
React.Fragment
shorthand<></>
to return output
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
- Add as many icons as you need
- Use like any other React component
Step 4 - Other Ideas
- Set size via passing a
width
/height
prop or via CSS. Be creative here. - Pass
fill
orstroke
as a prop to change up colors
A couple small changes and we have the Chromium icon
- To simplify the concept lets add a
dot
icon
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>
}
Pass in a fill
prop. Note the use of a default parameter so we don't get errors if fill
is omitted.
<>
<Svg name='dot' />
<Svg name='dot' fill='rebeccapurple' />
<Svg name='dot' fill='orangered' />
<Svg name='dot' fill='greenyellow' />
</>
In Closing
Now you know how to make your own icons and turn them into a simple and reuseable 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.
**Examples From My Last Project