<?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: Matt Hagner</title>
    <description>The latest articles on Forem by Matt Hagner (@hagnerd).</description>
    <link>https://forem.com/hagnerd</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%2F112962%2Fb1373942-b945-4d16-af76-c448e080d14a.jpeg</url>
      <title>Forem: Matt Hagner</title>
      <link>https://forem.com/hagnerd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hagnerd"/>
    <language>en</language>
    <item>
      <title>A Primer on Testing &amp; TDD</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Fri, 09 Aug 2019 14:14:42 +0000</pubDate>
      <link>https://forem.com/hagnerd/a-primer-on-testing-tdd-9a5</link>
      <guid>https://forem.com/hagnerd/a-primer-on-testing-tdd-9a5</guid>
      <description>&lt;p&gt;There are two types of people in the world: those who love testing in React, and those who have never tried &lt;code&gt;@testing-library/react&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I joke, but this article is a light introduction into what test-driven&lt;br&gt;
development is, why I find it useful with front end development, an overview of what should be tested, and what the differences are between different kinds of tests.&lt;/p&gt;

&lt;p&gt;There are a lot of opinions that I express in this article that pertain to my personal style of development. You may not agree with some or all of my opinions and that totally is fine.&lt;/p&gt;

&lt;p&gt;This is the first article in a series on testing in React. In the next post I will talk about &lt;code&gt;@testing-library/react&lt;/code&gt; for unit testing, so if you'd like to be notified of future posts make sure to follow.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is test-driven development?
&lt;/h2&gt;

&lt;p&gt;Test-driven development took rise during the early 2000s. The basic premise was that we should write our tests &lt;em&gt;before&lt;/em&gt; we write our implementations to avoid the false-positive affirmation that can happen when you write tests &lt;em&gt;after&lt;/em&gt; you write your implementation. &lt;/p&gt;

&lt;p&gt;The main ethos of test-driven development can be summed up in three words: red, green, refactor.&lt;/p&gt;

&lt;p&gt;You write a test that you know will fail because you haven't implemented the feature yet. You write code to make that test pass. And now you can refactor the portion of code that is tested with confidence.&lt;/p&gt;

&lt;p&gt;You repeat the cycle by writing more tests to cover other aspects of the feature, tests against regressions, and tests against edge cases you discover.&lt;/p&gt;

&lt;p&gt;Test-driven development can be extremely powerful, however, the goal isn't to have 100% code coverage and you shouldn't feel the need to write a test for every little thing. This can be a slippery slope and at some point writing more tests is &lt;em&gt;not&lt;/em&gt; going to increase your confidence in the code base, or make you more productive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why do &lt;em&gt;I&lt;/em&gt; write tests?
&lt;/h2&gt;

&lt;p&gt;I write tests because I've found that when employing test-driven development it helps me write more ergonomic components. I avoid poor design choices the first time around because I write the usage before I write the implementation.&lt;/p&gt;

&lt;p&gt;Having tests written for a component or feature helps me refactor with confidence. If the test was passing before I made a change and the behavior is expected to be the same, then any change I make should not make the test fail. If it does I've either 1) broken the contract and will need to update all usage of the component throughout the application, or 2) tested implementation details and I should delete the tests if not needed, or update them to not test implementation details.&lt;/p&gt;

&lt;p&gt;I've also found that when practicing test-driven development I'm a lot more focused. I can write down some expectations, set a timer for 25 minutes, and then get to work. I focus on one thing at a time. Write a test. Watch the test fail. Start implementing the feature. Watch the test pass. Refactor if needed. And then move on to the next thing. I tend to get a lot more done a lot faster than if I just start writing code without a clear direction in mind.&lt;/p&gt;




&lt;h2&gt;
  
  
  What should we test?
&lt;/h2&gt;

&lt;p&gt;A better first question might be who should we write tests for? The answer is pretty simple. Our users. As developers we have two users of our code. The actual end-user who is interacting with our website or application, and our future selves or other developers who will use our code to implement other features or make changes to our code.&lt;/p&gt;

&lt;p&gt;For example let's say we need to make a Button in React. There could be a developer who uses that Button in a different part of the application, and there could be a user of the app who interacts with that Button.&lt;/p&gt;

&lt;p&gt;The parts that those two users need to interact with should be the things that we test. What are their expectations? What are our intentions?&lt;/p&gt;

&lt;p&gt;The user probably expects to be able to interact with it. Depending on the context of the button on the page they could expect it to submit a form, lead them to a new page (a link that looks like a button), to increment a counter, to save some data, etc.&lt;/p&gt;

&lt;p&gt;The developer might expect to be able to pass their own click handler into it and have it fire reliably. They might expect to be able to change the button text, override, append, or modify styles, they might expect to have some mechanism for disabling the button.&lt;/p&gt;

&lt;p&gt;Some of these expectations can be tested in a generic way at the unit level, and some will make more sense as an integration test where the component is actually being used in a specific context. &lt;/p&gt;

&lt;p&gt;We can even use static testing via linters or tools like Storybook and the a11y addon to test our code for best practices. Like making sure that we are using a button for interactive elements or passing the DOM element the applicable aria properties like &lt;code&gt;role=button&lt;/code&gt;, &lt;code&gt;aria-pressed&lt;/code&gt; and making it focusable if we are using something like a div.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A11y is shorthand for accessibility. A, 11 letters in the middle, y. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Unit vs Integration vs End to End
&lt;/h2&gt;

&lt;p&gt;Guillermo Rauch once tweeted "Write tests. Not too many. Mostly integration". I think this is a pretty good tweet to model your testing practices after. &lt;/p&gt;

&lt;p&gt;So what are some of the different types of tests?&lt;/p&gt;

&lt;h3&gt;
  
  
  Unit Tests
&lt;/h3&gt;

&lt;p&gt;Unit tests are tests centered around a unit of code. It could be a singular function, or a component. When you first start testing you will typically write a lot of unit tests. Soon you will realize though that they don't really give you confidence in your &lt;em&gt;application&lt;/em&gt;, instead in an &lt;em&gt;isolated&lt;/em&gt; piece of code. You end up having to mock a lot of things, and any time you have mocks in your tests your overall confidence in these tests are lowered.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note on mocking. Sometimes it's necessary to mock some functionality or 3rd party library. Take data fetching for example. You don't want to be making requests to APIs in your tests because this would make your tests slow. You also don't know when or how many times your tests will be run so making potentially dozens or hundreds of requests every time your tests run 😬 That's a big yikes from me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Integration Tests
&lt;/h3&gt;

&lt;p&gt;Integration tests focus on larger chunks of code. In React it could be a page, or a larger component like a form that contains a bunch of smaller components. Integration tests are the bread and butter of testing. This is where you are testing the actual usage of your components, instead of testing the potential usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  End to End Tests
&lt;/h3&gt;

&lt;p&gt;End to end tests are typically harder to set up, and more costly to run. You should still consider having end to end test in your code base. End to end tests simulate user interaction through the entire application/website. Usually you will test certain flows through the application like signing a user up, making a new post, editing the post, or deleting a post the user is authorized to delete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Property-Based Tests
&lt;/h3&gt;

&lt;p&gt;Property-based testing hasn't really made too many waves in JavaScript but is popular in languages like Clojure and Elixir. We won't do any property-based testing in this series but the idea is that you test a provable property (think of mathematical properties) against your piece of code, you use some sort of input generation, and it can catch edge cases where that property breaks. &lt;/p&gt;

&lt;h3&gt;
  
  
  Static Tests aka Static Analysis
&lt;/h3&gt;

&lt;p&gt;While not necessarily &lt;em&gt;tests&lt;/em&gt; in the traditional sense, static analysis is the combination of tools like Eslint, and type checkers (if you're using a statically typed language like TypeScript), among other things, that allow you to check your code for correctness in some way. When static analysis is used correctly it helps you catch potential bugs early, or notify that you are doing something you shouldn't, like putting an &lt;code&gt;onClick&lt;/code&gt; handler on a div instead of just using a button. When used incorrectly, like using Airbnb's Eslint rules, static analysis will cause you headaches and make you significantly less productive, unless of course you work at Airbnb and need to adhere to their code style guide.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We've talked about what test-driven development is, why I like to practice test driven development, how to identify what we should be testing, and what the difference between different types of tests are.&lt;/p&gt;

&lt;p&gt;If you have any questions please post them in the comments.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>react</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Setting up Tailwind With create-react-app</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Fri, 02 Aug 2019 13:58:42 +0000</pubDate>
      <link>https://forem.com/hagnerd/setting-up-tailwind-with-create-react-app-4jd</link>
      <guid>https://forem.com/hagnerd/setting-up-tailwind-with-create-react-app-4jd</guid>
      <description>&lt;h2&gt;
  
  
  What is Tailwind?
&lt;/h2&gt;

&lt;p&gt;Tailwind is a functional CSS framework that is ergonomic to use, but low level enough to make it fully customizable. You can configure it, add plugins, and override defaults. It generates CSS class names for you so that you can use compose them throughout your project.&lt;/p&gt;

&lt;p&gt;I've found that Tailwind lends itself particularly well to developing components in React and Vue.&lt;/p&gt;




&lt;h2&gt;
  
  
  What does it look like?
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputProps&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;input&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;"px-2 py-1 text-gray-700 bg-gray-200 rounded-lg shadow-md border-2 border-gray-800 focused:border-blue-400"&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="si"&gt;}&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;What do all of those classes mean? Most of the classes should be pretty self explanatory. The &lt;code&gt;px-2&lt;/code&gt; and &lt;code&gt;py-1&lt;/code&gt; are horizontal (x), and vertical (y) padding respectively. The &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; refer to the sizing. &lt;/p&gt;

