{"id":16667819,"url":"https://github.com/eanplatter/introduce-reason-example","last_synced_at":"2025-10-01T08:30:29.080Z","repository":{"id":82518611,"uuid":"86183593","full_name":"eanplatter/introduce-reason-example","owner":"eanplatter","description":"An example app made with Create React App which introduces a Reason component","archived":false,"fork":false,"pushed_at":"2017-03-28T10:51:49.000Z","size":104,"stargazers_count":82,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-13T10:01:56.899Z","etag":null,"topics":["bucklescript","ocaml","react","reason","reason-react","reasonml"],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eanplatter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-25T19:35:29.000Z","updated_at":"2024-01-04T16:12:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"786c5595-3cff-4f61-ac5a-07e041d8d23c","html_url":"https://github.com/eanplatter/introduce-reason-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eanplatter%2Fintroduce-reason-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eanplatter%2Fintroduce-reason-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eanplatter%2Fintroduce-reason-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eanplatter%2Fintroduce-reason-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eanplatter","download_url":"https://codeload.github.com/eanplatter/introduce-reason-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234841994,"owners_count":18895143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bucklescript","ocaml","react","reason","reason-react","reasonml"],"created_at":"2024-10-12T11:15:11.080Z","updated_at":"2025-10-01T08:30:28.764Z","avatar_url":"https://github.com/eanplatter.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introducing Reason to an existing React Project\nOne of the hardest things about trying out new tools is that they don't always play well with your\nexisting code, or if they do it takes a lot of time and effort to make it happen.\n\n[Reason](https://github.com/facebook/reason) happens to be extremely easy to integrate into an existing React app with the help of [reason-react](https://github.com/reasonml/reason-react)\n\nIn this README I am going to attempt to convey how I added Reason to an existing app created by [create-react-app](https://github.com/facebookincubator/create-react-app).\nThe code in this project is an \"existing codebase\" with Reason implemented.\n\n## Step 1 - BuckleScript Config\n[BuckleScript](https://github.com/bloomberg/bucklescript) is \"a backend for the OCaml compiler which emits JavaScript\". It\nis what turns our Reason code into JavaScript we can import into our React code.\n\nWe will run BuckleScript in our terminal, it will read our code and turn it into JavaScript. In order to point it in the\nright direction we will need to create a `bsconfig.json` file. This is similar to `webpack.config.js` or `.babelrc` files.\nIt merely configures BuckleScript.\n\nIn the root of your project create a file named `bsconfig.json`.\n\nI borrowed most of this `bsconfig.json` file from [Cheng Lou](https://github.com/chenglou)'s [reason-react-example](https://github.com/chenglou/reason-react-example)\n\n[bsconfig.json](bsconfig.json)\n```json\n  {\n    \"name\" : \"introduce-reason\",\n    \"reason\" : { \"react-jsx\" : true },\n    \"bs-dependencies\": [\"reason-react\", \"reason-js\"],\n    \"sources\": [\n      {\n        \"dir\": \"src\",\n      }\n    ],\n  }\n```\n## Step 2 - Add Dependencies\nWe need 3 new dependencies in order to make this work: [reason-react](https://www.npmjs.com/package/reason-react), [reason-js](https://www.npmjs.com/package/reason-js), and [bs-platform](https://www.npmjs.com/package/bs-platform).\n\nTo install these, run the following in your terminal:\n```shell\nnpm i -S reason-js reason-react \u0026\u0026 npm i -D bs-platform\n```\n\n## Step 3 - Add a BuckleScript NPM Script\nWe are going to need a way to run BuckleScript over our codebase. Since we've installed the `bs-platform` dependency and have created our `bsconfig.json` file we are set to start running BuckleScript! Add a script to our `package.json` file which runs BuckleScript, it should look something like this:\n```json\n  \"scripts\": {\n    \"buckle:up\": \"bsb -make-world -w\",\n    \"buckle:clean\": \"bsb -clean-world\",\n    \"start\": \"react-scripts start\",\n  }\n```\nThe names are arbitrary, I decided to call my scripts buckle:up and buckle:clean. So now in my terminal I can run it:\n```shell\nnpm run buckle:up\n```\nOnce we do this, if everything worked properly we should see a new directory in the root of our app named `lib/`; this is where BuckleScript will put our transpiled Reason components.\n\nIf we look in the `lib/` directory right now we will see that there is a `bs/` directoy. This isn't really important for us to look at right now, once we have a Reason component we will also see a `js/` directory. This `js/` directory is where BuckleScript is going to put our component! Let's go ahead and get started on that.\n\n## Step 4 - Writing a Reason Component\nIn the `/src` directory of our project let's create a new file called `Intro.re`. This is going to be a React Reason component which is going to replace the into paragraph on the default create-react-app main page.\n\n[Intro.re](src/Intro.re)\n```OCaml\nmodule Intro = {\n  include ReactRe.Component.JsProps;\n  type props = { message: string };\n  let name = \"Intro\";\n  let render { props } =\u003e \u003cp className=\"App-intro\"\u003e (ReactRe.stringToElement props.message) \u003c/p\u003e;\n  type jsProps = Js.t {. message : string };\n  let jsPropsToReasonProps =\n    Some (\n      fun jsProps =\u003e { message: jsProps##message }\n    );\n};\n\ninclude ReactRe.CreateComponent Intro;\n\nlet createElement ::message =\u003e wrapProps { message };\n\n```\nI don't want to dive too deep into the Reason syntax here, but essentially this is a component which takes in a `message` props and puts it into a `\u003cp /\u003e` tag with the `className` \"App-intro\".\n\n## Step 5 - Tieing it All Together\nIn order to do this, I had 2 terminal windows open, one running Webpack, the other running BuckleScript. Make sure both of these are running:\n\n### Running Webpack\n```shell\nnpm start\n```\n\n### Running BuckleScript\n```shell\nnpm run buckle:up\n```\nOnce these are running we should be able to see that our component has been transpiled by BuckleScript to [lib/js/src/intro.js](lib/js/src/intro.js) and it should look something like this:\n```js\n// Generated by BUCKLESCRIPT VERSION 1.6.0+dev, PLEASE EDIT WITH CARE\n'use strict';\n\nvar Curry   = require(\"bs-platform/lib/js/curry\");\nvar React   = require(\"react\");\nvar ReactRe = require(\"reason-react/lib/js/src/reactRe\");\n\nvar include = ReactRe.Component[/* JsProps */9];\n\nvar componentDidMount = include[0];\n\nvar componentWillUpdate = include[1];\n\nvar componentDidUpdate = include[2];\n\nvar componentWillReceiveProps = include[3];\n\nvar componentWillUnmount = include[4];\n\nvar getInstanceVars = include[5];\n\nvar getInitialState = include[6];\n\nvar name = \"Intro\";\n\nfunction render(param) {\n  return React.createElement(\"p\", {\n              className: \"App-intro\"\n            }, param[/* props */1][/* message */0]);\n}\n\nvar jsPropsToReasonProps = /* Some */[function (jsProps) {\n    return /* record */[/* message */jsProps.message];\n  }];\n\nvar Intro = /* module */[\n  /* componentDidMount */componentDidMount,\n  /* componentWillUpdate */componentWillUpdate,\n  /* componentDidUpdate */componentDidUpdate,\n  /* componentWillReceiveProps */componentWillReceiveProps,\n  /* componentWillUnmount */componentWillUnmount,\n  /* getInstanceVars */getInstanceVars,\n  /* getInitialState */getInitialState,\n  /* name */name,\n  /* render */render,\n  /* jsPropsToReasonProps */jsPropsToReasonProps\n];\n\nvar include$1 = ReactRe.CreateComponent([\n      name,\n      getInstanceVars,\n      getInitialState,\n      componentDidMount,\n      componentWillReceiveProps,\n      componentWillUpdate,\n      componentDidUpdate,\n      componentWillUnmount,\n      jsPropsToReasonProps,\n      render\n    ]);\n\nvar wrapProps = include$1[1];\n\nvar createElement = Curry.__1(wrapProps);\n\nvar comp = include$1[0];\n\nexports.Intro         = Intro;\nexports.comp          = comp;\nexports.wrapProps     = wrapProps;\nexports.createElement = createElement;\n/* include Not a pure module */\n\n```\n\nIf that is all working then we should be able to now import our Reason component into our existing React app. I am going to import it into [App.js](src/App.js) as `Intro`:\n[App.js](src/App.js)\n```js\nimport React, { Component } from 'react';\nimport logo from './logo.svg';\nimport Intro from '../lib/js/src/intro'\nimport './App.css';\n```\n...and replace the paragraph with the `className` \"App-intro\" with:\n```js\n\u003cIntro.comp message=\"To get started, edit src/App.js and save to reload.\" /\u003e\n```\n\n\n## All done!\nThat should be it! If you've made it this far then congratulations you've successfully introduced Reason into a React codebase! If you experienced any issues with this walkthrough please [open an issue](https://github.com/eanplatter/introduce-reason-example/issues/new) or if there are changes you think we should make feel free to [open a PR](https://github.com/eanplatter/introduce-reason-example/compare).\n\nA big thanks to [Cheng Lou](https://github.com/chenglou) and his [reason-react-example](https://github.com/chenglou/reason-react-example) which served as my primary source of information while doing this. Be sure to check out his example project for a more in depth look at using reason-react.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feanplatter%2Fintroduce-reason-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feanplatter%2Fintroduce-reason-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feanplatter%2Fintroduce-reason-example/lists"}