Should I include or exclude *.bs.js files in git?


This is a pretty common question in Discord chat and I hate to answer it everytime so let’s me type it once and refer to it later.

Should I?


If you’re in the process in introducing ReasonML/Bucklescript into an existing Javascript/Typescript/Flow codebase and you don’t want to change your build process. Everyone who’s not working with ReasonML shouldn’t notice a thing.

The downside of this approach is git conflicts. It’s a real pain.


  • You’re starting a project from scratch with ReasonML.
  • You let everyone working on the project know about it. They must install bs-platform for compiling .re files to *.bs.js

If I’m releasing a library for ReasonML consumers, should I?

Exclude it please.

cc @chenglou Please make this a wiki so others could edit it.


In my company I just added one step to build process - ‘npm run build-reason’. It builds all *.bs.js files, which are later imported by ‘normal’ TS/JS application, without even knowing they come from ReasonML code. This build step takes a second, so no one noticed it.

Also, if you exclude bs.js from git, and add a tiny build step ‘npm run build-reason’, you will never forget to commit *.re files together with updated *.bs.js files! In other cases you might update *.re files but forget to build and commit *.bs.js files :frowning:


This is what I’m talking about in include section. and IHMO, the best time to run the script is on git-hooks. This ensures *.bs.js files are always in sync with *.re code.

husky is an amazing tool for introducing git hooks into your codebase


Made into a wiki. When this is mature, let’s upstream it into or something. Such thing should be part of the official docs!


This is an interesting question. I think there is an argument to be made that even if a package is only consumed from Reason/Bucklescript that being able to easily see diffs of the generated javascript aids in code review. One could check generated js into git but exclude it from the published package with .npmignore. Reason-React commits and publishes its generated js, for example. I have been doing the same with packages I maintain.

On a side note, I wish bsb had a flag to skip dead code elimination so we wouldn’t have to write code that uses all of our bindings just to see if it generates correct-looking js.


I’ve learnt to trust bsb completely. I never look into bs.js files. I only do that when I think there is a bug in the bindings


I second this. I haven’t looked at a *.bs.js file in months.


I, too, don’t actually read the generated files much nowadays. Doesn’t help much that ReasonReact’s output is rather bad. Though I do think it’s an invaluable tool for newcomers, and a workflow that we, as folks who have been using Reason for a while, don’t encounter enough, since our our codebase likely overcame the initial interop period.

So it depends on the condition of your company’s codebase, etc.


For just being able to see how a given change affects the compiled output I think tooling can help. If you snapshot (but don’t commit) the JS artifacts on your master branch, then you can run a quick diff of the changes on the feature branch. Maybe even add that to the scripts in your package.json. Then you get all the benefits of being able to see the changes without creating a bunch of noise in commits and further complicating merge conflicts. I think I’ll give this setup a try, actually.


In our company we started adding Reason to an existing JS codebase that is a multi package Monorepo using Yarn workspaces. Initially things went well and we could run make-world and commit the compiled bs.js to the repo. We started to refactor more and more code into Reason.

The moment we started to use third party binding like reason-apollo, we needed to add a build step to our CI. In an app that has dependencies like a -> b -> c where c contains a Reason binding, means configuring a bsconfig.json and installing a bs-platform in packages a, b & c even though a & b don’t have any Reason code.

This workflow proved difficult to manage for other devs who don’t use Reason. To solve the problem, we are cloning and compiling the third party dependencies to remove the build step from our dev and ci environments.

Can anyone suggest a solution to cloning bindings/libraries?

Thanks in advance.