&lt;p&gt;By default Tailwind generates a set of sizes for you that you can customize. Sizing 1 starts at &lt;code&gt;0.25rem&lt;/code&gt; and the sizing goes up by &lt;code&gt;0.25rem&lt;/code&gt; each step.&lt;/p&gt;

&lt;p&gt;The class naming follows pretty easy to understand conventions so once you start learning some you will understand how to use most. For instance to set a margin vertical margin of 2 rem you would use the class name &lt;code&gt;my-8&lt;/code&gt;. &lt;code&gt;m&lt;/code&gt; because you are setting margin, &lt;code&gt;y&lt;/code&gt; because you want to set only the vertical axis margin, and &lt;code&gt;8&lt;/code&gt; because you want 2 rem and the sizing is 4 per rem.&lt;/p&gt;

&lt;p&gt;Things that can accept a color value like text, border, or background have their prefix &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt; and &lt;code&gt;bg&lt;/code&gt;, followed by the color name &lt;code&gt;text-gray&lt;/code&gt;, &lt;code&gt;border-gray&lt;/code&gt; or &lt;code&gt;bg-gray&lt;/code&gt; and then a value from 100-900 that jumps by 100. So &lt;code&gt;text-gray-700&lt;/code&gt; will make the text a fairly dark gray, and &lt;code&gt;bg-gray-200&lt;/code&gt; will give the background a fairly light gray color.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;focused:border-blue-400&lt;/code&gt; class applies a blue 400 color to the border when the focused pseudo class is active for the element.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rounded&lt;/code&gt; has a number of suffixes to affect the class like &lt;code&gt;sm&lt;/code&gt;, &lt;code&gt;lg&lt;/code&gt;, and &lt;code&gt;full&lt;/code&gt; with the default being a medium rounded border if there isn't a suffix. There is even the ability to change any corner individually.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shadow&lt;/code&gt; is similar to &lt;code&gt;rounded&lt;/code&gt; but with the default being small with no suffix, and sizing all the way to &lt;code&gt;2xl&lt;/code&gt;. Additional modifiers that make sense for a box shadow are also available like &lt;code&gt;inner&lt;/code&gt; or &lt;code&gt;outline&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why would you use it?
&lt;/h2&gt;

&lt;p&gt;When you get into the flow it's like writing regular CSS with shorthands except you don't have to do it in a separate file, you don't have to come up with a bunch of class names, and you don't have to possibly update two files every time you change the styles for a single element.&lt;/p&gt;

&lt;p&gt;It  makes your code easier to delete. We'll touch on this more later, but traditional CSS is append only, which means it is really hard to know when you are okay to delete some styles. &lt;/p&gt;

&lt;p&gt;Component based styling, which you can absolutely do with Tailwind, allows you to delete the styles along with the component when you no longer need it.&lt;/p&gt;

&lt;p&gt;Tailwind is also totally and completely extendable. Want to add different colors, or change the ones included with Tailwind? You totally can and the API to do so is pretty well &lt;a href="https://tailwindcss.com/docs/configuration" rel="noopener noreferrer"&gt;documented&lt;/a&gt; and easy to follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we set up create-react-app to use Tailwind?
&lt;/h2&gt;

&lt;p&gt;Let's set up our project by scaffolding a new react app with &lt;code&gt;create-react-app&lt;/code&gt;. If you don't have it installed you can use npx.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx create-react-app setting-up-tailwind &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;setting-up-tailwind


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we need to install some dev dependencies.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; tailwindcss autoprefixer postcss-cli


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the root of the project create a &lt;code&gt;postcss.config.js&lt;/code&gt; file and open it up in your favorite editor.&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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&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;tailwindcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;autoprefixer&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;If you're interested in finding out more about PostCSS check out the &lt;a href="https://github.com/postcss/postcss" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Autoprefixer is recommended to install alongside Tailwind, because autoprefixer automatically tracks caniuse.com to see which CSS properties still need to be prefixed, and out of the box Tailwind does not provide any vendor prefixing.&lt;/p&gt;

&lt;p&gt;Now we should initialize Tailwind. This will create a tailwind.config.js file in the root of our project with a default configuration. This step is optional, but I usually do this when setting up a Tailwind project so that I can customize things later without having to come back.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx tailwind init


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you open it up it looks pretty barren right now. Maybe in a different post I'll go over adding plugins, or customizing Tailwind.&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;// tailwind.config.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extend&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;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;plugins&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;We also need to create an input CSS file for PostCSS to process with Tailwind. I usually call this &lt;code&gt;tailwind.css&lt;/code&gt; and add it to the &lt;code&gt;src&lt;/code&gt; folder in my React projects, but you can name it whatever, and place it in any place that makes sense to you.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* src/tailwind.css */&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;These are Tailwind directives that add the three main parts of core Tailwind. You can make your bundle smaller by omitting one or multiple if you don't need them, but to get the most from Tailwind you will probably end up using at least some classes from each.&lt;/p&gt;

&lt;p&gt;When Tailwind (the first plugin in PostCSS) sees these directives it will replace each &lt;code&gt;@tailwind &amp;lt;name&amp;gt;&lt;/code&gt; with some CSS.&lt;/p&gt;

&lt;p&gt;To make it easy on ourselves in the future case where we might be changing the &lt;code&gt;tailwind.config.js&lt;/code&gt; we should add a few scripts to our &lt;code&gt;package.json&lt;/code&gt; file. Add the following three scripts to the scripts object.&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;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="c1"&gt;//... place these after the four scripts created by CRA&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:styles&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;postcss src/tailwind.css -o src/styles.css&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;prebuild&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;yarn build:styles&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;prestart&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;yarn build:styles&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;p&gt;Or if you use npm change &lt;code&gt;yarn&lt;/code&gt; to &lt;code&gt;npm run&lt;/code&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="c1"&gt;//...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="c1"&gt;//... place these after the four scripts created by CRA&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:styles&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;postcss src/tailwind.css -o src/styles.css&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;prebuild&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;npm run build:styles&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;prestart&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;npm run build:styles&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;
  
  
  Building our React component
&lt;/h2&gt;

&lt;p&gt;Let's delete some of the unnecessary stuff that create-react-app makes for us.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;rm &lt;/span&gt;src/App.test.js src/App.css src/index.css src/logo.svg


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open up &lt;code&gt;src/index.js&lt;/code&gt; and make the following changes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="nx"&gt;ReactDOM&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-dom&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;./styles.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- change './index.css' to './styles.css'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&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;./App&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;serviceWorker&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;./serviceWorker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregister&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now open up &lt;code&gt;src/App.js&lt;/code&gt;, delete the whole thing and start from scratch.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/App.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/button&lt;/span&gt;&lt;span class="dl"&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;App&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="s"&gt;"flex flex-col w-3/4 mx-auto my-12 items-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Super cool page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&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;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I was clicked&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;
        I am a button
      &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;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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's create a simple button component, this will be a small wrapper around a normal button, but will contain some styles. I'm making this component in a &lt;code&gt;components&lt;/code&gt; directory inside of &lt;code&gt;src&lt;/code&gt;, but you can put the component wherever you want.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/components/button.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&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;buttonProps&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;button&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;"px-2 py-1 rounded-lg bg-green-400 text-green-800 text-xl font-light uppercase shadow-md hover:shadow-lg"&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;buttonProps&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;If you run yarn start now you should see that PostCSS is processing our styles for us, and then you should see something like this.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fofjwq1nujeugmrrdj884.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fofjwq1nujeugmrrdj884.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Such beauty. It is almost too much to behold!
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Checking our app out in production
&lt;/h2&gt;

&lt;p&gt;So our app is looking great now and we are ready to send it off into the world, but first we need to build for production. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn build


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now to check our production build, we can use a tool like &lt;code&gt;serve&lt;/code&gt;. Either install it globally, &lt;code&gt;yarn global add serve&lt;/code&gt; or you can use npx.&lt;/p&gt;

&lt;p&gt;If you installed globally you'll use&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

serve &lt;span class="nt"&gt;-s&lt;/span&gt; build


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;or if you want to use npx&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx serve &lt;span class="nt"&gt;-s&lt;/span&gt; build


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Sweet! Our page looks pretty rad if I do say so myself. Now let's just open up the developer tools in our browser, click on the network tab, refresh the page and see how slim our sleek new CSS is...&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fokekz472vdgw6ymemptw.gif" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fokekz472vdgw6ymemptw.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at the size of the CSS bundle. 350KB... Yikes! Why is it so big!? &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcul3usx78uu0gumn4sk4.gif" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcul3usx78uu0gumn4sk4.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well Tailwind generates classes. A lot of classes. The stylesheet that it generates is over 3000 lines long. But we are only using a fraction of those classes right now so what can we do?&lt;/p&gt;

&lt;h2&gt;
  
  
  Slimming Our Build
&lt;/h2&gt;

&lt;p&gt;There is a utility called PurgeCSS which will parse any files that match the given file globs for the usage of the selectors in your CSS. If a selector isn't present in any of the matched files, then it rips those styles out of the CSS, ultimately slimming the build. &lt;/p&gt;

