Getting started with ReScript and parcel  
Tags: reason, rescript, react
Published: 2021-04-30 22:14:40

## What is [ReScript](https://rescript-lang.org/) ?
as mentioned on the website, 
> The JavaScript-like language you have been waiting for,
Previously known as BuckleScript and Reason
### History & Summary
- `OCaml` is a typed FP language compiling to bytecode and native code.
- `Js_of_ocaml` is based on OCaml and compiles to JavaScript for OCaml users.
- `BuckleScript` is a fork of OCaml that also outputs JavaScript, optimized (features, JS interoperability, output, build tools) for JS developers rather than OCaml developers.
- `Reason` is an alternative, JS-looking syntax layer over OCaml, plus extra tools. Reason used 1. BuckleScript to produce JavaScript output and 2. OCaml to produce native output. Most of the community focused on the former usage.
Reason and BuckleScript shared most teammates, who wanted to double down on the JS use-case.
- `ReScript`, thus born, is the new branding for BuckleScript that reimplements or cleans up Reason's syntax, tools, ecosystem & docs into a vertically integrated experience.
Reason project will continue serving its purpose of a syntax layer for native OCaml. Some folks might use Reason with Js_of_ocaml to output JS code.


There is only one official template to create a new ReScript app [ReScript docs](https://rescript-lang.org/docs/react/latest/installation)
```bash
git clone https://github.com/rescript-lang/rescript-project-template my-app
cd my-app
npm install
npm start
node src/Demo.bs.js
```

`npm start` script will run `bsb -make-world -w` to compile the `.res` code into `.bs.js` code

as you can see the source code has only a console log statement so we need to add `@rescript/react` and convert that to a single-page web app, cd into `my-app` directory and install the other dependencies
also will use `parcel` bundler to transpile and bundle our front-end code and run the development server

```bash
npm install react react-dom  @rescript/react --save
npm install parcel concurrently --save-dev
```

- `concurrently` will be used to run 2 commands in parallel from npm scripts

The next step is to edit the bucklescript config file `bsconfig.json`

```json
{
  ...
  "reason": { "react-jsx": 3 },
  "bs-dependencies": ["@rescript/react"],
  "package-specs": {
    ...
    "in-source": false
  },
  ...
}
```
- `in-source` config is optional, I like to keep the compiled `.bs.js` files outside the `src` especially in a new project that is started as ReScript projects, if you set this to `false` the compiled files will be at `./lib/js/src`, if it is `true` the compiled file will be in the same place as its `.res` source

next, create a `public/index.html` and `public/global.css` directory with the content

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./global.css">
    <title>Hello ReScript</title>
</head>
<body>
    <div id="app-root"></div>
    <script src="../lib/js/src/App.bs.js"></script>
</body>
</html>
```

then will add an npm script to start the bucklescript compiler command and the parcel dev server

```json
    "dev": "concurrently \"parcel ./public/index.html\" \"bsb -make-world -w\" ",
```

finally rename `src/Demo.res` to `src/App.res` with this basic ReScript code 

```react
module App = {
  @react.component
  let make = () => {
    <div> <p> {React.string("Hello World 123")} </p> </div>
  }
}

switch ReactDOM.querySelector("#app-root") {
  | Some(root) => ReactDOM.render(<App />, root)
  | None => ()
}
```
this will create a React component `App` and render it at the div with id `app-root`

now let us start the dev server and check the result at http://127.0.0.1:1234

```bash
npm run dev
```