Confused about ReScript? ReScript, Reason, ReasonML, and BuckleScript explained

tl;dr:

  • If you’re a web dev and you’ve heard about this newfangled ReScript/Reason/ReasonML/BuckleScript thingy, you’re most likely looking for ReScript, which is a new language that combines the best parts of JS and OCaml. It has a compiler that compiles to JS and leverages OCaml’s static and sound type system. Many people prefer this approach to TypeScript. It also has an awesome and growing community with people who are ready to help you learn the language.
  • ReScript grew out of Reason (a JS-like syntax for OCaml), BuckleScript (the former name of the ReScript compiler and toolchain) and ReasonML (the name for the ecosystem that grew up around Reason’s syntax). Reason and ReasonML still exist whereas BuckleScript morphed into ReScript, introducing with it a new Reason-like syntax and a new community.
  • If you’ve been confused by the ReScript team’s announcement that Reason “rebranded” into ReScript, you’re not alone. What it boils down to is that ReScript is a new, distinct language with historical links to Reason that will diminish over time as the language grows.

ReScript is one of the most amazing technologies available to JavaScript developers today. Unfortunately it suffers from a marketing problem:

Folks are totally confused by its “rebrand” from Reason/ReasonML.

The team’s leaders have explained that ReScript is a “rebranding” of BuckleScript meant to provide newcomers with a clear single term used to refer to the wide ecosystem of languages, tooling and projects that it leverages. For many, though, the rebrand seems to have obfuscated matters rather than clarified them.

That’s why I’d like to take some time to thoroughly explain what ReScript is and its relationship to three other terms that you may have heard before: Reason, ReasonML and BuckleScript. I’m going to explain each of these terms individually, and then I’ll show how they relate to ReScript.

Reason

Reason is a JS-like syntax for OCaml that was created by Jordan Walke, the creator of React, in 2016, to popularize OCaml among JS devs.

Reason has no formal specification. Its source of truth is its parser code, which is written in OCaml. It also has an accompanying standard library, some of which reimplements the OCaml standard library using the new syntax.

A point of confusion that I’ve seen come up before is whether Reason is merely an OCaml syntax or its own fully-fledged language. This distinction was a major factor behind why ReScript split off from Reason (more on this later). ReScript’s devs wanted the freedom to iterate on Reason as its own language, adding and removing parts to and from OCaml as needed, but Reason’s devs wanted to stay more tightly connected to OCaml.

Reason’s own documentation fuels some of this confusion by describing the project as a language:

Reason is a programming language powered by OCaml’s strong type system, and has a syntax designed to feel familiar to people coming from JavaScript or C-family languages.

The distinction between a syntax and a language is perhaps somewhat subjective, but I think that ultimately it comes down to the intentions of the development team. Reason’s team has indicated that they want to stay firmly in the OCaml ecosystem and retain maximum compatibility with all of OCaml’s features, so for most users it’s less confusing to think of it as a specialized syntax rather than a language in its own right.

Summary: Reason is a JS-like syntax for OCaml with an accompanying standard library.

ReasonML

According to Jordan Walke:

ReasonML is an umbrella project/sponsor for many subprojects, all of which have the goal of bringing fully type safe, fast compiling, fast executing code to the widest number of developers and today that means JavaScript developers. Many ReasonML projects support or improve upstream OCaml ecosystem.

Reason syntax was the first project under the ReasonML umbrella. Other projects include ReasonReact (a set of React bindings and tools for Reason), esy (package management for Reason/OCaml), and Sketch.sh (REPL for Reason).

What’s confusing for beginners is that ReasonML is often conflated with Reason, but the two are apples and oranges. I suspect that folks use the terms “Reason” and “ReasonML” interchangeably is because the word “Reason” by itself is too generic. Try searching for “Reason” and you’ll get everything from music production software to libertarian magazines, but if you search for “ReasonML” you’ll find tutorials and articles for the Reason syntax.

Go suffers from a similar problem, which is why that community often uses the term “golang” in posts and search queries. Their approach, in my opinion, is much clearer since it would be difficult to confuse “the Go community” with “golang.” By overloading “ReasonML,” the ReasonML community has unfortunately become conflated with the syntax used by that ecosystem.

Summary: ReasonML is the name given to the Reason ecosystem. More broadly construed, ReasonML is a community focused on popularizing OCaml with an emphasis on outreach to JS developers.

BuckleScript