&lt;p&gt;There is a PostCSS plugin for PurgeCSS so we can just install our new dependency, and add a little bit more set up to &lt;code&gt;postcss.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; @fullhuman/postcss-purgecss


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open up your &lt;code&gt;postcss.config.js&lt;/code&gt; file and make some additions. The following set up is taken &lt;a href="https://tailwindcss.com/docs/controlling-file-size/#setting-up-purgecss" rel="noopener noreferrer"&gt;directly from the Tailwind docs&lt;/a&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;// postcss.config.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;purgecss&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;@fullhuman/postcss-purgecss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;

  &lt;span class="c1"&gt;// Specify the paths to all of the template files in your project &lt;/span&gt;
  &lt;span class="na"&gt;content&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;./src/**/*.js&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;./public/index.html&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="c1"&gt;// Include any special characters you're using in this regular expression&lt;/span&gt;
  &lt;span class="na"&gt;defaultExtractor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Za-z0-9-_:&lt;/span&gt;&lt;span class="se"&gt;/]&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;)&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;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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&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;tailwindcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;autoprefixer&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&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;purgecss&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;The content property in the PurgeCSS plugin takes an array of file globs that it should check for the inclusion of CSS selectors. In a create-react-app project we want it to check all of our React components so we pass &lt;code&gt;./src/**/*.js&lt;/code&gt; which means check any nested folders inside of src for any file with an extension of &lt;code&gt;.js&lt;/code&gt;. We also want it to look at our &lt;code&gt;./public/index.html&lt;/code&gt; file because Tailwind uses Normalize, and without having it check the projects HTML page, it will gut a lot of the Normalize rules that we want it to include. &lt;/p&gt;

&lt;p&gt;There are some pitfalls with PurgeCSS, like it won't actually render your components to check dynamic class usage, so you want to avoid partial class names in dynamic renders and instead stick to full class names.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="c1"&gt;// DO NOT DO THIS&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;color&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="k"&gt;return&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="s2"&gt;`text-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"red-300"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Do not click me&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;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;///////////////////////////////////&lt;/span&gt;
&lt;span class="c1"&gt;// Instead do this!&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;color&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="k"&gt;return&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-red-300"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Do not click me&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;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The other thing that we need to do is make a slight modification to one of our scripts in &lt;code&gt;package.json&lt;/code&gt;. The addition of &lt;code&gt;NODE_ENV=production&lt;/code&gt; to our &lt;code&gt;prebuild&lt;/code&gt; script will set the environment variable for Webpack which create-react-app uses under the hood, and will trigger the PostCSS cli to use PurgeCSS in the building of our styles.&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;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="c1"&gt;//...&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prebuild&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;NODE_ENV=production yarn build:styles&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;p&gt;Now let's build for production, serve our app, open up the dev tools and check out our network tab again.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; serve &lt;span class="nt"&gt;-s&lt;/span&gt; build


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0wx5pm30wn1dltdrrtoi.gif" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0wx5pm30wn1dltdrrtoi.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Much better!&lt;/p&gt;

&lt;p&gt;If you want to further slim the build there is great documentation on &lt;a href="https://tailwindcss.com/docs/controlling-file-size/" rel="noopener noreferrer"&gt;how to control the size&lt;/a&gt; of Tailwind.&lt;/p&gt;




&lt;p&gt;So now you know how to set up Tailwind in your create-react-app projects and how to get some decent production wins with PurgeCSS + PostCSS. Let me know if you any questions in the comments, or if you enjoyed this article. &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>What is Shadowing in Gatsby Themes?</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Wed, 24 Jul 2019 02:28:11 +0000</pubDate>
      <link>https://forem.com/hagnerd/what-is-shadowing-in-gatsby-themes-3aj6</link>
      <guid>https://forem.com/hagnerd/what-is-shadowing-in-gatsby-themes-3aj6</guid>
      <description>&lt;p&gt;This is the continuation of a series on Gatsby themes. In previous posts we covered how to start a Gatsby site from scratch, how to add a theme, and how to use theme options to customize our website.&lt;/p&gt;

&lt;p&gt;We'll be picking up with Shadowing in Gatsby which is a powerful concept that allows you to use themes and customize only the parts that you want in a reliable, ergonomic way.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Shadowing?
&lt;/h2&gt;

&lt;p&gt;Shadowing is Gatsby's answer to customizing parts of a theme, without throwing the baby out of the bathwater. It would suck if you needed to re-wire &lt;code&gt;gatsby-theme-blog&lt;/code&gt; from scratch if you wanted to change some of the styles, components, or content. &lt;/p&gt;

&lt;p&gt;It would also suck to have a giant object with theme options for everything you want a user to be able to override. It would also suck if some theme creator made some component, or style NOT overridable.&lt;/p&gt;

&lt;p&gt;By making shadowing an inherent part of how Gatsby works, there is a consistent and simple way to override pretty much anything. &lt;/p&gt;

&lt;h2&gt;
  
  
  What can you Shadow?
&lt;/h2&gt;

&lt;p&gt;With Gatsby themes you can shadow styles, components, and data requirements (GraphQL queries). Anything that lives in the &lt;code&gt;src&lt;/code&gt; directory of a theme is fair game!&lt;/p&gt;

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

&lt;p&gt;Let's quickly change something small like the main color of our blog. I love purple, but you know what's an even better color? Tomato. &lt;/p&gt;

&lt;p&gt;To shadow something from a theme we follow a simple convention. Inside of our &lt;code&gt;src&lt;/code&gt; folder, we make a folder with the theme name, &lt;code&gt;gatsby-theme-blog&lt;/code&gt;, and then we mimic the path to the file in the theme itself but we ignore the &lt;code&gt;src&lt;/code&gt; inside of the theme. &lt;/p&gt;

&lt;p&gt;So &lt;code&gt;gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js&lt;/code&gt; becomes &lt;code&gt;src/gatsby-theme-blog/gatsby-plugin-theme-ui/colors.js&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Since we happen to want to change a color, and I happen to know that &lt;code&gt;gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js&lt;/code&gt; is the exact file that we need to shadow, we need to create some folders, and a new file in our Gatsby website so we can shadow it.&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; src/gatsby-theme-blog/gatsby-plugin-theme-ui
&lt;span class="nb"&gt;touch &lt;/span&gt;src/gatsby-theme-blog/gatsby-plugin-theme-ui/colors.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now pop open your favorite code editor and we are going to open up two files. File 1) &lt;code&gt;node_modules/gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js&lt;/code&gt; and file 2) &lt;code&gt;src/gatsby-theme-blog/gatsby-plugin-theme-ui/colors.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When I'm shadowing, I find it easiest to look at the thing I'm going to shadow, while working on the new file. &lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;node_modules/gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors.js&lt;/code&gt; file should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;purple60&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`#663399`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;purple30&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`#D9BAE8`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grey90&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`#232129`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;black80&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`#1B1F23`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;white&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`#fff`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightWhite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`rgba(255, 255, 255, 0.86)`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opaqueLightYellow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`rgba(255, 229, 100, 0.2)`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opaqueLightWhite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`hsla(0, 0%, 100%, 0.2)`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightGray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`hsla(0, 0%, 0%, 0.2)`&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;grey90&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="nx"&gt;white&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="nx"&gt;purple60&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="nx"&gt;black80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;muted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lightGray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;opaqueLightYellow&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;grey90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;prism&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="s2"&gt;`#011627`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#809393`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#addb67`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;var&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#d6deeb`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#f78c6c`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#82aaff`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;punctuation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#c792ea`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#ffc98b`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#ffa7c4`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#ff5874`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#80cbc4`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#b2ccd6`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`hsla(207, 95%, 15%, 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;modes&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lightWhite&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="nx"&gt;grey90&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="nx"&gt;purple30&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="nx"&gt;lightWhite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;muted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;opaqueLightWhite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;purple60&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;white&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;The color that we want to change is the &lt;code&gt;primary&lt;/code&gt; key in the object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;gray90&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="nx"&gt;white&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="nx"&gt;purple60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So what can we learn from this file? The first thing to take away is that we should have a default export in our shadowed &lt;code&gt;colors.js&lt;/code&gt; file. The second is that, unless we want to change a bunch of these values, we will need some way to merge the &lt;code&gt;gatsby-theme-blog&lt;/code&gt; colors, with our colors and just override the ones that we want to.&lt;/p&gt;

&lt;p&gt;Before we get to figuring out how to merge our colors object, let's make an export default and set the primary key to 'tomato'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&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;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;tomato&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;p&gt;Now the cool part...&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;colors&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;gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors&lt;/span&gt;&lt;span class="dl"&gt;'&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="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="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;tomato&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;modes&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="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;modes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dark&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;#ff755e&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;We can import the thing we are shadowing and use whatever JavaScript method we want to merge, and override whatever we want. It's that easy. At least updating styles is that easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does Shadowing work this way?
&lt;/h2&gt;

&lt;p&gt;When you are using a theme Gatsby first tries to resolve within your own projects &lt;code&gt;src&lt;/code&gt; folder, looking in &lt;code&gt;src/{theme-name}/{any-sub-dirs}/{file}&lt;/code&gt;, if it doesn't see anything there, it resolves to &lt;code&gt;node_modules/{theme-name}/src/{any-sub-dirs}/{file}&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;When building a theme you don't have to do anything special to allow shadowing. It just works. When you're consuming a theme you can follow these conventions to shadow whatever you need to.&lt;/p&gt;

&lt;h2&gt;
  
  
  BONUS
&lt;/h2&gt;

&lt;p&gt;Want an even easier way to do partial/deep updates of an object in JavaScript? There's a really cool library called &lt;a href="https://github.com/immerjs/immer"&gt;immer&lt;/a&gt; that is particularly good at this.&lt;/p&gt;

