DEV Community

Cover image for Bootstrap a Reason-React project with Parcel
Sebastien Castiel
Sebastien Castiel

Posted on • Originally published at blog.castiel.me

Bootstrap a Reason-React project with Parcel

Not that long ago I used Create-React-App a lot to quickly boostrap my React projects. That’s why I naturally used Reason Scripts when I wanted to use Reason-React. But even if I still understand the advantages of the approach of CRA and Reason Scripts, I recently discovered Parcel, a very minimalist bundler for web projects.

There are already a lot of articles explaining the advantages of Parcel, and how to use it with React for instance. What I wanted to do here is show you how you can use it to start a new project with Reason first, then add Reason-React to write React components.

TL;DR: I created a project on GitHub containing the final code for the article, if you just want to see the final result.

Start a basic Parcel project

First, let’s init a new project with Yarn (NPM should work just fine too) and add Parcel:

$ mkdir reason-parcel && cd reason-parcel
$ yarn init -y
$ yarn add --dev parcel-bundler
Enter fullscreen mode Exit fullscreen mode

Let’s edit the generated package.json to add the start script:

{
  "name": "reason-parcel",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "parcel public/index.html"
  },
  "devDependencies": {
    "parcel-bundler": "^1.6.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

Then let’s create our public/index.html file:

<html>
<body>
  <script src="../src/index.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

And finally let’s add a src/index.js file so we can test our first version:

console.log("Hello from JavaScript!");
Enter fullscreen mode Exit fullscreen mode

To start the project, let’s just run yarn start:

![Hello from JavaScript!](https://thepracticaldev.s3.amazonaws.com/i/j3g74ataa6zoh8eouhal.png)

Add Reason

Okay this was basically the tutorial to start a Parcel project, but where is Reason? Let’s start by adding bs-platform dependency to the project:

$ yarn add bs-platform
Enter fullscreen mode Exit fullscreen mode

We’ll need a bsconfig.json file to tell BuckleScript what to do:

{
  "name": "reason-parcel",
  "refmt": 3,
  "sources": "src",
  "dependencies": [],
  "package-specs": {
    "module": "commonjs",
    "in-source": true
  },
  "suffix": ".bs.js"
}
Enter fullscreen mode Exit fullscreen mode

We are telling BuckleScript to compile Reason files to JavaScript in the same directory, with .bs.js, so our src/index.re will be compiled to src/index.bs.js. This way Parcel will be able to deal with them natively.

Let’s create this src/index.re file (by renaming src/index.js file to src/index.re) and set its content to:

Js.log("Hello from Reason!");
Enter fullscreen mode Exit fullscreen mode

We also need to update our public/index.html with the new path of the main file, which is now written in Reason:

<script src="../src/index.re"></script>
Enter fullscreen mode Exit fullscreen mode

Let’s start our app now:

![Hello from Reason!](https://thepracticaldev.s3.amazonaws.com/i/ov8gn0h2v1p6i0jgi4mi.png)

There it is! Only one command to run the project including Reason to JavaScript transpilation! 😁

Add Reason-React

Last step now: adding Reason-React to the project so you can write your components in Reason. First we need to add the dependency:

yarn add reason-react
Enter fullscreen mode Exit fullscreen mode

We also need to update bsconfig.json to tell BuckleScript we’ll use Reason-React and JSX:

{
  "name": "reason-parcel",
  "refmt": 3,
  "sources": "src",
  "bs-dependencies": ["reason-react"],
  "reason": {
    "react-jsx": 2
  },
  "dependencies": [],
  "package-specs": {
    "module": "commonjs",
    "in-source": true
  },
  "suffix": ".bs.js"
}
Enter fullscreen mode Exit fullscreen mode

Now let’s create a simple component in src/Greeting.re:

let component = ReasonReact.statelessComponent("Greeting");

let make = (~name, _children) => {
  ...component,
  render: (_self) =>
    <div>
      (ReasonReact.stringToElement("Hello "))
      <strong> (ReasonReact.stringToElement(name)) </strong>
      (ReasonReact.stringToElement("!"))
    </div>
};
Enter fullscreen mode Exit fullscreen mode

Let’s use it in src/index.re:

ReactDOMRe.renderToElementWithId(<Greeting name="Sebastien" />, "root");
Enter fullscreen mode Exit fullscreen mode

And finally let’s add a root div to our public/index.html to render our component:

<html>
<body>
  <div id="root"></div>
  <script src="../src/index.re"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Wow that’s it! Easy right? Here is what you should get in your browser:

![Hello from Reason!](https://thepracticaldev.s3.amazonaws.com/i/y56ggj1vovssand2xa1h.png)

Now you’re ready to use React to build powerful and maintainable components and enjoy the possibilities of Reason in the same time. Of course it isn’t the only way to do so, but I like how elegant the method with Parcel is.

I’d be curious to know if you see improvements to this workflow. Maybe using Parcel packagers or plugins could make it even cleaner? 😉

Some resources:

This article was originally posted on my blog.

Top comments (4)

Collapse
 
ben profile image
Ben Halpern

Reason is becoming mainstream right before our eyes!

Collapse
 
scastiel profile image
Sebastien Castiel

Yes, and that’s a very good thing! ;)

Collapse
 
justgage profile image
Gage

HERE HERE! So excited.

Collapse
 
aeons profile image
Bjørn Madsen

Hey,

Did this work with auto-reloading when changing a .re file? If it's not index.re?