BuckleScript is the old name for the ReScript compiler (see below). Open sourced in 2016, it was created by Bloomberg as a way of compiling OCaml into JavaScript. The goal was to generate high-quality, optimized JS modules from OCaml without any name conflicts.

BuckleScript was also adopted by ReasonML as its official OCaml-to-JS compiler. As such, the compiler supported both standard OCaml as well as Reason syntax. BuckleScript also introduced a few modules, including a standard library called Belt and various bindings for JS API’s (e.g., DOM, Node).

Sometimes people will confuse BuckleScript with Reason or mistake it as its own language. My suspicion is that it’s because of the profusion of compile-to-JS languages that end with the word “Script” (e.g., TypeScript, PureScript, ClojureScript). Unlike those other projects, however, BuckleScript was a compiler with a standard library and some bindings for OCaml (with support for Reason syntax) rather than being its own language.

Summary: BuckleScript was an optimizing compiler that compiled OCaml into JS. It also introduced a few libraries such as Belt and bindings for JS API’s.

ReScript

Now we come to the main course.

First, let me explain what “ReScript” is in my own words without any reference to Reason, ReasonML or BuckleScript:

ReScript is a language that combines the best parts of JS with the best parts of OCaml. It has its own syntax, compiler, formatter and build tools. It also has a vibrant community that’s interested in making OCaml’s power and its sound, static typing as accessible to JS developers as possible.

Can you see the connection to Reason, BuckleScript and ReasonML? ReScript combines all three into a fully-fledged language:

  • A JS-like syntax for OCaml (like Reason)
  • A compiler and toolchain (like BuckleScript)
  • A community and various tooling (like ReasonML)

ReScript started as an evolution of Reason’s syntax and was introduced by the BuckleScript team to BuckleScript 8.1.0 in July 2020. As the BuckleScript team made clear at the time, the new syntax was compatible with only BuckleScript and no other compilers. For this reason (no pun intended), the classical syntax supported by BuckleScript before 8.1.0 continued to be called Reason, and the new syntax was dubbed ReScript.

“Rebranding” BuckleScript as ReScript

In August 2020, the BuckleScript developers announced that they were “rebranding” their compiler as ReScript, which was already the name of their new Reason-like syntax. Their intention was to signal that web development efforts in the ReasonML world around Reason and BuckleScript would henceforth go under a single banner, “ReScript.” The hope was that, whatever short-term pain might stem from changing the name, in the long term having a single brand would help boost adoption. I believe that this prediction will eventually pan out.

Whether you think of it as a rebrand or an entirely new product, ReScript brought together a huge number of changes to the old BuckleScript project:

  • Independence from OCaml: Remember Jordan Walke’s description of ReasonML as a way of bringing OCaml to “the widest number of developers, and today that means JavaScript developers”? BuckleScript’s devs wanted to give themselves the freedom to break away from OCaml’s idioms and even its features. For example, ReScript has introduced the uncurried calling convention to make JS interop better, and the team plans to remove support for OCaml classes and objects from the compiler. Whereas BuckleScript could be thought of as an OCaml compiler, ReScript’s compiler is really intended to be a compiler for its own language.
  • Closer to JS: ReScript’s syntax has gone beyond Reason to adopt idioms from the JS ecosystem. For example, replacing the parens surrounding Reason type parameters with angle brackets, as in array<string> instead of array(string), resembles generic types in TypeScript.
  • Relegation of Reason to legacy status: The rebranding announcement effectively froze the ReScript compiler’s support for Reason syntax. Existing Reason code will work for a long time, but changes to Reason will not be supported by ReScript and vice versa. The ReScript team’s focus will now be on their own syntax.
  • Parser: The team wrote a new parser compatible with ReScript, Reason and standard OCaml syntaxes. The old Reason parser still exists in a separate repo, maintained by the Reason team.
  • New website and documentation: A new, rebranded site was launched with a guide focused on ReScript syntax, unlike the old BuckleScript site which offered examples in Reason and OCaml. Although the documentation dropped references to the old syntaxes, the ReScript compiler still supports them.
  • Community: A new forum, Twitter account, and Discord channel were launched.
  • Emphasis on ReScript as a language: If you look through the documentation, blog posts and all the community resources, you’ll notice that the team appears to emphasize that ReScript is a language, not a syntax. There’s been a concerted effort to think of ReScript as its own thing rather than just an extension of OCaml, even more so than has been the case with Reason.
  • Governance: Reason is maintained by Facebook whereas ReScript, having been driven by BuckleScript’s team, is largely community-driven.