&lt;p&gt;Just install immer to the project, import it into our file and let the magic happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;produce&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;immer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;colors&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;gatsby-theme-blog/src/gatsby-plugin-theme-ui/colors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;produce&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;draft&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;draft&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tomato&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dark&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff755e&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;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Shadowing is a concept in Gatsby that allows us to override and compose styles, components, and data from a Gatsby theme. It follows a simple convention of path resolution to allow shadowing. Anything in a theme's &lt;code&gt;src/&lt;/code&gt; folder is open to shadowing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Up
&lt;/h3&gt;

&lt;p&gt;Next time we will dive into shadowing &lt;code&gt;gatsby-theme-blog&lt;/code&gt; and making it our own by shadowing styles and components.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Using Gatsby Theme Options Part 2</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Tue, 16 Jul 2019 13:20:03 +0000</pubDate>
      <link>https://forem.com/hagnerd/using-gatsby-theme-options-part-2-573n</link>
      <guid>https://forem.com/hagnerd/using-gatsby-theme-options-part-2-573n</guid>
      <description>&lt;h2&gt;
  
  
  Previously in the series
&lt;/h2&gt;

&lt;p&gt;This is the third post in a series about getting started with Gatsby themes where we learn about themes progressively. In the first blog post, we set up a Gatsby website from scratch, and added the gatsby-theme-blog, which takes some Markdown or Mdx content in a specified folder, transforms it into pages on our website, and gives us some nice base components and styles.&lt;/p&gt;

&lt;p&gt;In the second post, we discussed what options are in themes, how to customize the theme with the options available, and where to look inside of the theme to find what options are available as well as how those options are used.&lt;/p&gt;

&lt;p&gt;If you haven't read from the beginning of the series &lt;a href="https://dev.to/hagnerd/using-your-first-gatsby-theme-hep"&gt;Using Your First Gatsby Theme&lt;/a&gt;, you might want to before continuing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are we going to discuss today?
&lt;/h2&gt;

&lt;p&gt;In this post, we are going to customize our Gatsby website by changing some of the options available to us from &lt;code&gt;gatsby-theme-blog&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the next post we'll discuss what shadowing is as a concept in Gatsby, and how to find the things that can be shadowed in a theme.&lt;/p&gt;

&lt;p&gt;If you'd like to see the completed code for this section, check the branch &lt;a href="https://github.com/hagnerd/first-gatsby-theme-demo/tree/using-gatsby-theme-options-pt-2" rel="noopener noreferrer"&gt;Using Gatsby Theme Options Pt 2&lt;/a&gt; on Github.&lt;/p&gt;




&lt;h2&gt;
  
  
  Changing the base URL of our blog
&lt;/h2&gt;

&lt;p&gt;Right now our blog index, the page rendering a list of our blog posts, is rendering at our root path "/", but what if we want to add a blog to an existing website, or what if we want to make something else our home page?&lt;/p&gt;

&lt;p&gt;Luckily that's pretty easy to change.&lt;/p&gt;

&lt;p&gt;If you remember, the &lt;code&gt;gatsby-theme-blog&lt;/code&gt; has a few options that we can change. One of them is a property called &lt;code&gt;basePath&lt;/code&gt;. This &lt;code&gt;basePath&lt;/code&gt; determines the base URL for our blog content. The default is &lt;code&gt;/&lt;/code&gt;, but let's go ahead and change that to &lt;code&gt;/blog&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open up gatsby-config.js&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;// gatsby-config.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&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;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;gatsby-theme-blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this will do is make the blog index render at &lt;code&gt;'/blog'&lt;/code&gt; and make the blog posts render at &lt;code&gt;'/blog/:slug'&lt;/code&gt; where &lt;code&gt;:slug&lt;/code&gt; is replaced with the slugified version of your title. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's pretty common to call it slugifying when you set all characters to lowercase and change any characters that don't fall between a-z or 0-9 into "-".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last time we changed our &lt;code&gt;src/pages/index.js&lt;/code&gt; page to &lt;code&gt;/src/pages/_index.js&lt;/code&gt; so that Gatsby wouldn't try to render our index page in place of our blog index. Now that we have the blog rendering at a different path, let's change the filename back to &lt;code&gt;index.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mv &lt;/span&gt;src/pages/_index.js src/pages/index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll also want to add a navigation component so that we can get to our home and blog page.&lt;/p&gt;

&lt;p&gt;Let's first make a &lt;code&gt;components&lt;/code&gt; directory inside of the &lt;code&gt;src&lt;/code&gt; directory. And then we'll make two new components, &lt;code&gt;layout&lt;/code&gt;, and &lt;code&gt;navigation&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;src/components
&lt;span class="nb"&gt;touch &lt;/span&gt;src/components/&lt;span class="o"&gt;{&lt;/span&gt;layout,navigation&lt;span class="o"&gt;}&lt;/span&gt;.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In my experience with Gatsby I always need a generic page layout, or maybe a few different layouts for different types of pages. You will sometimes see these living in &lt;code&gt;src/templates&lt;/code&gt; or sometimes &lt;code&gt;src/components&lt;/code&gt;. Either is perfectly fine, but I try to stick with keeping layouts that affect markup and styles in &lt;code&gt;src/components&lt;/code&gt;, and use &lt;code&gt;src/templates&lt;/code&gt; only for tying the data requirements for programmatic pages to a visual component or set of visual components.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&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;../components/layout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HomePage&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="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Hello, from Gatsby&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&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;span&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img"&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hand emoji waving hello"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          👋
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Layout&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;span class="c1"&gt;/////////////////////////////////////////&lt;/span&gt;
&lt;span class="c1"&gt;// src/components/layout.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Navigation&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;./navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Navigation&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&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;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&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;/////////////////////////////////////////&lt;/span&gt;
&lt;span class="c1"&gt;// src/components/navigation.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&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;gatsby&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Navigation&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;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/blog"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Blog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&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;There are a few things to note when we start our Gatsby site up 1) it's really ugly, and 2) the navigation is on the home page but not the blog page :( bummer.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fet1ygkg90nlbz7na6gpf.gif" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fet1ygkg90nlbz7na6gpf.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix problem one just use your favorite styling method whether that's CSS-in-JS, CSS modules, Sass, etc. I won't be touching the general styles because that is beyond the scope of this series. If you're interested in learning about different ways to style your Gatsby website let me know in the comments and I'll write an article.&lt;/p&gt;

&lt;p&gt;To fix problem two we are going to have to learn how to shadow components. We'll discuss what shadowing is in the next post.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;If you found this post useful and want to see more from this series leave a reaction or comment. I'm trying to find the right length and depth per article so please let me know if you think this length is too short&lt;/p&gt;

&lt;p&gt;In the next post, we'll learn about what shadowing is, why it's so powerful, and how Gatsby resolves shadowed content.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Using Gatsby Theme Options</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Sun, 14 Jul 2019 01:09:17 +0000</pubDate>
      <link>https://forem.com/hagnerd/using-gatsby-theme-options-16bm</link>
      <guid>https://forem.com/hagnerd/using-gatsby-theme-options-16bm</guid>
      <description>&lt;p&gt;This is the second post in a series about getting started with Gatsby themes where we learn about themes progressively. In the first blog post we set up a Gatsby website from scratch, and added &lt;code&gt;gatsby-theme-blog&lt;/code&gt;, which takes some Markdown or Mdx content in a specified folder, transforms them into pages on our website, and gives some nice base components and styles.&lt;/p&gt;

&lt;p&gt;If you haven't read &lt;a href="https://dev.to/hagnerd/using-your-first-gatsby-theme-hep"&gt;Using Your First Gatsby Theme&lt;/a&gt;, you might want to do that before continuing on.&lt;/p&gt;

&lt;p&gt;In this post we are going to dive deeper into the options that &lt;code&gt;gatsby-theme-blog&lt;/code&gt; gives us to customize our experience.&lt;/p&gt;

&lt;p&gt;In future posts we will discuss what shadowing is, and how to shadow components, styles, and data.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are the options?
&lt;/h2&gt;

&lt;p&gt;If we take a look at the &lt;a href="https://www.npmjs.com/package/gatsby-theme-blog"&gt;documentation&lt;/a&gt; for the &lt;code&gt;gatsby-theme-blog&lt;/code&gt; package, there are four options available to us.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;basePath&lt;/code&gt; which defaults to "/". It is the url for the blog index page, and root url for all blog posts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contentPath&lt;/code&gt; defaults to &lt;code&gt;/content/posts&lt;/code&gt;. It is the location of the .md/.mdx files you want to be transformed into blog posts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assetPath&lt;/code&gt; defaults to &lt;code&gt;/content/assets&lt;/code&gt;. It is the location of your avatar (picture) for the bio component.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mdx&lt;/code&gt; which defaults to true. This determines whether &lt;code&gt;gatsby-theme-blog&lt;/code&gt; should configure &lt;code&gt;mdx&lt;/code&gt; for you, or if you will handle it yourself. If you have &lt;code&gt;gatsby-mdx&lt;/code&gt; installed and configured for other pages, you can set this to false.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How do we override them?
&lt;/h2&gt;

&lt;p&gt;We can override these defaults in the &lt;code&gt;gatsby-config.js&lt;/code&gt; of our Gatsby website. When you don't need to change any of the options in a theme your config might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// gatsby-config.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&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;gatsby-theme-blog&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;p&gt;If we wanted to change one or more of the options we would use the longhand syntax for a plugin/theme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// gatsby-config.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&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;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;gatsby-theme-blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/blog&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;You might need to consult the documentation for the themes that you are using to see if there are any options that you &lt;em&gt;must&lt;/em&gt; set, or if all are optional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where are the options used?
&lt;/h2&gt;

