<?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>Forem: Daniel Del Core</title>
    <description>The latest articles on Forem by Daniel Del Core (@danieldelcore).</description>
    <link>https://forem.com/danieldelcore</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%2F179808%2F45b48dbb-0223-4d7a-9cd9-353c9bfc90f4.jpeg</url>
      <title>Forem: Daniel Del Core</title>
      <link>https://forem.com/danieldelcore</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/danieldelcore"/>
    <language>en</language>
    <item>
      <title>A new way to ship Codemods</title>
      <dc:creator>Daniel Del Core</dc:creator>
      <pubDate>Mon, 15 Aug 2022 01:39:02 +0000</pubDate>
      <link>https://forem.com/danieldelcore/a-new-way-to-ship-codemods-4h11</link>
      <guid>https://forem.com/danieldelcore/a-new-way-to-ship-codemods-4h11</guid>
      <description>&lt;p&gt;A little under two years ago, my team was preparing for our first performance refactor of our Design System. Our plans to maximise performance gains were predicated on removing deprecated API, which had slowly accumulated over the years, now representing a substantial amount of bloat and code duplication. Worryingly, doing so would mean an unprecedented amount of breaking changes at a time when adoption and stability were a huge pain point for our consumers. Automated migration seemed like the only feasible way forward…&lt;/p&gt;

&lt;p&gt;Like most popular libraries, e.g. &lt;a href="https://github.com/reactjs/react-codemod" rel="noopener noreferrer"&gt;React&lt;/a&gt;, &lt;a href="https://nextjs.org/docs/advanced-features/codemods" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; and more, which provide codemods to help move their huge user base across versions, we needed a bespoke and fairly simple CLI wrapper of &lt;a href="https://github.com/facebook/jscodeshift" rel="noopener noreferrer"&gt;jscodeshift&lt;/a&gt;, that would provide a means of publishing, downloading and running codemods. So we created a custom 'codemod-cli', our first piece of internal codemod infrastructure.&lt;/p&gt;

&lt;p&gt;We had already written a few codemods to help with some internal migrations. These were in the form of standalone transform files co-located with the packages they served but were one-offs which were written, run and forgotten about since the work was done and no longer necessary. This is not unlike what React and Next.js provide, unstructured but at times unclear as to when and why a codemod should be used. This is where we saw our first opportunity: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if every breaking change was paired with a versioned codemod?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this model, every breaking change would be accompanied by a codemod, the name of the codemod would point to the version which it targeted button-v2.0.0 so its intent was clear to the user. What’s more, once we accumulate codemods for multiple major versions, it would be possible for users lagging many versions behind to be slingshotted to the latest code by running all available codemods in sequence. &lt;/p&gt;

&lt;p&gt;With this paradigm in place and the functionality implemented in the codemod-cli, we were at a point where we needed to put tools down. We needed to get back to the project we originally set out to complete, improving performance. It was now on us to start putting it to the test by writing and publishing codemods for our breaking changes. But now with the ability to actually change APIs that had been holding us back for years. To keep this short, I’ll skip over the next year or so by just saying: It worked! We wrote loads of codemods, they ran and they certainly did what we originally intended – Yay!&lt;/p&gt;

&lt;p&gt;However, I walked away from that project with a lot of unfinished business, I felt that there were many more uncapitalised opportunities in this space. So I did what no other engineer has done before me, I started a side-project… 😅. With more and more Design Systems and convergence toward multi-package repositories, I feel like it’s the right time to share what I’ve been up to in the hope that it might also help folks in a similar situation to us.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.codeshiftcommunity.com/" rel="noopener noreferrer"&gt;🚚 CodeshiftCommunity&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fed6mtvh6kwzccp1f0fvc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fed6mtvh6kwzccp1f0fvc.png" alt="CodeshiftCommunity site" width="800" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First and foremost, If the project was nothing else, it would simply be a docs site representing our collective codemod authoring knowledge. This is obviously a huge gap and barrier to entry for newcomers to jscodeshift. An onboarding experience that is quite intimidating, pieced together by various examples and blog posts. &lt;/p&gt;

&lt;p&gt;Secondly, the strategy of codemods targeting specific versions of a package seemed strikingly similar to that of &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped" rel="noopener noreferrer"&gt;DefinitelyTyped&lt;/a&gt;, versioned artifacts (ts type definitions) supporting a package across its lifecycle. What if we could provide similar facilities to act as a single place where codemods could be distributed, documented and maintained in a controlled and structured way? &lt;/p&gt;

