<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zander Martineau</title>
    <description>The latest articles on DEV Community by Zander Martineau (@mrmartineau).</description>
    <link>https://dev.to/mrmartineau</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F28442%2Fe09069f9-8e16-41d6-b2da-6d0d27758a98.jpg</url>
      <title>DEV Community: Zander Martineau</title>
      <link>https://dev.to/mrmartineau</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrmartineau"/>
    <language>en</language>
    <item>
      <title>Styling React 2023 edition</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Thu, 02 Nov 2023 16:50:29 +0000</pubDate>
      <link>https://dev.to/mrmartineau/styling-react-2023-edition-3dg5</link>
      <guid>https://dev.to/mrmartineau/styling-react-2023-edition-3dg5</guid>
      <description>&lt;h2&gt;
  
  
  My approach for using PostCSS, Tailwind, cva and a few others tools to style react apps and components
&lt;/h2&gt;

&lt;p&gt;Over the past few years, I've worked with React apps utilising various CSS-in-JS libraries, starting with &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt;, transitioning through &lt;a href="https://emotion.sh/docs/introduction" rel="noopener noreferrer"&gt;emotion&lt;/a&gt;, &lt;a href="https://theme-ui.com/" rel="noopener noreferrer"&gt;Theme UI&lt;/a&gt;, and finally &lt;a href="https://stitches.dev/" rel="noopener noreferrer"&gt;Stitches&lt;/a&gt;. I've also integrated MUI, Mantine, and Chakra in numerous client projects.&lt;/p&gt;

&lt;p&gt;While I didn't always opt for CSS-in-JS, I frequently chose it for its ubiquity — everyone was using it, and I was aboard the hype train 🚂. I knew there was an performance overhead when compared to vanilla CSS however, I was oblivious to how detrimental its impact on performance was until I read Sam Magura's article, &lt;a href="https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b"&gt;"Why We're Breaking Up with CSS-in-JS"&lt;/a&gt;. This piece prompted me to search for a new standard in styling React apps. I believe I've found it, not in a single tool, but in a harmonious blend of various utilities.&lt;/p&gt;

&lt;p&gt;TLDR; these are the tools I use to style React apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://postcss.org/" rel="noopener noreferrer"&gt;PostCSS&lt;/a&gt; (or Sass)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cva.style/docs" rel="noopener noreferrer"&gt;CVA&lt;/a&gt; (class-variance-authority)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://utopia.fyi/" rel="noopener noreferrer"&gt;Utopia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open-props.style/" rel="noopener noreferrer"&gt;Open Props&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/lukeed/clsx" rel="noopener noreferrer"&gt;clsx&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/dcastil/tailwind-merge" rel="noopener noreferrer"&gt;tailwind-merge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PostCSS
&lt;/h3&gt;

&lt;p&gt;I use &lt;a href="https://postcss.org/" rel="noopener noreferrer"&gt;PostCSS&lt;/a&gt; to extend CSS’s features and to add a few things that make writing styles a little more convenient, but it could easily be swapped for another preprocessor like Sass or vanilla CSS. It’s up to you. You can view my PostCSS config &lt;a href="https://github.com/mrmartineau/Otter/blob/main/postcss.config.json" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Typically styles are colocated with the components or pages that they concern, but I also include a base line of styles that are used across the app. I use a &lt;a href="https://github.com/mrmartineau/otter-2/blob/main/app/globals.css" rel="noopener noreferrer"&gt;&lt;code&gt;global.css&lt;/code&gt;&lt;/a&gt; file to import these files, which is then imported into the main app entrypoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tailwind
&lt;/h3&gt;

&lt;p&gt;I find &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt; useful when used sparingly, it is perfect for allowing me to append certain styles to an element on an ad-hoc basis. For example, I like to use it to add classes to elements to add some margin or to make a flex container when I don’t want to make a new bespoke class declaration. I got the idea from Andy Bell’s &lt;a href="https://www.youtube.com/watch?v=5uhIiI9Ld5M" rel="noopener noreferrer"&gt;"Be the browser’s mentor, not its micromanager"&lt;/a&gt; talk from All Day Hey 2022.&lt;/p&gt;

&lt;p&gt;You can view my Tailwind config &lt;a href="https://github.com/mrmartineau/otter-2/blob/main/tailwind.config.js" rel="noopener noreferrer"&gt;here&lt;/a&gt;, it is a little different to the default config, I have extended the spacing and font-size scales, added a few extra colours and some other bits and bobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  CVA
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://cva.style/docs" rel="noopener noreferrer"&gt;CVA&lt;/a&gt; or &lt;strong&gt;class-variance-authority&lt;/strong&gt; is a excellent package that makes it easy to create style variants for components. I do not use CVA for all components, only the ones that need different variants, e.g. buttons and other UI primitives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utopia
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Utopia is not a product, a plugin, or a framework. It’s a memorable/pretentious word we use to refer to a way of thinking about fluid responsive design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using the various tools on Utopia’s &lt;a href="https://utopia.fyi/" rel="noopener noreferrer"&gt;website&lt;/a&gt;, you can copy the CSS custom properties that are output and add them to your styles. These properties are responsive, which means the values scale based on the viewport size. Follow &lt;a href="https://utopia.fyi/type/calculator?c=320,18,1.2,1240,20,1.25,5,2,&amp;amp;s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&amp;amp;g=s,l,xl,12" rel="noopener noreferrer"&gt;this link&lt;/a&gt; for an example font-size scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Props
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://open-props.style/" rel="noopener noreferrer"&gt;Open Props&lt;/a&gt; adds to the set by providing extra custom properties for things like easing functions or animations.&lt;/p&gt;

&lt;h3&gt;
  
  
  clsx and tailwind-merge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/lukeed/clsx" rel="noopener noreferrer"&gt;clsx&lt;/a&gt; is a tiny utility for constructing &lt;code&gt;className&lt;/code&gt; strings conditionally, I use it in conjunction with &lt;a href="https://github.com/dcastil/tailwind-merge" rel="noopener noreferrer"&gt;tailwind-merge&lt;/a&gt; which merges Tailwind CSS classes without style conflicts.&lt;/p&gt;

&lt;p&gt;I use a &lt;code&gt;cn()&lt;/code&gt; function that was ripped from &lt;a href="https://ui.shadcn.com" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt;, it is a simple utility that conditionally joins classnames together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ClassValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clsx&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;twMerge&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwind-merge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cn&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ClassValue&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;twMerge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;clsx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Basic component
&lt;/h3&gt;