&lt;p&gt;If we go to the folder of our Gatbsy website and open up &lt;code&gt;node_modules/gatsby-theme-blog/gatsby-config.js&lt;/code&gt; in our favorite editor, we will see something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// node_modules/gatsby-theme-blog/gatsby-config.js&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="nx"&gt;options&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Blog Title Placeholder`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Name Placeholder`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Description placeholder`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;social&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`twitter`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://twitter.com/gatsbyjs`&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`github`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://github.com/gatsbyjs`&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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;mdx&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-plugin-mdx`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`.mdx`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`.md`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;gatsbyRemarkPlugins&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;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-remark-images`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// should this be configurable by the end-user?&lt;/span&gt;
                &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1380&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;linkImagesToOriginal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-remark-copy-linked-files`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-remark-numbered-footnotes`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-remark-smartypants`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="na"&gt;remarkPlugins&lt;/span&gt;&lt;span class="p"&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="s2"&gt;`remark-slug`&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="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-source-filesystem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentPath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`content/posts`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentPath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`content/posts`&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="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-source-filesystem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assetPath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`content/assets`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assetPath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`content/assets`&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;// ...more config&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;The most important thing to note is that the &lt;code&gt;gatsby-config.js&lt;/code&gt; file is a&lt;br&gt;
function that takes an object, here it's called options, as an argument and returns a config object. If we look carefully we will see three of the four options for &lt;code&gt;gatsby-theme-blog&lt;/code&gt; being used at different spots in the config.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mdx&lt;/code&gt; which is used to determine whether or not to configure &lt;code&gt;gatsby-mdx&lt;/code&gt; for us, along with some helpful plugins for Markdown/Mdx. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;contentPath&lt;/code&gt; which is used inside of a &lt;code&gt;gatsby-source-filesystem&lt;/code&gt; config&lt;br&gt;
determining where on our filesystem to look for the posts, and what to call them when we are querying for them with GraphQL.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;assetPath&lt;/code&gt; which is also used inside of a &lt;code&gt;gatsby-source-filesystem&lt;/code&gt; config, but this time determining where on our filesystem to look for our assets, and what to call them when we are querying for them with GraphQL.&lt;/p&gt;

&lt;p&gt;So we've located three of the four options. Where is the fourth one being used?&lt;/p&gt;

&lt;p&gt;For this one we are going to look inside &lt;code&gt;node_modules/gatsby-theme-blog/gatsby-node.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// node_modules/gatsby-theme-blog/gatsby-node.js&lt;/span&gt;
&lt;span class="c1"&gt;// Ensure that content directories exist at site-level&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onPreBootstrap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;themeOptions&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;program&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;basePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;themeOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`/`&lt;/span&gt;
  &lt;span class="nx"&gt;contentPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;themeOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentPath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`content/posts`&lt;/span&gt;
  &lt;span class="nx"&gt;assetPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;themeOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assetPath&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`content/assets`&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dirs&lt;/span&gt; &lt;span class="o"&gt;=&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;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentPath&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;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;assetPath&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&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;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Initializing &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; directory`&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;existsSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;mkdirp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dir&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;You don't need to understand what's happening in this whole file, in fact that's the beauty of Gatsby, Gatsby plugins, and now Gatsby Themes, but if we look at the &lt;code&gt;onPreBootstrap&lt;/code&gt; function we can see that the second argument is an object with the same options available to it as in the &lt;code&gt;gatsby-config.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;When a Gatsby website with this theme is started up, Gatsby will check for these paths (&lt;code&gt;contentPath&lt;/code&gt;, and &lt;code&gt;assetPath&lt;/code&gt;) existence. If they don't exist, Gatsby will use the &lt;code&gt;mkdirp&lt;/code&gt; package to make sure that they are created.&lt;/p&gt;

&lt;p&gt;The next place we need to look is the &lt;code&gt;createPages&lt;/code&gt; function in the same file. This time, we are taking advantage of the global &lt;code&gt;basePath&lt;/code&gt; variable that we set in the &lt;code&gt;onPreBootstrap&lt;/code&gt; function. The relevant part is here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// node_modules/gatsby-theme-blog/gatsby-node.js&lt;/span&gt;
&lt;span class="c1"&gt;// inside of the exports.createPages function&lt;/span&gt;
  &lt;span class="nx"&gt;createPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PostsTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;siteTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;socialLinks&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;The important thing to understand is that whatever our &lt;code&gt;basePath&lt;/code&gt; is, that will be the path that our &lt;code&gt;PostsTemplate&lt;/code&gt; gets rendered to with the data that is passed in via the context object.&lt;/p&gt;




&lt;p&gt;That's a lot of stuff to take in but let's quickly recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The theme documentation &lt;em&gt;should&lt;/em&gt; list what options are available, and what the defaults are&lt;/li&gt;
&lt;li&gt;You can use the longhand plugin syntax that is standard in Gatsby to override the theme defaults if/when needed&lt;/li&gt;
&lt;li&gt;You can also check the &lt;code&gt;gatsby-config.js&lt;/code&gt; of the theme, and the &lt;code&gt;gatsby-node.js&lt;/code&gt; for more context on how/where those options are being used if the documentation leaves more to be desired.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope this post was helpful. Next time we'll be diving into shadowing by going over what the concept of shadowing is in Gatsby.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Using Your First Gatsby Theme</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Sun, 07 Jul 2019 01:23:44 +0000</pubDate>
      <link>https://forem.com/hagnerd/using-your-first-gatsby-theme-hep</link>
      <guid>https://forem.com/hagnerd/using-your-first-gatsby-theme-hep</guid>
      <description>&lt;p&gt;Gatsby just announced the stable release of themes, and along with it released a bevy of themes-related content. This post will go over what a theme is, why they might be useful to you, and how to use your first theme. In later posts I'll dive into topics like component shadowing, and maybe even authoring your own theme.&lt;/p&gt;

&lt;p&gt;If you'd like to dive right into the deep end Jason Lengstorf released a free &lt;a href="https://egghead.io/courses/gatsby-theme-authoring"&gt;egghead course on Gatsby themes&lt;/a&gt; that is superb.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are themes?
&lt;/h2&gt;

&lt;p&gt;The name theme might invoke the assumption that they only relate to visual content, however Gatsby themes are way more than that. They can include some default configuration, setting up transformers, plugins, and even other child themes. Themes can &lt;em&gt;also&lt;/em&gt; include visual styles and components.&lt;/p&gt;

&lt;p&gt;Themes are configurable, overridable, and best of all, composable. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why are themes useful?
&lt;/h2&gt;

&lt;p&gt;If you've used Gatsby in the past, you might have used a starter to bootstrap your website. Starters were a great stepping stone before themes. They allowed you to kick off a Gatsby site that was configured with some additional functionality out of the box, like say supporting Mdx, or maybe using an external service like Shopify.&lt;/p&gt;

&lt;p&gt;However, if you ran into the case of wanting to quickly start a website that supported both Mdx AND Shopify you had to find a starter with both configured, use one of the starters and figure out how to get the other functionality set up, or configure everything from scratch.&lt;/p&gt;

&lt;p&gt;Themes change this. Instead of starting with a &lt;code&gt;this&lt;/code&gt; or &lt;code&gt;that&lt;/code&gt;, we can easily make a &lt;code&gt;this&lt;/code&gt; AND &lt;code&gt;that&lt;/code&gt;. Remember, themes are configurable, overridable, and composable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get started
&lt;/h2&gt;

&lt;p&gt;We're going to start off simple. Let's set up a Gatsby website from scratch, and then use &lt;code&gt;gatsby-theme-blog&lt;/code&gt; to quickly bootstrap the basic functionality of a blog. &lt;/p&gt;

&lt;p&gt;If you want to see the full code check out the &lt;a href="https://github.com/hagnerd/first-gatsby-theme-demo"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the directory
&lt;/h2&gt;

&lt;p&gt;First we need to make a directory for our Gatsby website, and then we need to initialize it.&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;mkdir &lt;/span&gt;first-gatsby-theme
&lt;span class="nb"&gt;cd &lt;/span&gt;first-gatsby-theme
yarn init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I'm using &lt;code&gt;yarn&lt;/code&gt;, but feel free to use &lt;code&gt;npm&lt;/code&gt; if you'd like. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Installing Our Dependencies
&lt;/h2&gt;

&lt;p&gt;We could use a starter by using the &lt;code&gt;gatsby new &amp;lt;STARTER&amp;gt;&lt;/code&gt; command, but let's set one up manually. It's surprisingly easy to do.&lt;/p&gt;

&lt;p&gt;We only need &lt;code&gt;react&lt;/code&gt;, &lt;code&gt;react-dom&lt;/code&gt;, and &lt;code&gt;gatsby&lt;/code&gt; to get started. So let's install those. After that, let's open up the &lt;code&gt;package.json&lt;/code&gt; file in the root directory and add some scripts for convenience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add react react-dom gatsby
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"first-gatsby-theme"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"react"&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;"react-dom"&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;"gatsby"&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="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gatsby build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gatsby develop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"clean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gatsby clean"&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;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;blockquote&gt;
&lt;p&gt;The &lt;code&gt;...&lt;/code&gt; are just placeholders. Your &lt;code&gt;package.json&lt;/code&gt; file will have the specific versions you have installed. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Check that Gatsby is working
&lt;/h2&gt;