&lt;p&gt;Thirdly, everyone using jscodeshift, including ourselves, is likely to be also writing/maintaining a bespoke CLI to solve this problem. We would need to tie everything together into a single and familiar CLI tool.&lt;/p&gt;

&lt;p&gt;Lastly, my main objective and what I’m currently working on is to: Provide a renovate-like bot that can not only version bump, but also automatically migrate code across major versions and prompt maintainers to either merge on green CI or give them clear call-outs for their intervention in case a codemod can’t migrate them all the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;Generally speaking, the library works by publishing every codemod to npm as its own package or piggybacking off an existing NPM package. Our CLI can then download and run them from anywhere. With the hidden benefit of being able to publish codemods with dependencies, currently, something that isn’t possible with vanilla jscodeshift CLI implementations.&lt;/p&gt;

&lt;p&gt;Using NPM drastically lowers the adoption bar since all one would need to do is publish their existing package paired with a &lt;code&gt;codemod.config.js&lt;/code&gt;, which is effectively a file that holds the names and locations of codemods. In existing npm packages, simply adding this file would be all that is necessary to adopt Codeshift, no dependency is required.&lt;/p&gt;

&lt;p&gt;For example:&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;transforms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Versioned transforms&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./18.0.0/transform&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;13.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./19.0.0/transform&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;presets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Generic utility transforms&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;format-imports&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./format-imports/transform&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;p&gt;Running the above codemod now is a simple matter of referencing the package name and version. &lt;/p&gt;

&lt;p&gt;Let’s for a moment say this config exists within the &lt;code&gt;@chakra/button&lt;/code&gt; package. Assuming the config and codemods are published to NPM, one could run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ codeshift -p @chakra/button@12.0.0 path/to/src&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Codeshift will download the latest version of &lt;code&gt;@chakra/button&lt;/code&gt; locally, ensuring we always have the most up-to-date codemods. The CLI would read the config and pass that to jscodeshift where normal transformation would take place. &lt;/p&gt;

&lt;p&gt;Passing the &lt;code&gt;--sequence&lt;/code&gt; flag will trigger a run of both v12 and v13, one after the other.&lt;/p&gt;

&lt;p&gt;The presets config, is a place for “generic” or “non-version specific” codemods, which relate to &lt;code&gt;@chakra/button&lt;/code&gt;. This is potentially where one might want to share codemods like, &lt;code&gt;format-imports&lt;/code&gt; which would, for example, format button imports into a certain order. Running one looks like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ codeshift -p @chakra/button#format-imports path/to/src&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How you adopt Codeshift is up to you
&lt;/h2&gt;

&lt;p&gt;You can contribute to the &lt;a href="https://www.codeshiftcommunity.com/docs/registry/" rel="noopener noreferrer"&gt;public registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Augment existing packages with codemods to make them available to via the &lt;code&gt;@codeshift/cli&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Or create your own private codemod registry, utilising the same docs, best practices and structured API whilst being fully compatible the community.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://www.codeshiftcommunity.com/docs/authoring" rel="noopener noreferrer"&gt;authoring guide&lt;/a&gt; for more info.&lt;/p&gt;

&lt;h2&gt;
  
  
  What next?
&lt;/h2&gt;

&lt;p&gt;The overarching goal is to lower the barrier to entry so that the JS ecosystem as a whole could leverage these resources and community and in turn generate codemod coverage for libraries that we depend on, in the same way we consume type definitions from &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped" rel="noopener noreferrer"&gt;DefinitelyTyped&lt;/a&gt;. The idea is that developers will eventually be able to leverage codemods the community collectively provide, simplifying migration for core dependencies (react, redux, next, emotion, jest, etc). A lofty goal, but consider if existing ecosystem codemods were to integrate with the library. &lt;/p&gt;

&lt;p&gt;The only barrier to entry for them is providing a configuration file and using the &lt;code&gt;@codeshift/cli&lt;/code&gt;, which can be safely done alongside existing infrastructure. Once published to NPM our build tooling and consumers can run these codemods from anywhere.&lt;/p&gt;

&lt;p&gt;Ultimately and more importantly consolidating efforts in the space into a structured library serves the broader JS ecosystem.&lt;/p&gt;