Given all these changes, it’s fair to say that ReScript is an entirely new language. Indeed, that’s how its developers want us to think of it.

Where does that leave us?

What does all this mean for those of you who are looking to use Reason or ReScript in your projects? It’s simple:

If you’re a web developer and you heard about Reason, ReasonML, BuckleScript or ReScript on Hacker News or somewhere else and want to give it a try, there’s a 99% chance you want the language called ReScript, not the OCaml syntax called Reason. When you look for community, again look for ReScript, not ReasonML, even if sometimes you need to search for “reasonml” to get hits on StackOverflow and translate Reason syntax to ReScript’s syntax. And when you think about your toolchain and standard libraries, know that you’re using ReScript, not BuckleScript, even though you’ll see some vestigial references to the former name (e.g., bs-platform). So head over to https://rescript-lang.org/ and start having some fun!

If you’re developing native apps or perhaps even React Native, the picture is a little more murky. I believe that Reason is more oriented toward these use cases, but to be honest I don’t know much about it and I could be totally wrong. (If you know this subject well, please let me know in the comments below and I’ll update this post!) If you’re a library developer, I’d assume at this point that you’d want to write your code in Reason if you wanted to retain maximum compatibility with both communities, although there’s a case for writing in ReScript if you want to invest in the new ecosystem.

If you’re a React web developer, you’ll want to start with ReScript and you’ll also want to delve into ReasonReact, which is the ReasonML community’s official set of bindings. There are active conversations as of writing about how to rename the project (i.e., something like “ReScriptReact”) and integrate it into ReScript, which makes a lot of sense since ReScript has more of an emphasis than Reason on JS conventions and interop. All the code examples in ReasonReact’s documentation are still written in Reason, but they will work just fine using ReScript’s compiler in .re files. You’ll need to become familiar with Reason’s syntax in order to understand them, which fortunately isn’t too difficult since, at the moment, Reason and ReScript’s syntax are still very similar.

As you start working with ReScript, you’ll quickly become adept at translating code back and forth between Reason and ReScript syntaxes since, at the moment, there aren’t too many differences betwen them and many libraries are still written in Reason. So any Reason code examples that you find are perfectly valid for learning ReScript, so long as you’re willing to jump back and forth between different sets of documentation.

Speaking of documentation, you’re going to eventually encounter features used in the wild that aren’t covered by ReScript’s guide. This is an issue that I and others have raised within the community. The good news is that the dev team is aware that the docs must improve and it’s being worked on. The bad news is that, as you become more advanced, you’ll find yourself flipping between the docs for ReScript, Reason, OCaml, the old BuckleScript docs (which were taken down but have been mirrored by a volunteer), as well ReScript blog posts that have announced new language features that haven’t made it into the official guide yet.

Remember! Because of ReScript’s heritage, its compiler supports:

  • ReScript’s own syntax (which is derived from Reason’s syntax; this is what you should be using for new projects)
  • OCaml’s Reason syntax (i.e., plain ol’ Reason; specifically, the version from around August 2020 when ReScript split off, which as of writing is still very similar to ReScript’s syntax)
  • ReScript-specific features (e.g., the uncurried calling convention for JS interop; there aren’t too many of these features as of writing)
  • OCaml features (because ReScript started as a Reason-like syntax for OCaml that was supported by BuckleScript)
  • BuckleScript-specific libraries that carried over into ReScript (e.g., Belt, Js)

Until the community creates a unified and comprehensive set of docs for the language, users will find themselves referring to all the docs mentioned above. I’d say that after using ReScript for two months, 80% of the time I’m looking up info in the ReScript guide, 10% in the old BuckleScript docs, 5% in Reason docs, 3% in blog posts and 2% in OCaml docs. I spent much more time early on in the Reason docs in order to read library code written in that syntax, but now that I know it, I hardly refer to it anymore.

You’ll also want to check out the ReasonML Discord #rescript channel and the ReScript forums for help. I’ve noticed that people are especially responsive on Discord (although not so much on the #react channel).

I hope that my deep dive into ReScript’s rebranding has clarified any confusion that you may have had regarding the language and its relationship to the broader ReasonML ecosystem.

What are your thoughts about ReScript? I’d love to hear from you.

And if you enjoyed my article, please don’t forget to like it and share it! ❤️