&lt;p&gt;To see all of our hard work paid off, let's make some content and let Gatsby work its magic. &lt;/p&gt;

&lt;p&gt;We need to make a directory at &lt;code&gt;src/pages&lt;/code&gt;. By convention this is where Gatsby will look for content to transform into pages on the website, and handles the routing for us.&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; src/pages
&lt;span class="nb"&gt;touch &lt;/span&gt;src/pages/index.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;mkdir -p creates all missing directories in the path provided&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;src/pages/index.js&lt;/code&gt; will be mapped to the root path "/" of our website.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/index.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;HomePage&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;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello, from Gatsby &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"img"&lt;/span&gt; &lt;span class="na"&gt;aria&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hand emoji waving hello"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;👋&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&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;Now to start up the Gatsby website all you need to do is run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should see something that looks like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YsY0WOr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jn2c89iq0772vi4g01a9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YsY0WOr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jn2c89iq0772vi4g01a9.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Very exciting, I know.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing the theme
&lt;/h2&gt;

&lt;p&gt;Now that we know we have Gatsby working, let's install a theme. Everyone says that they want to have a blog, but getting started is hard. The good news is that themes makes it so easy to get started that you won't have any excuses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add gatsby-theme-blog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the root of your project make a &lt;code&gt;gatsby-config.js&lt;/code&gt; file.&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;touch &lt;/span&gt;gatsby-config.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And add the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="na"&gt;plugins&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;gatsby-theme-blog&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;p&gt;Before the stable release of themes, your themes used to live under an additional property called &lt;code&gt;__experimentalThemes&lt;/code&gt;, but now that they're stable, they're just like plugins!&lt;/p&gt;

&lt;p&gt;If you tried to start your Gatsby website up at the moment you'd get some errors :(. Let's figure out why in the next two sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring the theme options
&lt;/h2&gt;

&lt;p&gt;Right now there isn't a Github repo for gatsby-theme-blog, but if you look at the &lt;a href="https://www.npmjs.com/package/gatsby-theme-blog"&gt;npm page&lt;/a&gt; you can see a section called &lt;code&gt;Usage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BgX5OGJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4j4zppm41wkuecivw89s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BgX5OGJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4j4zppm41wkuecivw89s.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most Gatsby plugins and themes will have options that you can set. For &lt;code&gt;gatsby-theme-blog&lt;/code&gt; there are four options and defaults for each of them, meaning we can not pass any options in and the theme will still work. &lt;/p&gt;

&lt;p&gt;That being said, it has some expectations. Right now &lt;code&gt;gatsby-theme-blog&lt;/code&gt; expects some blog posts in the form of either Markdown or MDX in the &lt;code&gt;content/posts&lt;/code&gt; directory, and an image with the title of &lt;code&gt;avatar&lt;/code&gt; in the &lt;code&gt;content/assets&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;The errors you get from not having either of these are kind of cryptic which is a bit of a bummer. &lt;/p&gt;

&lt;p&gt;For now we are going to leave the options set to the defaults. If you wanted to override any you would change your &lt;code&gt;gatsby-config.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// gatsby-config.js&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&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;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;gatsby-theme-blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;contentPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content/posts&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 file path to your blog posts&lt;/span&gt;
        &lt;span class="na"&gt;basePath&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="c1"&gt;// the url for the root of your blog&lt;/span&gt;
        &lt;span class="na"&gt;assetPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content/assets&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 file path to your assets folder&lt;/span&gt;
        &lt;span class="na"&gt;mdx&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;// whether or not to configure mdx for you&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;These are the default values, but to change any of them, set the value you would like in the options object. &lt;/p&gt;

&lt;h2&gt;
  
  
  Add Content
&lt;/h2&gt;

&lt;p&gt;So now that we know why our Gatsby website is failing after adding this theme, let's use the default options as a guide for what we need to do to get our website working again.&lt;/p&gt;

&lt;p&gt;First we need to make the necessary folders. In the root of the project we're going to create &lt;code&gt;content&lt;/code&gt;, &lt;code&gt;content/posts&lt;/code&gt;, and &lt;code&gt;content/assets&lt;/code&gt; directories.&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; content/&lt;span class="o"&gt;{&lt;/span&gt;posts,assets&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;the {} here is called brace expansion and is equivalent to running &lt;code&gt;mkdir -p content/posts&lt;/code&gt; and &lt;code&gt;mkdir -p content/assets&lt;/code&gt;, just in a shorter way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have our folders in place we need to make a blog post, and add an avatar.&lt;/p&gt;

&lt;p&gt;Make a file called &lt;code&gt;hello-world.md&lt;/code&gt;, inside of your &lt;code&gt;content/posts&lt;/code&gt; directory and add whatever content you'd like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

The worlds greatest blog post!

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, save a picture of yourself named &lt;code&gt;avatar&lt;/code&gt; in &lt;code&gt;content/assets&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The third thing we need to do is temporarily remove our &lt;code&gt;src/pages/index.js&lt;/code&gt; page, because &lt;code&gt;gatsby-theme-blog&lt;/code&gt; defaults to making the root of the blog the "/" root path.&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;mv &lt;/span&gt;src/pages/index.js src/pages/_index.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you run &lt;code&gt;yarn start&lt;/code&gt; now, everything should work and you'll see something like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t_AACB-8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9i03lm2b5qktigct8t94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t_AACB-8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9i03lm2b5qktigct8t94.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Site/Author Info
&lt;/h2&gt;

&lt;p&gt;The other thing that &lt;code&gt;gatsby-theme-blog&lt;/code&gt; does is look in our &lt;code&gt;gatsby-config.js&lt;/code&gt; for some site metadata. &lt;/p&gt;

&lt;p&gt;Pop open your &lt;code&gt;gatsby-config.js&lt;/code&gt; one last time and add your information in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="na"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome Blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Enter the title of your blog here&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Matt Hagner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Change this to your name&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A really cool blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;social&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;twitter.com/_hagnerd&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;github&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;github.com/hagnerd&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;span class="na"&gt;plugins&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;gatsby-theme-blog&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;Hopefully that wasn't too painful and helped highlight just how quick it is to install and set up a Gatsby theme. The best part is that you can install more themes, as needed and it won't require you to fundamentally change how your website is structured.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Up
&lt;/h2&gt;

&lt;p&gt;The quick set up for our blog was great, but what if we want to change the styles? Or how some of the default components are rendered? To do that we'll use a feature called shadowing. &lt;/p&gt;

&lt;p&gt;I'll update with a link to the post when it's finished. &lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Where Did All My Methods Go? Modules in ReasonML</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Sun, 30 Jun 2019 18:22:50 +0000</pubDate>
      <link>https://forem.com/hagnerd/where-did-all-my-methods-go-modules-in-reasonml-28g4</link>
      <guid>https://forem.com/hagnerd/where-did-all-my-methods-go-modules-in-reasonml-28g4</guid>
      <description>&lt;p&gt;Coming from JavaScript to ReasonML there are a lot of barriers. While the syntax may look friendly at first, and the type inference is amazing requiring very little effort from you to massage it, there are a lot of symbols, and a huge mental shift needs to take place.&lt;/p&gt;

&lt;p&gt;To help others coming from non-functional languages, and JavaScript&lt;br&gt;
specifically, I want to start sharing some of the things that tripped me up when I was learning ReasonML.&lt;/p&gt;

&lt;p&gt;The community is one of the best around and someone will always help you no matter how silly you think your question is, but there isn't a ton of content surrounding ReasonML online. Join the &lt;a href="https://discord.gg/reasonml"&gt;discord&lt;/a&gt;, and don't be afraid to post on the &lt;a href="https://reasonml.chat"&gt;forum&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;Functional programming languages tend to structure their code differently than non-functional languages. Whether or not you consider JavaScript to be an object oriented language, it still has some form of inheritance using the prototype chain, and you call methods directly on the instance of the data structure.&lt;/p&gt;
&lt;h2&gt;
  
  
  The JavaScript Way
&lt;/h2&gt;

&lt;p&gt;An example. In JavaScript you can create an array literal like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;myFriends&lt;/span&gt; &lt;span class="o"&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;Me&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;Myself&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;I&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 you can use the Array methods by using the dot notation on the instance of the data structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;myFriends&lt;/span&gt; &lt;span class="o"&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;Me&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;Myself&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;I&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;shoutingFriends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myFriends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;friend&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;friend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Under the Hood
&lt;/h3&gt;

&lt;p&gt;In JavaScript when you declare a new array literal you are creating a new instance of the Array pseudo-class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;myFriends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Me&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;Myself&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;I&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;A naive implementation of an Array in JavaScript using pseudo-classes might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// pretend I didn't use an actual Array in my definition&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt; &lt;span class="o"&gt;=&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;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&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;cb&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;__internal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&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;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;__internal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;array&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="nx"&gt;__internal&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;myFriends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Me&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;Myself&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;I&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;shoutingFriends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myFriends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;friend&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;friend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You might be used to seeing classes instead of pseudo-classes, but under the hood JavaScript classes are just syntatic sugar that results in the same thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Important to note that our methods have an &lt;em&gt;implicit&lt;/em&gt; dependency on &lt;code&gt;this&lt;/code&gt; (the instance itself). We aren't passing an array into the method. The &lt;em&gt;implicit&lt;/em&gt; dependency on &lt;code&gt;this&lt;/code&gt; is what allows the dot notation &lt;code&gt;myFriends.map...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our instance of &lt;code&gt;MyArray&lt;/code&gt; doesn't actually copy over &lt;code&gt;forEach&lt;/code&gt;, or &lt;code&gt;map&lt;/code&gt; because that would be extremely inefficient. If our program has tens-of-thousands of arrays it would be unnecessary to copy EVERY method to each instance of the data structure. Instead JavaScript has this thing called the prototype.&lt;/p&gt;