&lt;p&gt;If you’re interested or want to learn more please feel free to browse the docs: &lt;a href="https://www.codeshiftcommunity.com/docs/" rel="noopener noreferrer"&gt;CodeshiftCommunity&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>codemod</category>
      <category>react</category>
    </item>
    <item>
      <title>CSS-in-JS: What happened to readability?</title>
      <dc:creator>Daniel Del Core</dc:creator>
      <pubDate>Fri, 06 Nov 2020 07:07:19 +0000</pubDate>
      <link>https://forem.com/danieldelcore/css-in-js-what-happened-to-readability-5bil</link>
      <guid>https://forem.com/danieldelcore/css-in-js-what-happened-to-readability-5bil</guid>
      <description>&lt;p&gt;When I first started using &lt;a href="http://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt; (block-element-modifier) early in my career, I distinctly remember how refreshing it was to have a system to name and assign semantic meaning to our otherwise esoteric CSS blocks. Almost immediately (once I understood the rules) it became easy to glance at some CSS and visualise the changes that will be applied to elements in their various states. Love it or hate it, something about its simple underlying principles stuck with me.&lt;/p&gt;

&lt;p&gt;It looked something like this…&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="nc"&gt;.my-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.my-button.my-button__icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.my-button.my-button--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;p&gt;Nowadays, most of us are using CSS-in-JS libraries like &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt; or &lt;a href="https://emotion.sh/" rel="noopener noreferrer"&gt;emotion&lt;/a&gt; (which are fantastic libraries btw), but all of a sudden it seems like we forgot about the helpful methodologies we learned with &lt;a href="http://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt;, &lt;a href="https://github.com/stubbornella/oocss/wiki" rel="noopener noreferrer"&gt;OOCSS&lt;/a&gt; and &lt;a href="http://smacss.com/" rel="noopener noreferrer"&gt;SMACSS&lt;/a&gt;. As a result CSS-in-JS that you encounter in the wild is hard to read and reason about.&lt;/p&gt;

&lt;p&gt;You might be familiar with seeing code like this:&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;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
 background: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;you&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="s2"&gt;didn't&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
 color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;read&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="s2"&gt;this&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
 font-size: 1em;
 margin: 1em;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, properties for the &lt;code&gt;primary&lt;/code&gt; modifier are computed individually, carrying an implicit runtime cost, which scales poorly as more modifiers are eventually added. More importantly, this carries &lt;strong&gt;substantial cognitive overhead&lt;/strong&gt; for future maintainers, trying to understand how and when properties are being applied. A point proven by the fact that you probably didn’t read that code block at all (Check again 😉).&lt;/p&gt;