&lt;p&gt;For a simple component, I import a CSS file (&lt;code&gt;TheComponent.css&lt;/code&gt;) into the component file (&lt;code&gt;TheComponent.jsx&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;TheComponent&lt;/span&gt;&lt;span class="nc"&gt;.css&lt;/span&gt;
&lt;span class="nc"&gt;.component-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TheComponent.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./TheComponent.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TheComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"component-wrapper"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Component without variants
&lt;/h3&gt;

&lt;p&gt;In this slightly more complex example the &lt;code&gt;cn&lt;/code&gt; function is used to merge a specific class with the classes passed to the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ComponentPropsWithoutRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/src/utils/classnames&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./TheComponent.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TheComponentProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ComponentPropsWithoutRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TheComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;TheComponentProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thecomponentClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component-wrapper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;thecomponentClass&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Component with variants
&lt;/h3&gt;

&lt;p&gt;As mentioned above, when using variants, I use CVA. The way that the &lt;code&gt;Props&lt;/code&gt; TypeScript types are setup ensure that the &lt;code&gt;cva&lt;/code&gt; variants are included in the component's props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/src/utils/classnames&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VariantProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cva&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;class-variance-authority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ComponentPropsWithoutRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Button.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buttonVariants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cva&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;l&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-l&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;defaultVariants&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;
  &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ComponentPropsWithoutRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;VariantProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;buttonVariants&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;cn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;buttonVariants&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"l"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Hello
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or you can use the &lt;code&gt;buttonVariants&lt;/code&gt; helper to create a link that looks like a button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;buttonVariants&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click here&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://ui.shadcn.com" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt; served as an excellent source of inspiration for this approach to styling React apps. It leans more heavily on Tailwind, so if that's your thing, I recommend checking it out.&lt;/p&gt;




&lt;p&gt;The great thing about this approach is that it is flexible, you can use as much or as little of it as you like and without much modification, it can be used in an Astro, Svelte or Vue app. I've found that it works well for me, and I hope it works well for you too.&lt;/p&gt;

&lt;p&gt;You can see methods from this post used in practice for &lt;a href="https://github.com/mrmartineau/Otter" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmrmartineau%2FOtter%2Fmain%2Fpublic%2Fotter-logo.svg"&gt;&lt;/a&gt;, my personal bookmarking app side-project.&lt;/p&gt;




&lt;p&gt;This was originally posted on my blog at &lt;a href="https://zander.wtf/blog/styling-react" rel="noopener noreferrer"&gt;https://zander.wtf/blog/styling-react&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Avoid being tracked on the web</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Sun, 08 Sep 2019 06:27:55 +0000</pubDate>
      <link>https://dev.to/mrmartineau/avoid-being-tracked-on-the-web-1pdm</link>
      <guid>https://dev.to/mrmartineau/avoid-being-tracked-on-the-web-1pdm</guid>
      <description>&lt;h2&gt;
  
  
  A few tips to keep you a bit more invisible
&lt;/h2&gt;

&lt;p&gt;So, you don't want to be tracked online 🙅 by advertisers &amp;amp; analytics scripts etc? What do you do? You need to block them. There are many different ways to achieve this, but I use a few different tools and services to block all these guys.&lt;/p&gt;

&lt;p&gt;➡️ Visit &lt;a href="https://github.com/StevenBlack/hosts#list-of-all-hosts-file-variants" rel="noopener noreferrer"&gt;github.com/StevenBlack/hosts#list-of-all-hosts-file-variants&lt;/a&gt; and find the "hosts" recipe that you'd like. The "Unified hosts = (adware + malware)" should be sufficient, but you can also find ones that block porn and/or gambling content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzanderwtf.cdn.prismic.io%2Fzanderwtf%2F248fd4298643dd9149d830671f263036598d0be8_screenshot-2019-09-07-at-15.26.00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzanderwtf.cdn.prismic.io%2Fzanderwtf%2F248fd4298643dd9149d830671f263036598d0be8_screenshot-2019-09-07-at-15.26.00.png" alt="A screenshot of the table of block recipes provided by the StevenBlack repo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're on a Mac, download Gas Mask (free) from &lt;a href="http://clockwise.ee/" rel="noopener noreferrer"&gt;clockwise.ee&lt;/a&gt;. If you're on Windows, you can try Unified Hosts AutoUpdate from &lt;a href="https://github.com/ScriptTiger/Unified-Hosts-AutoUpdate" rel="noopener noreferrer"&gt;github.com/ScriptTiger/Unified-Hosts-AutoUpdate&lt;/a&gt;. Both will allow you to select one of the hosts lists (mentioned above) and have it auto-update at regular intervals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzanderwtf.cdn.prismic.io%2Fzanderwtf%2F24385952ba39f04ac6186c6b967225d31eff66ac_screenshot-2019-09-07-at-15.31.24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzanderwtf.cdn.prismic.io%2Fzanderwtf%2F24385952ba39f04ac6186c6b967225d31eff66ac_screenshot-2019-09-07-at-15.31.24.png" alt="Screenshot of the Gas Mask app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Gas Mask can reference remotely hosted files, but only if they're not https, so use the "Non Github mirror" links from &lt;a href="https://github.com/StevenBlack/hosts#list-of-all-hosts-file-variants" rel="noopener noreferrer"&gt;github.com/StevenBlack/hosts#list-of-all-hosts-file-variants&lt;/a&gt;, like this one: &lt;a href="http://sbc.io/hosts/hosts" rel="noopener noreferrer"&gt;sbc.io/hosts/hosts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With this setup, visit an ad-riddled site like &lt;a href="http://theverge.com/" rel="noopener noreferrer"&gt;theverge.com&lt;/a&gt; or &lt;a href="http://mashable.com/" rel="noopener noreferrer"&gt;mashable.com&lt;/a&gt; and see that there are no ads anymore.&lt;/p&gt;

&lt;p&gt;By the way, these hosts files don't just block ads, but also trackers, malware, fake news and more that are otherwise hidden to you and other users.&lt;/p&gt;

&lt;p&gt;You may find that it isn't working, so have a look at these instructions to find out if you need to reset a few things on your computer: &lt;a href="https://github.com/StevenBlack/hosts#reloading-hosts-file" rel="noopener noreferrer"&gt;github.com/StevenBlack/hosts#reloading-hosts-file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to go one step further, you can setup a Pi-hole. Its a network-level blocking application that runs on a Raspberry Pi or similar device. Any device (smartphone or laptop) on your network is protected without installing apps etc like I outlined in the thread above.&lt;/p&gt;

&lt;p&gt;Find out about Pi-hole at &lt;a href="https://pi-hole.net/" rel="noopener noreferrer"&gt;pi-hole.net&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you don't want to setup a Pi-hole, give &lt;a href="https://nextdns.io/" rel="noopener noreferrer"&gt;nextdns.io&lt;/a&gt; a try. I've been using it for a couple of months now and love it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzanderwtf.cdn.prismic.io%2Fzanderwtf%2F6807a25f5ef859742f79065f95d6546ff24050ed_screenshot-2019-09-07-at-15.25.35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fzanderwtf.cdn.prismic.io%2Fzanderwtf%2F6807a25f5ef859742f79065f95d6546ff24050ed_screenshot-2019-09-07-at-15.25.35.png" alt="A screenshot of the intro from the NextDNS website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NextDNS can be used on both your smartphone and your PC and has many different configurations. Some of the rules are based on the StevenBlack rules (from above), but there is so much more to it. It is my recommended solution.&lt;/p&gt;

&lt;p&gt;If you want to level-up even further, I suggest using a VPN like &lt;a href="https://nordvpn.com/" rel="noopener noreferrer"&gt;NordVPN&lt;/a&gt;. NordVPN is very cheap, does not keep logs of your activity (this is crucial), and is extremely privacy focused.&lt;/p&gt;

&lt;p&gt;If you're looking to keep more of your online self private, I suggest you visit &lt;a href="https://www.privacytools.io/" rel="noopener noreferrer"&gt;privacytools.io&lt;/a&gt; to find many other tools.&lt;/p&gt;




&lt;p&gt;👨‍💻 The source for this post was originally one of my Twitter threads: &lt;a href="https://twitter.com/MrMartineau/status/1128578179730423808" rel="noopener noreferrer"&gt;twitter.com/MrMartineau/status/1128578179730423808&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This post was originally published on &lt;a href="https://zander.wtf/writing/not-tracked-online" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>tracking</category>
      <category>security</category>
    </item>
    <item>
      <title>My command line reference</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Sun, 08 Sep 2019 06:25:13 +0000</pubDate>
      <link>https://dev.to/mrmartineau/my-command-line-reference-4d4b</link>
      <guid>https://dev.to/mrmartineau/my-command-line-reference-4d4b</guid>
      <description>&lt;h2&gt;
  
  
  A mixture of my favourite CLI tools and things that I usually forget
&lt;/h2&gt;

&lt;p&gt;Disclaimer: If you don't use &lt;a href="https://fishshell.com/"&gt;fish-shell&lt;/a&gt;, some of the packages might not work. There will be alternatives for each of them for your own shell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyboard shortcuts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ctrl-r
&lt;/h3&gt;

&lt;p&gt;Search previously used commands&lt;/p&gt;

&lt;h3&gt;
  
  
  ctrl-t
&lt;/h3&gt;

&lt;p&gt;Invoke &lt;em&gt;FZF&lt;/em&gt; fuzzy file finder (see below)&lt;/p&gt;

&lt;h3&gt;
  
  
  ctrl-l
&lt;/h3&gt;

&lt;p&gt;Clear the terminal screen&lt;/p&gt;

&lt;h3&gt;
  
  
  ctrl-k
&lt;/h3&gt;

&lt;p&gt;Clears the terminal screen but no-scroll back. Basically wipes the &lt;/p&gt;

&lt;h3&gt;
  
  
  ctrl-w
&lt;/h3&gt;

&lt;p&gt;Cut one word backwards using white space as delimiter&lt;/p&gt;

&lt;h3&gt;
  
  
  esc-t
&lt;/h3&gt;

&lt;p&gt;Swap the last two words before the cursor&lt;/p&gt;

&lt;h2&gt;
  
  
  Commands
&lt;/h2&gt;

&lt;h3&gt;
  
  
  cal
&lt;/h3&gt;

&lt;p&gt;Show a calendar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ cal  
   September 2019  
Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6 |7|  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  date
&lt;/h3&gt;

&lt;p&gt;Show the date&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;date  
&lt;/span&gt;Sat  7 Sep 2019 09:22:28 BST
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  tree
&lt;/h3&gt;

&lt;p&gt;Show directory contents as a tree&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ tree &lt;span class="nt"&gt;-L&lt;/span&gt; 1  
&lt;span class="nb"&gt;.&lt;/span&gt;  
├── README.md  
├── components  
├── designsystem  
├── layouts  
├── next.config.js  
├── node_modules  
├── now.json  
├── package.json  
├── pages  
├── redirects.js  
├── scripts  
├── server.js  
├── static  
├── utils  
└── yarn.lock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  List global packages
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# with yarn  &lt;/span&gt;
❯ yarn global list  
yarn global v1.17.3  
info &lt;span class="s2"&gt;"canvas-sketch-cli@1.4.2"&lt;/span&gt; has binaries:  
   - canvas-sketch  
   - canvas-sketch-cli  
   - canvas-sketch-gif  
   - canvas-sketch-mp4  
info &lt;span class="s2"&gt;"create-react-app@2.1.2"&lt;/span&gt; has binaries:  
   - create-react-app  
info &lt;span class="s2"&gt;"docusaurus-init@1.0.1"&lt;/span&gt; has binaries:  
   - docusaurus-init  
info &lt;span class="s2"&gt;"emma-cli@2.0.1"&lt;/span&gt; has binaries:  
   - emma  
   - ema  
info &lt;span class="s2"&gt;"emoj@2.0.0"&lt;/span&gt; has binaries:  
   - emoj  
info &lt;span class="s2"&gt;"fx@10.0.0"&lt;/span&gt; has binaries:  
   - fx  
info &lt;span class="s2"&gt;"ibrew@1.1.1"&lt;/span&gt; has binaries:  
   - ibrew  
info &lt;span class="s2"&gt;"jscodeshift@0.6.2"&lt;/span&gt; has binaries:  
   - jscodeshift  
info &lt;span class="s2"&gt;"lighthouse@5.0.0"&lt;/span&gt; has binaries:  
   - lighthouse  
   - chrome-debug  
info &lt;span class="s2"&gt;"majestic@1.2.24"&lt;/span&gt; has binaries:  
   - majestic  
info &lt;span class="s2"&gt;"np@4.0.2"&lt;/span&gt; has binaries:  
   - np  
info &lt;span class="s2"&gt;"npm@6.0.0"&lt;/span&gt; has binaries:  
   - npm  
   - npx  
info &lt;span class="s2"&gt;"parcel-bundler@1.9.2"&lt;/span&gt; has binaries:  
   - parcel  
info &lt;span class="s2"&gt;"plop@2.1.0"&lt;/span&gt; has binaries:  
   - plop  
info &lt;span class="s2"&gt;"prettier@0.22.0"&lt;/span&gt; has binaries:  
   - prettier  
info &lt;span class="s2"&gt;"release-it@12.3.5"&lt;/span&gt; has binaries:  
   - release-it  
info &lt;span class="s2"&gt;"rimraf@2.6.3"&lt;/span&gt; has binaries:  
   - rimraf  
info &lt;span class="s2"&gt;"semver@5.6.0"&lt;/span&gt; has binaries:  
   - semver  
info &lt;span class="s2"&gt;"serve@10.0.2"&lt;/span&gt; has binaries:  
   - serve  
info &lt;span class="s2"&gt;"strapi@3.0.0-alpha.13.0.1"&lt;/span&gt; has binaries:  
   - strapi  
info &lt;span class="s2"&gt;"terser@3.8.2"&lt;/span&gt; has binaries:  
   - terser  
info &lt;span class="s2"&gt;"types-installer@1.4.0"&lt;/span&gt; has binaries:  
   - types-installer  
info &lt;span class="s2"&gt;"yalc@1.0.0-pre.27"&lt;/span&gt; has binaries:  
   - yalc  
✨  Done &lt;span class="k"&gt;in &lt;/span&gt;5.61s.  

&lt;span class="c"&gt;# with npm  &lt;/span&gt;
❯ npm &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom packages
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Autojump
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/wting/autojump"&gt;https://github.com/wting/autojump&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;autojump is a faster way to navigate your filesystem. It works by maintaining a database of the directories you use the most from the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ j code
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  exa
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ogham/exa"&gt;https://github.com/ogham/exa&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A modern version of &lt;code&gt;ls&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ exa &lt;span class="nt"&gt;-l&lt;/span&gt;  
❯ exa &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; 2 &lt;span class="c"&gt;# like tree&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  FZF
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/junegunn/fzf"&gt;https://github.com/junegunn/fzf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fuzzy find files. Use ctrl+t to access it&lt;/p&gt;

&lt;h3&gt;
  
  
  serve
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/zeit/serve"&gt;https://github.com/zeit/serve&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Static file serving and directory listing&lt;/p&gt;

&lt;h3&gt;
  
  
  emma
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/maticzav/emma-cli"&gt;https://github.com/maticzav/emma-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search for npm packages. Run &lt;strong&gt;emma&lt;/strong&gt; to initialise the search, then enter your search criteria&lt;/p&gt;

&lt;h3&gt;
  
  
  ibrew
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mischah/ibrew"&gt;https://github.com/mischah/ibrew&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interactive search CLI for Homebrew&lt;/p&gt;

&lt;p&gt;Run ibrew to initialise the search, then enter your search criteria&lt;/p&gt;

&lt;h3&gt;
  
  
  yalc
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/whitecolor/yalc"&gt;https://github.com/whitecolor/yalc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Work with yarn/npm packages locally like a boss.&lt;/p&gt;

&lt;h3&gt;
  
  
  hub
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://hub.github.com/"&gt;https://hub.github.com/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# clone one of your GitHub repos  &lt;/span&gt;
❯ hub clone dotfiles  
&lt;span class="c"&gt;# Same as → git clone git://github.com/YOUR_USER/dotfiles.git  &lt;/span&gt;

&lt;span class="c"&gt;# clone another project's repo  &lt;/span&gt;
❯ hub clone github/hub  
&lt;span class="c"&gt;# → git clone git://github.com/github/hub.git  &lt;/span&gt;

&lt;span class="c"&gt;# open the current project's issues page  &lt;/span&gt;
❯ hub browse &lt;span class="nt"&gt;--&lt;/span&gt; issues  
&lt;span class="c"&gt;# → open https://github.com/github/hub/issues  &lt;/span&gt;

&lt;span class="c"&gt;# open another project's wiki  &lt;/span&gt;
❯ hub browse mojombo/jekyll wiki
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  List the current repo's PRs
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# this is an alias  &lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;prs &lt;span class="s1"&gt;'hub pr list -L 20 -b develop --format="%t%n - Branch: [%H]%n - %U%n - %l%n%n"'&lt;/span&gt;  
&lt;span class="c"&gt;# e.g. ❯ prs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a branch and switch to it
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# FYI This is a fish shell function  &lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;branch  
   git branch &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$argv&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git checkout &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$argv&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;  
end  
&lt;span class="c"&gt;# e.g. ❯ branch feature/WL-88-hello&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  standup
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/kamranahmedse/git-standup"&gt;https://github.com/kamranahmedse/git-standup&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shows a list of commits for the past 24 hours&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ standup  
/Users/zander/code/fairfx/fx-holiday-money-app  
5315f033 - build&lt;span class="o"&gt;(&lt;/span&gt;multi&lt;span class="o"&gt;)&lt;/span&gt;: HM-925 Improve perf &lt;span class="k"&gt;for &lt;/span&gt;a couple of pages &lt;span class="o"&gt;(&lt;/span&gt;16 hours ago&lt;span class="o"&gt;)&lt;/span&gt; &amp;lt;Zander Martineau&amp;gt;  
4b41c048 - index on feature/HM-925-improve-performance: 1b854d84 fix&lt;span class="o"&gt;(&lt;/span&gt;ci&lt;span class="o"&gt;)&lt;/span&gt;: AWS-99 Remove builds/deployments associated &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="c"&gt;#845) (17 hours ago) &amp;lt;Zander Martineau&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  cross-port-killer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/milewski/cross-port-killer"&gt;https://github.com/milewski/cross-port-killer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kill a process running on a particular port&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kill-port 9001
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  doctoc
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/thlorenz/doctoc"&gt;https://github.com/thlorenz/doctoc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generated markdown table of contents&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ doctoc README.md &lt;span class="nt"&gt;--github&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  fx
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/antonmedv/fx"&gt;https://github.com/antonmedv/fx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Command-line JSON processing tool&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ fx package.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  jq
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://stedolan.github.io/jq/"&gt;https://stedolan.github.io/jq/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;jq is like &lt;code&gt;sed&lt;/code&gt; for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt; and friends let you play with text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# use jq to extract just the first commit from a repos list  &lt;/span&gt;
❯ curl &lt;span class="s1"&gt;'https://api.github.com/repos/stedolan/jq/commits?per_page=5'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.[0]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  npq
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/lirantal/npq"&gt;https://github.com/lirantal/npq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Safely* install packages with npm or yarn by auditing them as part of your install process&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# with npm   &lt;/span&gt;
❯ npq &lt;span class="nb"&gt;install &lt;/span&gt;express   

&lt;span class="c"&gt;# with yarn, set an alias like so:  &lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;npq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"NPQ_PKG_MGR=yarn npq-hero"&lt;/span&gt;  
❯ npq add express
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  youtube-dl
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtube-dl.org/"&gt;https://youtube-dl.org&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# install  &lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;youtube-dl  

&lt;span class="c"&gt;# use  &lt;/span&gt;
❯ youtube-dl d2qfa3tlgH8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;Are there any that I've missed? Let me know in the comments&lt;/p&gt;

</description>
      <category>cli</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Lessons learned building design systems</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Thu, 14 Mar 2019 09:22:57 +0000</pubDate>
      <link>https://dev.to/mrmartineau/lessons-learnt-building-design-systems-5cmj</link>
      <guid>https://dev.to/mrmartineau/lessons-learnt-building-design-systems-5cmj</guid>
      <description>

&lt;p&gt;Having contributed to a few design systems now, I have found that the same issues appear again and again. Most of the time, these issues can be resolved with a bit of forward planning and some common sense, but the rest of it is down to trial and error. Every team has their own needs from a design system so what works for one person may not work for another. Hopefully, the suggestions in this article can be applied to your design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clearly define what should and shouldn't be included in your component library
&lt;/h2&gt;

&lt;p&gt;In my opinion, a design system should only include component primitives and the most common reusable patterns. These would be known as &lt;strong&gt;atoms&lt;/strong&gt; or &lt;strong&gt;molecules&lt;/strong&gt; if you're using an atomic design methodology.&lt;/p&gt;

&lt;p&gt;If a component is too complex then I suggest that you move it out of the design system repository. Equally, if it is not going to be used by everyone consuming your design system, then it is also a good candidate for being moved into another repository. Use the design system as the base for everything else your team builds.&lt;/p&gt;

&lt;p&gt;This decision also has a basis in performance. More components will increase the package size of the result.&lt;/p&gt;

&lt;p&gt;Each team will have their own criteria for what should be included in a design system, but ultimately it is a personal and evolutionary decision. Once you have arrived at your decision, ensure you document it in a place that is easy to find.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a clear and consistent naming strategy
&lt;/h2&gt;

&lt;p&gt;It might sound obvious, but giving your components useful and intuitive names is crucial. What might sound good to a designer might not be clear to a developer (and vice versa). This one sounds easy, but is actually quite difficult in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Document everything
&lt;/h2&gt;

&lt;p&gt;The more information you provide for each component, the more it will be used and maintained. You wouldn't want your component to be used incorrectly, so provide information for how and when it should be used.&lt;/p&gt;

&lt;p&gt;Provide information about how to consume it from a development perspective, e.g. what code is needed to import it, and what are some example use cases for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.docz.site/"&gt;Docz&lt;/a&gt; is a great solution for documenting components. Documentation is written in markdown format (.mdx) and components can be embedded right into the documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; also has the ability to render markdown (using the readme or info add-ons) and is a great alternative for keeping the docs close to the implementation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make components easy to find
&lt;/h2&gt;

&lt;p&gt;If possible, provide a search to find your components. Both &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; and &lt;a href="https://www.docz.site/"&gt;Docz&lt;/a&gt; have a search but they're limited to names of the stories/items only. Alternatively create an index of all components on one page so that they can be easily be searched, &lt;a href="https://fannypack.style/"&gt;Fannypack&lt;/a&gt; does a brilliant job of this on their home page. Having a consistent naming strategy will also help in this matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make your components easy to develop
&lt;/h2&gt;

&lt;p&gt;Providing a dedicated development environment is extremely important too. A tool like &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; is perfect for this because it creates an environment to preview and develop your components in isolation.&lt;/p&gt;

&lt;p&gt;Test your components under different conditions by making use of Storybook's add-ons. The &lt;a href="https://github.com/storybooks/storybook/tree/master/addons/knobs"&gt;Knobs&lt;/a&gt; and &lt;a href="https://github.com/storybooks/storybook/tree/master/addons/viewport"&gt;Viewport&lt;/a&gt; add-ons make development much easier by allowing users to change values and data that the component uses.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/storybooks/storybook/tree/master/addons/storysource"&gt;story source&lt;/a&gt; add-on shows the source code for a given component so it makes it even easier for developers to see examples of it in use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Provide an interactive demo
&lt;/h3&gt;

&lt;p&gt;If you can publish your components to &lt;a href="https://npmjs.org"&gt;npm&lt;/a&gt;, you can then use something like &lt;a href="https://codesandbox.io/"&gt;CodeSandbox&lt;/a&gt; to allow developers to experiment with them and test different combinations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make your design tokens easy to access and edit
&lt;/h2&gt;

&lt;p&gt;Your designs tokens will be used more than any other aspect of your system, so make them easy to reference and even more easy to update. If you are writing CSS-in-JS, my library, &lt;a href="https://github.com/mrmartineau/design-system-utils/"&gt;Design System Utils&lt;/a&gt; can greatly help in this matter.&lt;/p&gt;

&lt;p&gt;Wherever you choose to document your components, your tokens should also be included there as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make your components accessible by default
&lt;/h2&gt;

&lt;p&gt;The extra effort required to make components accessible is negligible compared to the frustration they cause to users with special needs. There are many resources about accessibility online, here's &lt;a href="https://github.com/mrmartineau/awesome-web-dev-resources#accessibility-a11y"&gt;my ever-growing list&lt;/a&gt; of a11y resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test your components
&lt;/h2&gt;

&lt;p&gt;The more tests you add, the more robust and reliable your components will be. There are a few different types of tests that you'll need: unit tests, snapshot tests and visual regression tests.&lt;/p&gt;

&lt;p&gt;Visual regression tests are brilliant for picking up bugs in components over time. For example, if someone changes a token value for the border colour that is meant for the form inputs, but another component is also using that for its border, then your visual regression tests will notify your team of the change when the tests are run. &lt;a href="https://www.chromaticqa.com"&gt;Chromatic&lt;/a&gt; is great for this because it integrates brilliantly with Storybook, and it's free if your project is open source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versioning
&lt;/h2&gt;

&lt;p&gt;Using proper &lt;a href="https://semver.org/spec/v2.0.0.html"&gt;semantic versioning&lt;/a&gt; (e.g. &lt;code&gt;1.2.3&lt;/code&gt;) will really help when folks consume your design system. There is a clear understanding of why the version changed and what that means for people referencing and consuming your work.&lt;/p&gt;

&lt;p&gt;There are many tools that help automate versioning, one of which is &lt;a href="https://www.conventionalcommits.org"&gt;Conventional commits&lt;/a&gt;; it automatically determines a semantic version bump; automates CHANGELOG generation; and it also integrates with your continuous integration process so it offsets these features and more so developers don't have to think about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate as much as possible
&lt;/h2&gt;

&lt;p&gt;If you can automate your unit tests, visual regression tests, code coverage, code linting and even your release process then you will again be offsetting mundane and repetitive tasks that your team will not have to worry about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dedicate time and resources to maintaining your codebase
&lt;/h2&gt;

&lt;p&gt;I cannot stress this point enough: if you don't dedicate time and resources to maintaining your codebase it will ultimately fail. Fail to be used; fail to change with the times; and fail to be useful to those that need it.&lt;/p&gt;




&lt;p&gt;I would be keen to hear your thoughts on this. Do you have anything to add? Can any of my points be improved upon?&lt;/p&gt;


</description>
      <category>designsystems</category>
      <category>components</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introducing Design System Utils</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Wed, 14 Feb 2018 22:49:40 +0000</pubDate>
      <link>https://dev.to/mrmartineau/introducing-design-system-utils--3mp7</link>
      <guid>https://dev.to/mrmartineau/introducing-design-system-utils--3mp7</guid>
      <description>&lt;p&gt;Maintaining  styling consistency in a web app (or React Native) is often tough.  There isn’t a common way to manage shared values and settings. This  micro framework aims to standardise your design-system and provide  helpful utilities to access it’s information. It’s more than a set of  variables in a specific structure, it includes a few functions to access  values in your design system much more easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let me run through the basics
&lt;/h2&gt;

&lt;p&gt;You first need to create your design system file, this contains all your  global variables that your app will use, think font-sizes, color  palette, spacing etc. I usually create a top-level directory named theme or designsystem, and add an index.js inside, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./theme/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DesignSystem&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;design-system-utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// your design-system goes here, see below for details&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myDesignSystem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DesignSystem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myDesignSystem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;useModularScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fontSizeUnit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is the shape of the design system object?
&lt;/h3&gt;

&lt;p&gt;Below are the mandatory items that your design system should use. Beyond these, you can add anything you like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// this should be set as a px value if you have `options.fontSizeUnit` set&lt;/span&gt;
    &lt;span class="c1"&gt;// to 'rem' or 'em' so that the lib can convert the values properly&lt;/span&gt;
    &lt;span class="na"&gt;baseFontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="c1"&gt;// If you're using a modular scale, set it up here&lt;/span&gt;
    &lt;span class="c1"&gt;// Use these docs to find out more: https://github.com/modularscale/modularscale-js&lt;/span&gt;
    &lt;span class="na"&gt;modularscale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// should be the same as baseFontSize&lt;/span&gt;
      &lt;span class="na"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Color palette&lt;/span&gt;
  &lt;span class="c1"&gt;// Each object needs to have the same shape&lt;/span&gt;
  &lt;span class="c1"&gt;// Each color object needs a `base` value to be the default&lt;/span&gt;
  &lt;span class="c1"&gt;// Have as many color objects as you like&lt;/span&gt;
  &lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Used with `ds.color('colorName')`&lt;/span&gt;
    &lt;span class="nl"&gt;colorPalette&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;colorName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// base is the default&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="c1"&gt;// Used with `ds.brand('colorName)`&lt;/span&gt;
    &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;colorName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// base is the default&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Breakpoints&lt;/span&gt;
  &lt;span class="c1"&gt;// Used with `ds.bp()`&lt;/span&gt;
  &lt;span class="c1"&gt;// Keys can be anything you like&lt;/span&gt;
  &lt;span class="c1"&gt;// Have as many breakpoints as you like&lt;/span&gt;
  &lt;span class="c1"&gt;// Values can be use any unit you like&lt;/span&gt;
  &lt;span class="nx"&gt;breakpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Z-index&lt;/span&gt;
  &lt;span class="c1"&gt;// Used with `ds.z()`&lt;/span&gt;
  &lt;span class="nx"&gt;zIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Spacing&lt;/span&gt;
  &lt;span class="c1"&gt;// Used with `ds.spacing()` or `ds.space()`&lt;/span&gt;
  &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an excerpt from the example design-system. See a more complete example in the example directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myDesignSystem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;baseFontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;// the values below use modular-scale&lt;/span&gt;
    &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [default] p, h5, h6&lt;/span&gt;
      &lt;span class="na"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h4&lt;/span&gt;
      &lt;span class="na"&gt;l&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h3&lt;/span&gt;
      &lt;span class="na"&gt;xl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h2&lt;/span&gt;
      &lt;span class="na"&gt;xxl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h1&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;modularscale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sans&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"Helvetica Neue", Helvetica, Arial, sans-serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Georgia, "Times New Roman", Times, serif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;mono&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Menlo, Monaco, "Courier New", monospace&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Useful to set here if using anything other than `normal`&lt;/span&gt;
      &lt;span class="na"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Useful to set here when bold webfonts come as 400 font-weight.&lt;/span&gt;
      &lt;span class="na"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// instead of browser default, bold&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Accessing the design system data in your app
&lt;/h2&gt;

&lt;p&gt;To access your design system, you just need to &lt;code&gt;import&lt;/code&gt; it to the current file, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ds&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./myDesignSystem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I have created a very simple component using the design system and &lt;a href="https://styled-components.com" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt;, you should be able to see how easy it is to pull information from the design system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example uses styled-components&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ds&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  font-family: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;type.fontFamilyBase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;;
  background-color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;;
  margin: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;space&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; 0;
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Options
&lt;/h2&gt;

&lt;p&gt;There are two options that can be passed to your design system. These relate to font-sizing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use default options&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DesignSystem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myDesignSystem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// With custom options&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DesignSystem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myDesignSystem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// converts the `type.sizes` values into modular scale values&lt;/span&gt;
  &lt;span class="na"&gt;useModularScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// sets the font-size unit when calling fs.fontSize()&lt;/span&gt;
  &lt;span class="na"&gt;fontSizeUnit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  API methods
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Get any value
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.get()&lt;/code&gt; function can be used to get any value from the design-system. You can use dot notation to find nested values at any depth.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// with the system setup, as above&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;type.lineHeight.headings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// e.g. 1.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have provided a few other helper methods to make retrieving certain values more simple. Most are short-hands for the ds.get() method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Font-sizing
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.fontSize()&lt;/code&gt; method is a short-hand for the &lt;code&gt;ds.get()&lt;/code&gt; method, but with a little extra. It is used to pull values from the type.sizes object.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;type.sizes&lt;/code&gt; object’s values can be formatted in a few ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;s: -2&lt;/code&gt; — if a number is used and options.modularscale = true, then ds.fontSize() converts this number to a value on the modular scale.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s: '13px'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;s: '1.4rem'&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// define some values// type.sizes object&lt;/span&gt;
&lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [default] p, h5, h6&lt;/span&gt;
  &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h4&lt;/span&gt;
  &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h3&lt;/span&gt;
  &lt;span class="nx"&gt;xl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h2&lt;/span&gt;
  &lt;span class="nx"&gt;xxl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// h1&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;

&lt;span class="c1"&gt;// retrieve some values&lt;/span&gt;

&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// `fs()` is a short-hand alias for `fontSize()`&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// return font-size in px regardless of `option.fontSizeUnit` value&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns font-size of the 6th item on the modular-scale. This will only work if the òptions.modularscale` is `true`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
   Modular scale
&lt;/h4&gt;

&lt;p&gt;To make use of a modular scale, there are a few things that need to be done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;set &lt;code&gt;options.modularscale = true&lt;/code&gt;, see above for details on this&lt;/li&gt;
&lt;li&gt;define your modular scale options in &lt;code&gt;type.modularscale&lt;/code&gt;. Design system utils uses modularscale-js to do the conversions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;modularscale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Color palette
&lt;/h3&gt;

&lt;p&gt;There  are two possible ways to access color information: through the color  palette and the brand colors. The color palette is intended to contain  all the colors (and their shades) that your app will use, and the brand  palette is the specific colors that your brand uses. Two methods can be  used to retrieve the values, these are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// With a color palette like this:&lt;/span&gt;
  &lt;span class="nl"&gt;colorPalette&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;bright&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#F9FAFB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#F4F6F8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;darker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#DFE4E8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#212B35&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#454F5B&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lighter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#637381&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// With a brand palette like this:&lt;/span&gt;
  &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#e82219&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;deeporange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff7200&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;orange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff9500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#c4d000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;teal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#1aa5c8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;navy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0052da&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get color palette value
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.color()&lt;/code&gt; function gets values from the colorPalette object. It assumes every color has a base property and other properties for different shades of the same color. This is a short-hand for the ds.get() function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Get values like this:&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// #F9FAFB - the `base` key is the default, so it is not needed&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get brand palette value
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.brand()&lt;/code&gt; function gets values from the colors.brand object. This is a short-hand for the &lt;code&gt;ds.get()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Get brand values like this:&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary.blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// it is possible to nest this object as much as you like&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get breakpoint values
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.bp()&lt;/code&gt; method is a short-hand for the &lt;code&gt;ds.get()&lt;/code&gt; method. It can be used to get a breakpoint from the breakpoints object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get z-index values
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.z()&lt;/code&gt; method is a short-hand for the &lt;code&gt;ds.get()&lt;/code&gt; method. It can be used to get a breakpoint from the zIndex object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;z&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;low&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get spacing values
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ds.spacing()&lt;/code&gt; method returns a value from your spacing.scale array. It takes an index for that array and converts the value to pixels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example scale array// scale: [0, 8, 16, 24, 32, 40]&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// '16px'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: &lt;code&gt;ds.space(2)&lt;/code&gt; can also be used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Calculations
&lt;/h3&gt;

&lt;p&gt;The framework currently provides a few calculation functions, &lt;code&gt;multiply&lt;/code&gt;, &lt;code&gt;toPx&lt;/code&gt; and &lt;code&gt;pxTo&lt;/code&gt;:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;multiply(initial, muliplier)&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 20&lt;/span&gt;

&lt;span class="c1"&gt;// you can pass in another value from the system&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;spacing.baseline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// or just use the key from the system&lt;/span&gt;
&lt;span class="c1"&gt;// the initial value will always be run through `parseFloat()`&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;spacing.baseline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;pxTo(fontSize, baseFontSize, unit)&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Converts px to rem or em&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ds.pxTo(fontSize, baseFontSize, unit)&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pxTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0.6rem&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pxTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;em&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0.6em&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;toPx(fontSize, baseFontSize)&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Converts rem or em value to px&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toPx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.875rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 30px&lt;/span&gt;
&lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toPx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.875em&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 30px&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Demo &amp;amp; examples
&lt;/h2&gt;

&lt;p&gt;I created a demo on codesandbox.io, it includes examples of using the design-system utils with emotion, styled-components and glamorous. There is also a basic example &lt;a href="https://github.com/mrmartineau/design-system-utils/tree/master/example" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you get it?
&lt;/h2&gt;

&lt;p&gt;You can install it via npm using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; design-system-utils

yarn add design-system-utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How do you contribute?
&lt;/h2&gt;

&lt;p&gt;I am always looking for ways to improve, so welcome any and all feedback. The code is hosted on GitHub at &lt;a href="https://github.com/mrmartineau/design-system-utils" rel="noopener noreferrer"&gt;github.com/mrmartineau/design-system-utils&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Rebel with a CORS</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Wed, 14 Feb 2018 22:34:24 +0000</pubDate>
      <link>https://dev.to/mrmartineau/rebel-with-a-cors--88m</link>
      <guid>https://dev.to/mrmartineau/rebel-with-a-cors--88m</guid>
      <description>&lt;h2&gt;
  
  
  Or How to make your own simple CORS enabled API from one that has CORS disabled
&lt;/h2&gt;

&lt;p&gt;As a front-end developer, I often consume various 3rd party APIs while developing. These APIs could be for weather, crypto currency prices or the latest XKCD comic.&lt;/p&gt;

&lt;p&gt;The problem with some of them is that they do not support cross-origin requests (CORS), which means that client-side AJAX calls to these services do not work. This is frustrating but can easily be fixed with the help of a few lines of code in your own micro-service.&lt;/p&gt;

&lt;p&gt;Creating the micro-service&lt;br&gt;
All you need to create a simple micro-service is a package called micro. It is a very simple package that enables the creation of asynchronous micro-services, and if you read the project’s readme, you’ll see that a simple service can be created with no more than a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously the above is completely useless, but let me show how easy it is to consume almost any API, at least any API that didn’t need authentication, using micro.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fchat_systems.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fchat_systems.png"&gt;&lt;/a&gt;&lt;br&gt;
From &lt;a href="https://xkcd.com/1810/" rel="noopener noreferrer"&gt;comic #1810&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this example, I’ll use the free API from the XKCD comic, which cannot be used in AJAX calls on the client-side because CORS is disabled. Calling the url &lt;a href="https://xkcd.com/info.0.json" rel="noopener noreferrer"&gt;https://xkcd.com/info.0.json&lt;/a&gt; returns the latest comic, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"month"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"num"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1954&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"news"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"safe_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Impostor Syndrome"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transcript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"It's actually worst in people who study the Dunningâ€“Kruger effect. We tried to organize a conference on it, but the only people who would agree to give the keynote were random undergrads."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"img"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://imgs.xkcd.com/comics/impostor_syndrome.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Impostor Syndrome"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"day"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it can return a specific comic if passed the correct comic ID (&lt;a href="https://xkcd.com/1500/info.0.json" rel="noopener noreferrer"&gt;https://xkcd.com/1500/info.0.json&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"month"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"num"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2015"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"news"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"safe_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Upside-Down Map"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transcript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"((A mercator projection of the world map is shown. All the continents have been rotated one hundred eighty degrees.))&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;((Cuba  is next to alaska, and alaska is touching the tip of south america, which is all near the equator. Mexico is now friends with greenland.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;((Iceland, the UK, and asia are all close together. Japan and Taiwan haven't moved with the asian continent, and are technically European.))&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;((Siberia is now equatorial. Africa is pretty temperate, except for the north bits which are somewhat antarctic.))&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Caption: This upside-down map will change your perspective on the world!&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;{{Title text: Due to their proximity across the channel, there's long been tension between North Korea and the United Kingdom of Great Britain and Southern Ireland.}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Due to their proximity across the channel, there's long been tension between North Korea and the United Kingdom of Great Britain and Southern Ireland."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"img"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://imgs.xkcd.com/comics/upside_down_map.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Upside-Down Map"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"day"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the micro-service needs to do is to pass-through any requests to the original API and set a few headers to allow for cross-origin requests so that they can be used in AJAX calls on the client-side, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;micro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;microCors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;micro-cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;microCors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;allowMethods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DOMAIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://xkcd.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DOMAIN&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s 14 lines of code!&lt;/p&gt;

&lt;p&gt;The example above passes any slug information into the API (e.g. &lt;code&gt;1000/0.json&lt;/code&gt;), so calling &lt;code&gt;https://xkcd.now.sh/1000/0.json&lt;/code&gt; (my version of the API), would map to &lt;code&gt;https://xkcd.com/1000/0.json&lt;/code&gt;. This could be the end of our journey, but I’d like to improve the API UX a bit by changing the endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;xkcd.now.sh&lt;/code&gt; should return the latest comic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;xkcd.now.sh/1000&lt;/code&gt; should return comic ID 1000&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See below on how to achieve that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;micro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;microCors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;micro-cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;microCors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;allowMethods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DOMAIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://xkcd.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;info.0.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;comicId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DOMAIN&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;comicId&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;PATH&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newResponse&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1084&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;newResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;imgRetina&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;_2x.png`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;newResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s 29 lines of code! See it here 👀&lt;/p&gt;

&lt;p&gt;You can see above that beyond micro, there are two other packages that the service relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/axios/axios" rel="noopener noreferrer"&gt;axios&lt;/a&gt; for the HTTP requests&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/possibilities/micro-cors" rel="noopener noreferrer"&gt;micro-cors&lt;/a&gt; is a simple CORS for micro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My example with the XKCD API returns all of the original data and actually changes the response data slightly as well as how the API is consumed. I decided to add the retina image path (if there is one) as well as simplify the call to the API. So instead of calling &lt;code&gt;xkcd.com/1894/info.0.json&lt;/code&gt; you can call &lt;code&gt;xkcd.now.sh/1894&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, for example: calling &lt;a href="https://xkcd.now.sh/1894" rel="noopener noreferrer"&gt;https://xkcd.now.sh/1894&lt;/a&gt; would request this URL from the original XKCD API: &lt;a href="https://xkcd.com/1894/info.0.json" rel="noopener noreferrer"&gt;https://xkcd.com/1894/info.0.json&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"month"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"num"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1894&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"year"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2017"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"news"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"safe_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Real Estate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transcript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I tried converting the prices into pizzas, to put it in more familiar terms, and it just became a hard-to-think-about number of pizzas."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"img"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://imgs.xkcd.com/comics/real_estate.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Real Estate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"day"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"25"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"imgRetina"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://imgs.xkcd.com/comics/real_estate_2x.png"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💪 The code for this service is hosted on GitHub at &lt;a href="https://github.com/mrmartineau/xkcd-api" rel="noopener noreferrer"&gt;github.com/mrmartineau/xkcd-api&lt;/a&gt; and can be tested using &lt;a href="https://www.getpostman.com/collections/2254fd6b4db3e7345ddd" rel="noopener noreferrer"&gt;Postman here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hosting your new API
&lt;/h3&gt;

&lt;p&gt;I use now by zeit to host my various apps and APIs. now supports the JavaScript language features that this micro-service requires (async/await) as well as HTTPS out of the box. If your hosting does not support these features, you will need to transpile the code back to a version it does support.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l6wm4l9af43ldas9n3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l6wm4l9af43ldas9n3s.png"&gt;&lt;/a&gt;&lt;br&gt;
From &lt;a href="https://xkcd.com/1700/" rel="noopener noreferrer"&gt;comic #1700&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Other examples
&lt;/h3&gt;

&lt;p&gt;For an example of an even more simple pass-through API, you can see my CORS enabled version of the Pinboard feeds API. The code is hosted on GitHub at &lt;a href="https://github.com/mrmartineau/pinboard-api" rel="noopener noreferrer"&gt;github.com/mrmartineau/pinboard-api&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;My thanks go to Andrew Williams, Ashley Nolan &amp;amp; Ciaran Park for their help with the title of this post. Other suggestions from them include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No CORS for concern: getting that API&lt;/li&gt;
&lt;li&gt;Be-CORS you're worth it&lt;/li&gt;
&lt;li&gt;COR Blimey gov’nr&lt;/li&gt;
&lt;li&gt;CORS, Ugh, what is is it good for&lt;/li&gt;
&lt;li&gt;Just CORS&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating dynamic layouts with Jekyll</title>
      <dc:creator>Zander Martineau</dc:creator>
      <pubDate>Sun, 13 Aug 2017 06:55:35 +0000</pubDate>
      <link>https://dev.to/mrmartineau/creating-dynamic-layouts-with-jekyll</link>
      <guid>https://dev.to/mrmartineau/creating-dynamic-layouts-with-jekyll</guid>
      <description>&lt;p&gt;Liquid syntax error: Unknown tag 'endraw'&lt;/p&gt;
</description>
      <category>jekyll</category>
    </item>
  </channel>
</rss>