&lt;p&gt;So when we use &lt;code&gt;myFriends.map...&lt;/code&gt; the engine goes "Hmmm.... 🤔 myFriends doesn't seem to have a function called &lt;code&gt;map&lt;/code&gt; on its prototype. Perhaps its proto does." and then it checks &lt;code&gt;MyArray&lt;/code&gt;, because when we create an instance of a (pseudo-)class JavaScript adds some information to our instance so later it knows who to inherit functions from.&lt;/p&gt;

&lt;p&gt;Then it sees that "Ahhh. Yes! &lt;code&gt;MyArray&lt;/code&gt; does a have function on its prototype called &lt;code&gt;map&lt;/code&gt;", and then it uses that &lt;code&gt;map&lt;/code&gt; function for our operation.&lt;/p&gt;

&lt;p&gt;All of this rambling is to show you how data structures and methods are&lt;br&gt;
tightly coupled in JavaScript. To map an array we use the instance of the array, and chain a function onto it like so &lt;code&gt;[1,2,3].map(n =&amp;gt; n + 1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you learn this as the norm, you think, "Well yeah, duh. How else would you do it?". &lt;/p&gt;


&lt;h2&gt;
  
  
  The ReasonML Way
&lt;/h2&gt;

&lt;p&gt;In functional programming languages data structures store data. That's it. How do you do operate on data structures then? In ReasonML we place collections of functions that operate on a type into Modules. A module might know how to operate on one type only, like an Array for example. &lt;/p&gt;

&lt;p&gt;The functions have an &lt;em&gt;explicit&lt;/em&gt; dependency of an Array.&lt;/p&gt;

&lt;p&gt;In ReasonML the &lt;code&gt;Array&lt;/code&gt; module contains &lt;em&gt;most&lt;/em&gt; functions that know how to operate on the array data structure. What are the benefits of modules? They're self-contained. They don't have to be copied or have pointers created to their 'owners'. They also avoid notions of 'this/self' or the instance of the data structure at all.&lt;/p&gt;

&lt;p&gt;They are pure functions that take explicit arguments and return consistent results. &lt;/p&gt;
&lt;h3&gt;
  
  
  An Example
&lt;/h3&gt;

&lt;p&gt;In ReasonML &lt;code&gt;Array.map&lt;/code&gt; is a function that takes two arguments: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A function that takes whatever the type of data that is contained inside of the array (in the following example it takes a string) and does something to transform each element returning either the same, or a different type (in following example it returns a string).&lt;/li&gt;
&lt;li&gt;The actual Array we want to operate on.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;myFriends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;"Me"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Myself"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"I"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;shoutingFriends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;friend&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;friend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;myFriends&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This &lt;em&gt;explicit&lt;/em&gt; need for the Array to be passed in might still seem like an odd choice, especially if you're used to taking advantage of method chaining in JavaScript or other object oriented languages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;myArray&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myArray&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&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;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&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;// =&amp;gt; 36&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, you can achieve the same thing in ReasonML in a few different ways.&lt;/p&gt;

&lt;p&gt;(I am using a List here instead of an Array for reasons we'll explore in another post, but for our purposes squint and pretend it's an array).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;myArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myArray&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;mod&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fold_left&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Alternatively if you are using Bucklescript you can use Belt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;myArray&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myArray&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;mod&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Belt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or the Js.Array module...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;myArray&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myArray&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;mod&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;/*&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt; &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I don't want to dive into what the &lt;code&gt;|&amp;gt;&lt;/code&gt; and &lt;code&gt;-&amp;gt;&lt;/code&gt; operators are in this post. Just know that the &lt;code&gt;|&amp;gt;&lt;/code&gt; and &lt;code&gt;-&amp;gt;&lt;/code&gt; operators, in addition to currying, can help you achieve this same idea of method chaining. You're taking the result from one function and piping it into the next function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in ReasonML methods move from being available on the instance of a data structure, to being contained within a dedicated module. This allows them to be pure functions that require you to explicitly pass in the data structure you want to operate on.&lt;/p&gt;




&lt;h3&gt;
  
  
  Some Additional Info
&lt;/h3&gt;

&lt;p&gt;If you're comfortable reading type signatures, the following links contain the type definitions for the Array and List modules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reasonml.github.io/api/Array.html"&gt;Array module&lt;/a&gt;&lt;br&gt;
&lt;a href="https://bucklescript.github.io/bucklescript/api/Belt.Array.html"&gt;Belt Array module&lt;/a&gt;&lt;br&gt;
&lt;a href="https://reasonml.github.io/api/List.html"&gt;List module&lt;/a&gt;&lt;br&gt;
&lt;a href="https://bucklescript.github.io/bucklescript/api/Belt.List.html"&gt;Belt List module&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What's next?
&lt;/h3&gt;

&lt;p&gt;ReasonML is still evolving so there are often many ways to skin a cat, and there are often good reasons when to choose one over the other.&lt;/p&gt;

&lt;p&gt;In future posts I'm going to explore some of the different modules included in the standard library in ReasonML, as well as Belt and how they relate to JavaScript.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>reason</category>
    </item>
    <item>
      <title>I Wrote This Article In The Terminal</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Thu, 13 Jun 2019 22:03:10 +0000</pubDate>
      <link>https://forem.com/hagnerd/i-wrote-this-article-in-the-terminal-gp5</link>
      <guid>https://forem.com/hagnerd/i-wrote-this-article-in-the-terminal-gp5</guid>
      <description>&lt;p&gt;This article was written with my new tool &lt;a href="https://github.com/hagnerd/devto#readme"&gt;devto&lt;/a&gt;, a CLI for creating new articles, and posting them to Dev.to. It's dead simple, and probably a little rough around the edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prior Art
&lt;/h2&gt;

&lt;p&gt;This tool was heavily inspired by &lt;a href="https://dev.to/timdeschryver"&gt;Tim Deschryver&lt;/a&gt; who wrote this &lt;a href="https://dev.to/timdeschryver/writing-a-dev-to-blog-post-with-vscode-1fn"&gt;article&lt;/a&gt; about a VS Code extension called &lt;a href="https://marketplace.visualstudio.com/items?itemName=timdeschryver.new-blog-post"&gt;New Blog Post&lt;/a&gt;. If you use VS Code, check it out!&lt;/p&gt;




&lt;p&gt;If you're interested in using the CLI app you can install it globally at &lt;code&gt;@hagnerd/devto&lt;/code&gt;, or run it with &lt;code&gt;npx @hagnerd/devto&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once installed it will be globally available with &lt;code&gt;devto new&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following commands are available:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;devto new&lt;/code&gt; - creates a new article with frontmatter.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;devto publish&lt;/code&gt; - pushes the article up to your dev.to account*&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;devto dashboard&lt;/code&gt; - just a quick alias to open dev.to/dashboard in the browser.
Great if you want to push a draft up, and make changes or preview it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;devto reset&lt;/code&gt; - deletes your global ~/.devto file (which stores your API key)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;* I haven't tested it with orgs so if someone that is part of an org tries it&lt;br&gt;
out and the cli doesn't behave correctly, let me know!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@hagnerd/devto"&gt;npm&lt;/a&gt; link&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/hagnerd/devto#readme"&gt;Github&lt;/a&gt; link&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>cli</category>
    </item>
    <item>
      <title>Getting up and running with Reason, React, and Parcel</title>
      <dc:creator>Matt Hagner</dc:creator>
      <pubDate>Tue, 19 Feb 2019 04:08:21 +0000</pubDate>
      <link>https://forem.com/hagnerd/getting-up-and-running-with-reason-react-and-parcel-567j</link>
      <guid>https://forem.com/hagnerd/getting-up-and-running-with-reason-react-and-parcel-567j</guid>
      <description>&lt;h4&gt;
  
  
  UPDATED: 4/23/2019
&lt;/h4&gt;

&lt;p&gt;Recently the Reason React project released new bindings. It uses a new version of "react-jsx", and utilizes the React Hooks API instead of the old record based API.&lt;/p&gt;

&lt;p&gt;This means that if you have experience with hooks, you'll feel pretty much right at home with Reason React, with some small differences. &lt;/p&gt;




&lt;p&gt;With the rise of TypeScript on the front end, I think there will be an increased willingness to learn and utilize typed, compile-to-javascript languages. One strong contender for me is Reason.&lt;/p&gt;

&lt;p&gt;You may have heard about Reason and thought about learning it, but it's hard to give up the JavaScript tools you already know and love. The good news is that Bucklescript and tools like Parcel make Reason a breeze to work with.&lt;/p&gt;

&lt;p&gt;The following will show you how to set up a Reason React project with Parcel, but teaching you Reason, or how Reason React works compared to React in JavaScript are outside of the scope of this article. If you'd like to learn more about those things, let me know in the comments and I'll gladly write more.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Background
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Reason?
&lt;/h3&gt;

&lt;p&gt;Reason is a special syntax that will look extremely familiar to JavaScript programmers, that uses OCaml under the hood.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does Reason use OCaml under the hood?
&lt;/h3&gt;

&lt;p&gt;Facebook has been using OCaml for a long time to write some of their internal tools (Flow is written in OCaml). OCaml is a fast, mature language that has great type inference, strong type safety, and can compile to many different targets including JavaScript, and Native.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Bucklescript?
&lt;/h3&gt;

&lt;p&gt;Bucklescript is a compiler that takes OCaml (or Reason), and turns it into highly optimized, and surprisingly readable JavaScript. &lt;/p&gt;

&lt;h3&gt;
  
  
  What will we be using today?
&lt;/h3&gt;

&lt;p&gt;The set up we are using will use Reason as the language of our code, reason-react as the front-end framework, Bucklescript for compiling our Reason code to JavaScript, and Parcel for bundling everything up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expectations
&lt;/h3&gt;

&lt;p&gt;To get the most out this, you'll want to be comfortable with React.&lt;/p&gt;




&lt;h2&gt;
  
  
  Initialization
&lt;/h2&gt;

&lt;p&gt;The first we are going to do is make a new folder for our project, and change into the directory.&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;mkdir &lt;/span&gt;reason-parcel
&lt;span class="nb"&gt;cd &lt;/span&gt;reason-parcel

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we are going to initialize using either npm, or yarn, and install all of our dependencies.&lt;/p&gt;

&lt;p&gt;To use the new Reason React bindings you'll want to make sure that you are using bs-platform ^5.0.0, and reason-react ^7.0.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn init &lt;span class="nt"&gt;-y&lt;/span&gt; 
yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; parcel-bundler bs-platform bsb-js
yarn add react react-dom reason-react
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h2&gt;
  
  
  Scripts
&lt;/h2&gt;

&lt;p&gt;Now open up your package.json file, and we are going to add a start script. Add the following to the bottom of your package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"parcel src/index.html"&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;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;h2&gt;
  
  
  Set up index.html
&lt;/h2&gt;

&lt;p&gt;Let's make a directory called &lt;code&gt;src&lt;/code&gt;. We need to make an &lt;code&gt;index.html&lt;/code&gt; file inside of &lt;code&gt;src&lt;/code&gt; to match the start script we added to the package.json. While we're at it, we might as well make the file where our Reason code will live.&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;mkdir &lt;/span&gt;src
&lt;span class="nb"&gt;touch &lt;/span&gt;src/index.html
&lt;span class="nb"&gt;touch &lt;/span&gt;src/Main.re
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can use whatever HTML boilerplate you'd like. I highly recommend emmet, and if you use VSCode it's already available. Or you can copy the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Inside the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag of index.html add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./Main.re"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are two important things to note:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The id of the div is "app". This will be used later inside of our Main.re file to render our app.&lt;/li&gt;
&lt;li&gt;The src property on our script element coincides to the name of the file we just created. Parcel is smart enough to see this src, and know that it needs to process the Reason file, and replace the src property with the outputted JavaScript file path.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Set up bsconfig.json
&lt;/h2&gt;

&lt;p&gt;In the root of your project make a file called &lt;code&gt;bsconfig.json&lt;/code&gt;.&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;touch &lt;/span&gt;bsconfig.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Bucklescript will read from this file for configuration. If you want to read more about all of the available options for the config file, Bucklescript has &lt;a href="https://bucklescript.github.io/docs/en/build-configuration.html"&gt;great documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Copy the following config into bsconfig.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reason-parcel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"react-jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sources"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"dir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"subdirs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;span class="nl"&gt;"package-specs"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"in-source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;span class="nl"&gt;"suffix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".bs.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bs-dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"reason-react"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"refmt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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;Let's go through some of the interesting properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reason

&lt;ul&gt;
&lt;li&gt;reason-react: Is set to 3 to allow the new JSX features.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;sources

&lt;ul&gt;
&lt;li&gt;dir: Is set to the &lt;code&gt;src&lt;/code&gt; folder we made earlier.&lt;/li&gt;
&lt;li&gt;subdirs: Is true because this tells Bucklescript to recursively check within our &lt;code&gt;src&lt;/code&gt; folder for Reason files.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;package-specs&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;module: commonjs is the default 👍 which is good enough for us. &lt;/li&gt;
&lt;li&gt;in-source: Will make our outputted JavaScript files appear next to their Reason counterparts.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;bs-dependencies: This is an array of the Reason specific libraries you depend on. Right now we are only using &lt;code&gt;reason-react&lt;/code&gt;, but you could use component libraries, styling libraries, etc.&lt;/li&gt;
&lt;li&gt;refmt: should be set to 3 for the ReasonV3 syntax. &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Let's Finally Write Some Reason
&lt;/h2&gt;

&lt;p&gt;Now with all of that out of the way, let's write some Reason code, and view it in the browser!&lt;/p&gt;

&lt;p&gt;Open up src/Main.re and copy the following exactly. Semi-colons, double-quotes, and all. We'll run through exactly what is happening shortly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;HelloWorld&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="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nn"&gt;ReactDOMRe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;renderToElementWithId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HelloWorld&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now save the file, and run &lt;code&gt;yarn start&lt;/code&gt; or &lt;code&gt;npm run start&lt;/code&gt;, and open up &lt;a href="https://dev.tolocalhost:1234/"&gt;localhost:1234/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright so there's a few things that are probably familiar, and a few things that are probably weird.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Familiar
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Rendering to element with a specific id:
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;ReactDOMRe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;renderToElementWithId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HelloWorld&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That should look pretty familiar to you if you've written React before. It's essentially doing the same as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HelloWorld&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&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;h4&gt;
  
  
  JSX
&lt;/h4&gt;

&lt;p&gt;For the most part, JSX in Reason is the exact same. There are some small caveats to HTML attributes that name-clash with Reason reserved words like the &lt;code&gt;type&lt;/code&gt; property on input elements becomes &lt;code&gt;type_&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Weird
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What is with the &lt;code&gt;module&lt;/code&gt; declaration?
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;HelloWorld&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The full explanation goes a little deeper than the scope of this article, but in Reason a file is automatically a module. &lt;/p&gt;

&lt;p&gt;To create components in Reason React you need to either declare each new component in a new module, or in a new file. By wrapping our component in &lt;code&gt;module HelloWorld ={};&lt;/code&gt; it allows us to use the JSX element &lt;code&gt;&amp;lt;HelloWorld /&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is this [@react.component]?
&lt;/h4&gt;

&lt;p&gt;This is the recommended way to make a new Reason React component. It does some stuff for us behind the scenes which makes our lives easier, but if you want to learn how to manually create your own components without it, check out the new page on components in the &lt;a href="https://reasonml.github.io/reason-react/docs/en/components"&gt;Reason React documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is the &lt;code&gt;make&lt;/code&gt; function?
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello from Reason"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Similar to how in React class components React looks for a render method, in a Reason React module, Reason React expects a make function. This make function will take all of the &lt;code&gt;props&lt;/code&gt; as an argument, and simply return some JSX.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is that really what I have to do to make strings?
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, from Reason"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yes. Yes it is. At least that it is how you have to make strings that are valid Reason React elements. Stay tuned for the next section for some tips to make strings in Reason React less painful. &lt;/p&gt;




&lt;h2&gt;
  
  
  Let's Refactor a Little
&lt;/h2&gt;

&lt;p&gt;First let's pull out our component and put it in its own file.&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;touch &lt;/span&gt;src/HelloWorld.re

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we can copy and paste the HelloWorld module, but this time because it's in its own file so we don't need to wrap it in a &lt;code&gt;module&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Inside of HelloWorld.re&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, from Reason"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I also made it easier to call &lt;code&gt;React.string&lt;/code&gt; by assigning it to a short variable, &lt;code&gt;s&lt;/code&gt;. This technique is something you'll see quite frequently in Reason React code. &lt;/p&gt;

&lt;p&gt;Now let's go back to our &lt;code&gt;Main.re&lt;/code&gt; file and delete everything besides the last line.&lt;/p&gt;

&lt;p&gt;Main.re&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;ReactDOMRe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;renderToElementWithId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HelloWorld&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice how we didn't have to explicitly import &lt;code&gt;HelloWorld&lt;/code&gt; into &lt;code&gt;Main.re&lt;/code&gt;? This will seem extremely weird at first, but because of how OCaml's module system works, all file-level modules are globally available under the file name.&lt;/p&gt;

&lt;p&gt;So in &lt;code&gt;Main.re&lt;/code&gt; we have access to the HelloWorld module. By using it in our JSX Reason React knows to call the module's &lt;code&gt;make&lt;/code&gt; function. &lt;/p&gt;




&lt;p&gt;Now you have all of the pieces necessary for starting a Reason React project with Parcel. Feel free to play around with things, and let me know what questions you have regarding Reason, Reason React, or Parcel.&lt;/p&gt;

&lt;p&gt;P.S. I wouldn't feel right without quickly mentioning &lt;code&gt;bsb&lt;/code&gt; as an alternative for bootstrapping Reason React projects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bsb &lt;span class="nt"&gt;-theme&lt;/span&gt; react &lt;span class="nt"&gt;-init&lt;/span&gt; &amp;lt;PROJECT_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To use the &lt;code&gt;bsb&lt;/code&gt; command you will have to install it globally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn global add bsb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or use npx (if you're using npm 5.2 or newer you already have it installed) to run the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npx bsb &lt;span class="nt"&gt;-theme&lt;/span&gt; react &lt;span class="nt"&gt;-init&lt;/span&gt; &amp;lt;PROJECT_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>reason</category>
      <category>react</category>
      <category>parcel</category>
    </item>
  </channel>
</rss>