&lt;p&gt;Now you’re the next developer to come along and attempt to add a &lt;code&gt;disabled&lt;/code&gt; state to this button. You might be inclined to continue this pattern and do something like this…&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;function&lt;/span&gt; &lt;span class="nf"&gt;getBackgroundColor&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="p"&gt;{&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&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;function&lt;/span&gt; &lt;span class="nf"&gt;getColor&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="p"&gt;{&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;darkgrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&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="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
 background: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;getBackgroundColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
 color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;getColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
 font-size: 1em;
 margin: 1em;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this only further exacerbates the problem by creating yet another layer of indirection.. OH NO 😱 Not only do you have to compute this function in your head, you now have to locate these helpers 🤯&lt;/p&gt;

&lt;p&gt;For better or worse styled-components is totally unopinionated about these things, if you’re not careful you might inadvertently allow bad practices to propagate through your components. Sure, you could BEM-ify this code in styled-components, but my point is that you’re not forced to by the API. Even so, BEM-like methodologies are no better because they’re merely a set of rules and rules are great only until someone breaks them 👮‍♂️!&lt;/p&gt;

&lt;p&gt;CSS-in-JS actually provides the perfect opportunity for an API abstraction to solve this very problem 🎉 by abstracting away the messy details of a methodology and leaving you and your colleagues with a library that guards you from these implicit issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br&gt;
This was my motivation to build Trousers 👖 (&lt;a href="https://github.com/danieldelcore/trousers/pull/84" rel="noopener noreferrer"&gt;v4 coming soon&lt;/a&gt;)&lt;br&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;😅&lt;/p&gt;

&lt;p&gt;but I’m not the only one thinking about this! New libraries like &lt;a href="https://stitches.dev/" rel="noopener noreferrer"&gt;Stitches&lt;/a&gt; are popping up all over the place, taking a similar approach to shepherding users into using good patterns through API design. Leaving us with the best of both worlds!&lt;/p&gt;

&lt;p&gt;Trousers as an example provides grouped properties via modifiers…&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="nx"&gt;css&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;@trousers/core&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;css&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&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;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&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="nf"&gt;modifier&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&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="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disabled&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;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&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;p&gt;Named modifiers controlled via props…&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="cm"&gt;/* @jsx jsx */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;css&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;@trousers/core&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="nx"&gt;jsx&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;@trousers/react&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;css&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&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;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&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="nf"&gt;modifier&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&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="nf"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disabled&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;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&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;CustomButton&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
    &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;=&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="nx"&gt;isPrimary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;$disabled&lt;/span&gt;&lt;span class="o"&gt;=&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="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Themes as css variables, allowing for even less dynamic css and runtime cost.&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="nf"&gt;css&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&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;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&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="nf"&gt;modifier&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;var(--color-primary)&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="nf"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;color&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;red&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;p&gt;And all of the examples above will only ever mount &lt;code&gt;1 + number of modifiers&lt;/code&gt;, regardless of component state and active theme.&lt;/p&gt;

&lt;p&gt;All possible because CSS-in-JS provides us with layer of abstraction to do this work!&lt;/p&gt;

&lt;p&gt;So my ask for you to takeaway from this blog is not to necessarily use my library, but start to think the &lt;a href="https://en.wikipedia.org/wiki/Cognitive_science" rel="noopener noreferrer"&gt;cognitive science&lt;/a&gt; behind how we write CSS-in-JS today and how you can start incorporate these principles into your apps and libraries in the future to improve the readability and maintainability of your code!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick aside:&lt;/em&gt; Trousers is simply standing on the shoulders of other great libraries, so full credit to the people and libraries that inspired it!&lt;/p&gt;

&lt;p&gt;Please do yourself a favour and checkout these fantastic libraries if you haven’t already:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://compiledcssinjs.com/" rel="noopener noreferrer"&gt;Compiled&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stitches.dev/" rel="noopener noreferrer"&gt;Stitches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://emotion.sh/" rel="noopener noreferrer"&gt;Emotion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 👋&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>html</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learnings from migrating Atlaskit to TypeScript</title>
      <dc:creator>Daniel Del Core</dc:creator>
      <pubDate>Thu, 22 Oct 2020 06:13:52 +0000</pubDate>
      <link>https://forem.com/danieldelcore/learnings-from-migrating-atlaskit-to-typescript-379</link>
      <guid>https://forem.com/danieldelcore/learnings-from-migrating-atlaskit-to-typescript-379</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpcf4u5y0jpkgxx9cbk7f.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpcf4u5y0jpkgxx9cbk7f.jpeg" alt="IMG_1891" width="800" height="882"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This blog is aimed at people who are considering migrating their large projects to TypeScript!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So TypeScript support has recently landed in &lt;a href="https://atlassian.design/" rel="noopener noreferrer"&gt;Atlaskit 🎉&lt;/a&gt; and what a journey it was! I think now is a good time to reflect on what I found worked and what I would do if I was to do it all over again.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Full disclosure:&lt;/em&gt; It was a large and challenging undertaking… but one I would encourage regardless!&lt;/p&gt;

&lt;h2&gt;
  
  
  Our project
&lt;/h2&gt;

&lt;p&gt;In the spirit of transparency, I'd like to share some rough resource numbers, to give you an idea of what you might be in for.&lt;/p&gt;

&lt;p&gt;We had roughly ~10 different engineers working on the project over its lifespan. At the start, we had 5 people working on it full-time. This is where we made most of our progress. But as time went on, naturally people were pulled into other, more important initiatives and so about halfway through and we dropped back to 1 to 2 full-time engineers at best, for the remainder of the project. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's important to note that we were also juggling other priorities such as support, bugs, other projects, etc.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The whole effort spanned *&lt;em&gt;~6 months all up&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #1: Automate everything 🤖
&lt;/h2&gt;

&lt;p&gt;I can't stress this enough, use or build your own automation to do the tedious bits. You'll likely never get something that converts perfectly, but you can get most of the way there.&lt;/p&gt;

&lt;p&gt;This worked for us: &lt;a href="https://github.com/alexreardon/sink" rel="noopener noreferrer"&gt;alexreardon/sink&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It automated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transformed our already type-safe flow code and converted whatever syntax it could into TypeScript&lt;/li&gt;
&lt;li&gt;It renamed files from &lt;code&gt;.js&lt;/code&gt; to &lt;code&gt;.ts&lt;/code&gt; &amp;amp; &lt;code&gt;.tsx&lt;/code&gt; (surprisingly tedious)&lt;/li&gt;
&lt;li&gt;Added TS specific configuration files&lt;/li&gt;
&lt;li&gt;Removed old configuration files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sink is highly Atlaskit specific, but consider taking a similar approach. You wont regret it 😉!&lt;/p&gt;

&lt;p&gt;In hindsight I wish we invested more time in automating our conversion. If I was to do it again today, I would definitely investigate an &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;AST based approach&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But still definitely worth the upfront effort!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #2: Do not refactor AND convert to TypeScript 🔥
&lt;/h2&gt;

&lt;p&gt;It is really tempting to refactor code as you go, but you must &lt;strong&gt;resist the urge to clean up code while you're migrating at all costs!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you're migrating you'll look at every line of code critically. You're bound to find things that bother you. But it's important to resist because the risk of introducing a regression is extremely high and there is a strong chance that you or your PR reviewers will miss issues. Think about it, you're touching a lot of files, your PR diff is already cluttered with deltas, and then introducing logic changes on top of that  -  A recipe for disaster🔥. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Trust me on this one 😅&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just focus on moving from one working state to the next. If you need to refactor your component it should be a separate activity all together. Make a note or Jira ticket somewhere, do it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #3: Enable allowJs 🌲
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;allowjs: Allow JavaScript files to be compiled.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your codebase is big, do yourself a favor and enable allowJs so you can progressively convert components file-by-file, instead of doing an entire component at a time, which is what we did 😆. I found that it blew-out the size of the PRs and made getting past CI a real pain in the butt 🍑.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #4: Capture the Gotchas 🗒
&lt;/h2&gt;

&lt;p&gt;Keep a list of rules / best practices to govern the team. There are lots of little scenarios that happen over and over such as: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Which event handler do I use for this prop? How do I type HOCs? When should I use an &lt;code&gt;interface&lt;/code&gt; over a &lt;code&gt;type&lt;/code&gt;? Should I export my props?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Form these opinions as a team, share resources, discuss together and document it for later use. &lt;/p&gt;

&lt;p&gt;Here are some resources we used…&lt;/p&gt;

&lt;p&gt;Absolute god-send: typescript-cheatsheets/react&lt;/p&gt;

&lt;p&gt;You might also find these useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/piotrwitek/react-redux-typescript-guide" rel="noopener noreferrer"&gt;piotrwitek/react-redux-typescript-guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://product-fabric.atlassian.net/wiki/spaces/PRODUCT/pages/19333469/TypeScript+Styleguide" rel="noopener noreferrer"&gt;TypeScript Styleguide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/TypeScript-Handbook" rel="noopener noreferrer"&gt;microsoft/TypeScript-Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://levelup.gitconnected.com/ultimate-react-component-patterns-with-typescript-2-8-82990c516935" rel="noopener noreferrer"&gt;Ultimate React Component Patterns with Typescript 2.8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tip #5: Go upwards from the leaf nodes 🍂
&lt;/h2&gt;

&lt;p&gt;This should be a no-brainer: Start with the most simple and dependency-free components you have and move up and up the tree until you're finished.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #6: Beware the HOC 🐲
&lt;/h2&gt;

&lt;p&gt;In our conversion the most challenging obstacle to overcome, by far, was successfully typing a HOC (higher order component). Handle these with the most care, because it's possible that the return type of a HOC can be incorrectly typed. &lt;/p&gt;

&lt;p&gt;It's worth noting here that HOCs come in different flavors and the way you approach typing them varies slightly. If you get stuck check out these guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/piotrwitek/react-redux-typescript-guide#higher-order-components" rel="noopener noreferrer"&gt;Higher-Order Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/piotrwitek/react-redux-typescript-guide#--hoc-wrapping-a-component" rel="noopener noreferrer"&gt;HOC wrapping a component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/piotrwitek/react-redux-typescript-guide#--hoc-wrapping-a-component-and-injecting-props" rel="noopener noreferrer"&gt;HOC wrapping a component and injecting props&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing thoughts 🙏
&lt;/h2&gt;

&lt;p&gt;Don't let this blog discourage you, it was totally worth every second of the effort in my eyes. We found countless bugs in the process, we learned a lot about the quality of our components and in general feel like we're walking away with an a lot more stable codebase! &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>An approach to theming Design Systems</title>
      <dc:creator>Daniel Del Core</dc:creator>
      <pubDate>Tue, 29 Sep 2020 01:41:16 +0000</pubDate>
      <link>https://forem.com/danieldelcore/how-to-approach-theming-a-design-system-5829</link>
      <guid>https://forem.com/danieldelcore/how-to-approach-theming-a-design-system-5829</guid>
      <description>&lt;p&gt;To create a theme that will scale with the needs of your organisation, you must first choose the set of rules and principles that contribute to a scalable, flexible and sane theming solution. These rules need to be incorporated into a specification which will eventually need to be supported as a first-class API contract between your Design System and consumers.&lt;/p&gt;

&lt;p&gt;A theme can be thought of as a set of variables or 'global tokens' that are applied globally to your components. Containing all of the colours, spacing units and typography rules. Together they define how your components look and feel (not their behaviour). Allowing you to provide tailored and accessible experiences via dark mode, high contrast mode and more. &lt;/p&gt;

&lt;p&gt;Themes need to conform to some form of  'Theme specification', a schema which describes the structure, naming conventions, properties, data types, and scales of our theme. The definition of this schema carries hidden long-term implications, so it's important to define these rules with care. Let's walk through a some solutions you can put in place to navigate these complexities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theming is not the silver bullet for customisation
&lt;/h2&gt;

&lt;p&gt;Firstly, I want to call out that customisation is tricky. There are many ways to achieve it and all come with a healthy amount of pros and cons. It's a matter of using the right tool for the job. Global Theming is no exception, it's a great tool for rapidly and consistently effect change to colours and spacing and seeing immediate results, but it does not have any way to express component behaviour. Nor should it be expected to turn your Design System into a completely white-label suite of components. There are just too many tiny decisions baked into every aspect modern components, it would simply be next to impossible to control every case.&lt;/p&gt;

&lt;p&gt;Instead, think of a theme as the broad brushstrokes of customisation. Almost always used alongside other techniques such as Props, Composition, Overrides, CSS hacks etc. &lt;/p&gt;

&lt;p&gt;Setting the expectations of what theming is and what it is not is important to ensure the solution isn’t carrying too much of a burden, which is often followed by degraded performance and increased cognitive overhead. In short, doing less is always best (ha). &lt;/p&gt;

&lt;p&gt;Most Design Systems offer multiple avenues for customisation, but the decision making should be in the hands of users to choose the right approach for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Themes are a reflection of UI anatomy
&lt;/h2&gt;

&lt;p&gt;Consider the following example of a theme:&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.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transparent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;black&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;gray&lt;/span&gt;&lt;span class="p"&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="s2"&gt;#eeeeee&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="s2"&gt;#202633&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each colour defined here describes a value not a destination. What if you want to invert black and white in your UI to create a dark theme? You might naively switch the values, but then quickly realise that the names become a lie. Black is white and white is black.&lt;/p&gt;

&lt;p&gt;Moreover, consumers of the theme might be using these colours in different ways. &lt;code&gt;gray.light&lt;/code&gt; might be a great background colour to one developer, but also might already be used as a background by secondary buttons. Eventually, someone will want to tweak the theme’s background colour (&lt;code&gt;gray.light&lt;/code&gt;) which might then break colour contrast for secondary buttons. There’s nothing stopping these values from being inadvertently mixed up, causing wide-reaching issues. Remember we are operating in the global scope 🌏.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqoen00rljzatiuja8672.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqoen00rljzatiuja8672.jpeg" alt="human skeleton diagram" width="800" height="913"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similar to how every ridge, bump and groove of a human skeleton 💀 has been analysed, named and catalogued, so should every facet of our UI “anatomy”, if you will. That catalogue is the Theme, which describes the relationship between spacing, colours, focus rings, typography, etc have with the particular ridges and grooves of our UI, Buttons, Navigation, Forms... &lt;/p&gt;

&lt;p&gt;So with that in mind, the theme above &lt;em&gt;might&lt;/em&gt; be better represented in the form:&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.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#393939&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#439dfa&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;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#eee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;aside&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#e2e8f0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;footer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#e2e8f0&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see some of the primary elements of the &lt;a href="https://en.wikipedia.org/wiki/Holy_grail_(web_design)" rel="noopener noreferrer"&gt;Holy grail&lt;/a&gt; are listed here. These concepts are abstract in meaning and don’t refer to any specific component, they are simply parts of a typical webpage’s anatomy that you, the designer or developer, are already familiar with. These “concepts” are what I believe is the key to encoding semantic and contextual meaning into a theme.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theme properties should have contextual &amp;amp; semantic meaning
&lt;/h2&gt;

&lt;p&gt;Through describing where properties are intended to be used, rather than the value they hold, via abstract concepts, users of the theme should find it intuitive and easy to use the correct properties in the correct place.&lt;/p&gt;

&lt;p&gt;Given the examples above, consider a user wants to ensure some text on the page is using the correct typography colour, the structure and naming of the theme describes to them the best fit. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Before:&lt;/em&gt;&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;CustomHeading&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;h1&lt;/span&gt;&lt;span class="s2"&gt;`
  font-size: 3rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;black&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;After:&lt;/em&gt;&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;CustomHeading&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;h1&lt;/span&gt;&lt;span class="s2"&gt;`
  font-size: 3rem;
  color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heading&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hierarchy integrates our intention for each theme property into the structure of the theme. It’s clear that for  typography colours, it’s probably best to use &lt;code&gt;color.typography.element&lt;/code&gt; and so, if I decide to use a background colour to style some text, I’m probably doing something wrong and it's going to be prone to breaking sometime in the future. &lt;/p&gt;

&lt;p&gt;It’s also worth noting that &lt;a href="https://material-ui.com/customization/default-theme/" rel="noopener noreferrer"&gt;Material-UI already does a great job&lt;/a&gt; of using hierarchy to group properties into significant elements. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3guvziygqja9snyhki00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3guvziygqja9snyhki00.png" alt="screenshot of material-ui theme hierarchy" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Values making up the theme should be restricted to ‘Brand Tokens'
&lt;/h2&gt;

&lt;p&gt;Values that populate our theme should be limited to the set of 'Brand Tokens' for use within your organisation, so whichever combination of values selected from these tokens, the end result will still be distinctly on brand. &lt;/p&gt;

&lt;p&gt;Not all brand tokens need to be in use for any given theme. They’re just the available “pool” of options for you to choose from. For extreme use-cases it’s still possible to substitute your own values.&lt;/p&gt;

&lt;p&gt;Again, taking the example from above, moving the values into ‘Brand tokens’ allows us to apply colours consistently without picking arbitrary values.&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;// tokens.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;neutral50&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#eee&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;neutral100&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#e2e8f0&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;neutral500&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#393939&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;neutral600&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#000&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;blue100&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#439dfa&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;blue200&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#439ddd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// theme.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;anchor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blue100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;aside&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;footer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral100&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;In a dark mode theme, you could simply replace the lighter tokens with darker ones whilst still conforming to your Brand.&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-dark-mode.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;anchors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blue200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;aside&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;footer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;neutral600&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;h2&gt;
  
  
  Scales need to defined and consistently applied
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;If I use T-shirt sizing can I scale it to suit my needs in the future? Will an array carry enough semantics for others to understand? How can I describe progression of colour?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No doubt you’ve already done these mental gymnastics when trying to rationalise a scale or a group of related values. Choosing the right scales can be hard. They need to be consistent, flexible and hold some form of semantic value. The right system also needs to be paired with the right type of value, e.g. T-Shirt sizes can’t describe colours. It’s a tricky problem and it imposes a large obstacle to the flexibility and longevity of your theme. &lt;/p&gt;

&lt;p&gt;As you would expect there has already been plenty of thought on this, so i’ll point you to this &lt;a href="https://medium.com/eightshapes-llc/size-in-design-systems-64f234aec519" rel="noopener noreferrer"&gt;wonderful blog&lt;/a&gt; incase you wanted to go into more detail.&lt;/p&gt;

&lt;p&gt;I’ve seen a handful of scales used in themes in the wild, here are a few popular ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;T-Shirt sizing: &lt;code&gt;xxs, xs, s, m, l,xl, xxl, xxxl, xxxxl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Arrays: &lt;code&gt;fontSizes: [14, 16, 18, 24, 32]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enumeration: &lt;code&gt;b100, b200, b300&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Degrees of x: &lt;code&gt;lighter, light, lightest, lightestest…&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like everything, all have pros &amp;amp; cons, but to offer up an alternate opinion. What if we could extend on the thinking above and use that same thought process to side step the scales conversation? &lt;/p&gt;

&lt;p&gt;Consider spacing, you have an obvious set of options for defining a scale of spaces, you might use an array or T-Shirt sizes. But those values are still subjective, some people might use &lt;code&gt;space.m&lt;/code&gt; where others use &lt;code&gt;space.s&lt;/code&gt; it’s still largely open to interpretation. What if every value in the spacing scale had a finite set of use-cases and those use-cases could be encoded into the name, the same way we did with colours above? &lt;/p&gt;

&lt;p&gt;Stealing an image from &lt;a href="https://medium.com/eightshapes-llc/space-in-design-systems-188bcbae0d62" rel="noopener noreferrer"&gt;this blog by Nathan Curtis&lt;/a&gt; (definitely worth a read).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpambnkdr5w1c1ye3k90i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpambnkdr5w1c1ye3k90i.png" alt="Spacing types diagram" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We could use those concepts to define a new spacing scale:&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;// tokens.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;space50&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.5rem&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;space100&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1rem&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;space200&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2rem&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;space300&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3rem&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;space400&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4rem&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;space500&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// theme.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{...},&lt;/span&gt;
  &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;squishedInset&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;space100&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;space50&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="na"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space400&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;Now when choosing a spacing value for a new container component, we can take the guesswork out of the process, since we know that &lt;code&gt;space.inset&lt;/code&gt; is primarily used for padding the inside of containing elements. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most collaborators can’t see space, a primary reason it’s so arbitrarily applied. But now we’ve got a system: a limited number of concepts, each offering a limited range of options.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But weight (hehe get it?) there’s more, since one &lt;code&gt;inset&lt;/code&gt; is never going to be enough, now is the perfect time to introduce a scale to provide more granular control within the safe boundaries of a meaningful naming convention.&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;// tokens.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;space50&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.5rem&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;space100&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1rem&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;space200&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2rem&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;space300&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3rem&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;space400&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4rem&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;space500&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// theme.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{...},&lt;/span&gt;
  &lt;span class="na"&gt;space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;medium&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space400&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;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, the spacing scale is not as inclined to grow organically into a huge unmanageable array of values as new values are eventually added, making the system more resilient to change over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Theme’s concepts should be well documented
&lt;/h2&gt;

&lt;p&gt;Lastly, it is not enough to have a great theme, it needs good documentation because when used incorrectly it has the potential to destroy its value and lock API maintainers into a lifetime of breaking changes and workarounds.&lt;/p&gt;

&lt;p&gt;With all of these abstract concepts in place like “scales”, “inset”, “squish”, “token”, there needs to be a somewhere people can go to make sense of it all. So again, i’ll point you to &lt;a href="https://medium.com/eightshapes-llc/space-in-design-systems-188bcbae0d62" rel="noopener noreferrer"&gt;this blog&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Teach your spatial concepts using a tight doc diagram or cheat sheet. Such references quicken how we grasp, apply, and sustain the concepts through design and code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc8kxo98yi3zryfsfvljd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc8kxo98yi3zryfsfvljd.png" alt="spacing doc diagram" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And better yet, visual prototyping tools can bring the docs to life by giving users a feel for what they’re changing as they’re changing it. And the ability alter UI in broad brushstrokes 🖌.&lt;/p&gt;

&lt;p&gt;The ecosystem has already made a headstart on this: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hihayk.github.io/shaper/" rel="noopener noreferrer"&gt;https://hihayk.github.io/shaper/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://seek-oss.github.io/braid-design-system/playroom/" rel="noopener noreferrer"&gt;https://seek-oss.github.io/braid-design-system/playroom/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openchakra.app/" rel="noopener noreferrer"&gt;https://openchakra.app/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With good documentation in place, a greater overall understanding of how the theme should be used can form within your organisation. Future changes to the theme, as it grows organically overtime, fit into the already understood frameworks and paradigms we’ve defined (and documented). New themes can be designed, published and shared easily between products, teams and users. And limitations of a theme for customisation purposes become more apparent, prompting people to take more appropriate avenues to customisation problems they’re trying to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for coming 👋
&lt;/h2&gt;

&lt;p&gt;There are many ways to skin the big fat theming cat 😺, so treat this blog as merely a set of observations and ideas you could potentially incorporate into your Design System. &lt;/p&gt;

&lt;p&gt;Please feel free to post your ideas and opinions below, i’d love to hear them!&lt;/p&gt;

</description>
      <category>theming</category>
      <category>css</category>
      <category>react</category>
      <category>tokens</category>
    </item>
  </channel>
</rss>
