JS Party – Episode #175

This is ReScript

with Patrick Ecker

All Episodes

Ever wanted a language like JavaScript, but without the warts, with a great type system, and with a lean build toolchain that doesn’t waste your time?

Patrick Ecker from the ReScript Association sits down with Jerod and Feross to tell us all about this “JavaScript-like language you have been waiting for”.

Featuring

Sponsors

O'Reilly Media – Learn by doing — Python, data, AI, machine learning, Kubernetes, Docker, and more. Just open your browser and dive in. Learn more and keep your teams’ skills sharp at oreilly.com/changelog

Square – Develop on the platform that sellers trust! Use API Explorer to interact with, test, or play with your applications in Square. You can build, view, and send HTTP requests that call Square APIs with API Explorer. Get started with Square, check out the API Explorer, or the API Explorer docs.

Sentry – Build better software, faster with Sentry’s application monitoring platform. Diagnose, fix, and optimize the performance of your code. Cut your time on error resolution from hours to minutes. Use the code PARTYTIME and get the team plan free for three months.

Notes & Links

📝 Edit Notes

Transcript

📝 Edit Transcript

Changelog

Play the audio to listen along while you enjoy the transcript. 🎧

Hello, everyone out there in JavaScript land. It’s your internet friend, Jerod, and I’m here for a fun show about ReScript today. Feross is joining us. What’s up, Feross?

How’s it going, Jerod?

It’s going good. Hey, you launched a new thing, it’s called Wormhole… How’s that going? Good?

Yeah, going pretty good. It’s fun times.

Tell the folks what it is real quick.

Yeah, it’s a tool for sending files to people with end-to-end encryption, so you can safely send your files across the interwebs.

Yes. It’s like Firefox Send, only they shut that down and this is probably even cooler, because you’ve built it… Maybe you’ll have to give us the skinny sometime; remember we did the nitty-gritty on BitMidi…

We might need to regroup and get one for Wormhole.

Yeah, let’s do it.

Awesome. Sounds like a plan. We’re also joined by Patrick Ecker, who is with the ReScript Association. We’re here to talk about ReScript. You may have heard of ReScript, or maybe not; maybe you’ve heard of BuckleScript, maybe not. Maybe you’ve heard of Reason, maybe not. Maybe you’ve heard of OCaml. Maybe you’ve heard of none of these things. We’re gonna sort through all that, and hopefully dive deep into this cool language and ecosystem for building web apps… And maybe even more. Who knows. Patrick, welcome to JS Party.

Thank you for having me.

We’re excited. I thought we would start with all of that because I had never heard of ReScript, but I had heard of Reason… And I hadn’t heard of BuckleScript until I read the rebranding post… But y’all have been around for a while, in different forms, and there’s multiple tools that have come together to kind of unify and hopefully have a cohesive story going forward… But give us the background of these disparate tools, or involved tools, and then kind of the coming together. Maybe sort through that from that start, and then we’ll get into the nitty-gritty from there.

[04:08] Sure. This is probably the most famous question whenever someone is asking about ReScript, because a lot of people got in touch with ReasonML and BuckleScript, which is like a cohesive toolchain - Reason is the syntax and BuckleScript is the compiler which takes Reason syntax. It looks also a lot like JavaScript, and [unintelligible 00:04:26.10] to JavaScript. This has been going on for a few years. We also made some cross-compilation story out of it, and then people got involved with a lot of OCaml, which this whole thing is built on, basically.

There were two communities going on. There was one community going more into this native exploration direction; they wanted to compile to native, they wanted to have a nice garbage-collected language that is almost as fast as Rust, and then we had the JavaScript story, which should be like a single toolchain, it should be simple to understand, it should be simple to understand, it should be easy to integrate in existing JavaScript codebases… And this was also the bigger setting point of the platform, because a lot of people got into this JavaScript compilation thing and they used it actually in their projects for more than two years, three years in production now… And the major problem here was that people got confused. So they got into the community and they were like “Okay, I want to do ReasonML. What can I do?” and then they’re like “Oh, do you want to do native or do you want to do JavaScript?” And then it’s like “Okay, what is the easiest?” “Oh, you can do this and that with this compiler, or with this compiler, or you can do the OCaml way with something else”, which was always confusing. We never liked the idea of decoupling the syntax from the compiler.

In 2020, after one year of development of a rewrite of the syntax, we decided to align the compiler with this new syntax, which is actually even more JavaScripty as ReasonML, and called it ReScript. We also made it really clear that this is all about JavaScript development. So we built a toolchain which kind of feels similar from a workflow perspective, so you basically install other compile to JS languages like TypeScript or Elm or whatever. You install one npm package, npm install ReScript and you’ve got all the tools you need to compile ReScript files to equivalent JavaScript files.

Ever since we did that, suddenly people get it. People get to the platform, they get to one cohesive website, all the resources are on there… We have a cohesive story for React development, we have cohesive stories for how to integrate it with Next, how to integrate it with any React application that already exists… And we made it really clear – we also removed all the diverting for ReasonML or OCaml because it’s not relevant anymore. We care about minimalistic design, minimalistic CLI, no configuration or low configuration, and also a syntax formatter without any options. Without any of them. Not even the [unintelligible 00:07:11.02] not even semicolons, nothing. There is just one style basically enforced, and we are really glad we did that. We’re really happy that this is now such – now it’s easy to understand, and now we are happy, and now we want to start out again with a fresh brand and a cohesive story.

I just have to say, the more you kept talking, the more excited I was getting. All the words you were using - minimalist, no configuration format, or without any options, no semicolons, focusing the website down… I’m really curious now to try it.

[07:46] Right, right, right. It’s so exciting also for me, because I’m also not the biggest fan of these bulky, huge languages that give you 15 different configurations and every project looks different. And the second thing is the major selling point of the platform is that it’s fast, ridiculously fast. It’s hard to describe, actually. We try to build a platform that doesn’t really [unintelligible 00:08:08.26] So we can compile (I don’t know) 3,000 files in a project once, and then can start a cold build… Or actually, we cache files on the file system level, but we don’t need an extensive, incremental background service which requires two gigabytes of RAM, like in TypeScript. If you want to have a fast build, you need to wind up this huge server, and then it indexes all your files, and then caches get invalid in between in memory, and then you switch branches, and then suddenly all your type information is kind of corrupted, and then you need to do a cold build again and this takes 20 minutes… If you have a big codebase, like a serious codebase. For smaller projects it’s probably not a problem…

ReScript really scales with the amount of files you have. If you start out with a ten files project, it’s instant. It’s 20 to 50 milliseconds per build. It doesn’t matter if it’s an incremental build or a cold build. And then you have huge size projects, like – I have one client who has 3,290 files, or something; the first initial build, if you completely clean this whole thing and build it once, it takes like one minute and thirty seconds, and this is not even optimized. There are a few things you can tweak to make the compilation faster. But after that, you change a file and it doesn’t take forever to just recompile this one file, and it doesn’t really rely on these caches I was talking about. And then things get way less complex if you can just rely on one simple command that winds up when you need it, and then winds down when it’s done.

Yeah. So zooming out a little bit - it sounds like you’ve got really good performance on builds, and as far as the compiled language goes, you have a lot of nice features… But why would I use ReScript over just plain JavaScript? Because plain JavaScript files have no build time. So what am I getting by using ReScript over plain JS, or something like TypeScript?

Yeah. Plain JS is a dynamic, untyped language. For me personally, when I write a bigger JavaScript application, it’s usually very hard to maintain it or refactor it, especially if it’s like a really complex codebase, with a lot of people working on the same codebase. If it’s like a React application or an Angular application, it doesn’t matter. TypeScript tries to mitigate that by being a superset of JavaScript, so you can turn around a JavaScript file into a TypeScript file and it will still compile, but then you can also add type annotations and stuff. So it is a gradual type system, and these ones have the downside that they need to deal with the complexities of JavaScript, because JavaScript is a very dynamic language, it’s very polymorphic. You can do a lot of things you usually cannot do in statically-compiled, sound languages. And what ReScript is - it’s a sound-typed language, which means that every value in your program has a type annotated. There is no any type, there is no mixed type, or no unknown type, or some sorts of that, which makes it very robust.

We also don’t have – in the core language, if you just write ReScript code, you don’t have any null pointer exceptions, because we don’t have any null. We don’t have the concepts of null. Instead, we have a few other niceties which help you build very complex applications. For instance, we’ve got variant types, which are also very well known in languages like Rust, which is a data structure to design complex domains. If you think about like TypeScript, when you’re using a tagged union, you usually have an object type, and then you have an attribute type on there, and you call that type user, and then you have some certain attributes available because this is like a user type… Which is kind of like abusing the object type of some sense, and then gradually refining the type. In ReScript we have the variants, which look a little bit like – I don’t know how to explain it. You would define a type user, and then you have constructors values; call that (I don’t know) admin, or user, or privileged user, or moderator, and then you can attach data to it.

[12:28] So you can have an admin constructor, and this one contains a string for the user name, and then you can just use that as a value in your program, and then you can pattern-match on that with a very powerful switch-like expression. So you can really design your domain just with types, and then later on use these values to manage your application code.

The sound type thing is also very nice, because refactoring is a totally different story there. Whenever you’re doing TypeScript, you’re installing some libraries, these libraries maybe involve some definition files, these definition files may come from a third-party that is maintained independently from the actual library. Maybe it’s like an add-on which is – maybe the library is not written in TypeScript, and they write a definition file for that. So information can be stale, or wrong, or some sorts, and it’s not always clear when you refactor a codebase or when you raise a dependency, or when you do this kind of stuff if your code really works. And as soon as you have this one trust issue in your type system, that type system suddenly isn’t that nice anymore. You have autocompletion, yeah, and some other nice tooling opportunities… But the full trust, when the program compiles - it will work, unless I’m doing bailout functionality for communicating with external JavaScript… Yeah, that’s really great if you can do that. If you can say with a convincing voice “Yeah, this program compiles. I’m pretty sure this would just work.”

So no bugs. That’s what I want. I want no bugs.

I mean, you will still have bugs…

Alright, I’m out.

…but it’s very easy to at least say – if I change the interface or something, the compiler will really help me; the compiler messages are really good, especially with those variant types I was talking about. When you change something, then the compiler will say “Okay, this interface doesn’t match here and there.” If you do pattern-matching and you’re for instance adding new cases to a variant; for instance, I have my admin and my moderator, and I want to add a user variant constructor or whatever, then pattern matchers, wherever I have a switch expression, the compiler will tell me “Hey, you forgot to add the user constructor case.” And when I remove the user constructor, it says “There is no user constructor.” This is super-useful when, for instance, you’re building React components. React components in the beginning are super-easy. You’re like “Oh, I need to have a button.” Okay, HTML button. That’s it. Then it’s like, “Oh, but we need accessibility”, right? And then you need like, okay, I need to annotate different states; when there’s an hover state, or when there’s like a click hover, or when you have touch, and other interactions… Suddenly, the code gets really complex.

When you look at things like – Tailwind did a really great library for doing the heavy lifting for you, where you get React components and then you just use them, and they implement a complex logic in the background. Maybe you check that out; check out how complex this code can get with TypeScript, just because they’re using these tagged union objects, and then they try to shoehorn it in with some switch statements. It’s really hard to read, and then you need annotate everything, because the type system needs more help inferring all your types. In ReScript, every type that is inferred from the compiler is 100% correct. This is also very nice, if you can trust the compiler there to do the right thing.

[16:22] Well, pattern-matching is really cool, so that’s a great language feature that I always appreciate. It’s difficult sometimes when we are hearing about something brand new, unfamiliar, to get a frame of reference. ReScript is its own language. It’s a language that compiles to JavaScript. So what are some hooks that people can have? Not like specific features, but is it like anything else? Is it kind of like Elm, is it kind of like ClojureScript? We’ve already contrasted it from TypeScript; it’s not a superset of JavaScript. It’s not JavaScript. But would you say it’s Elm-esque in terms of it’s kind of FP-style?

Yeah, yeah… So no, it’s actually not. It looks a lot like JavaScript, acts a lot like JavaScript, and in our opinion, compiles to the highest quality of readable and performant JavaScript, which is really nice; it’s our marketing pitch. So our idea was - which is kind of rare; we haven’t seen this before, that’s why we build it. You really write your code, you have your typical let bindings, or let variable kind of thing; we call it let bindings. So you define a variable, or you define a function with arrow function syntax… We only have one syntax for functions, which is the arrow syntax, which compiles to an actual named function. So you don’t have to worry “Should I use a named function, or should I use a named function without a name? Should I use an arrow function? Should I use bind?” We don’t have that concept. We just use the arrow function syntax for that. We don’t have classes, which means that we replicate the behavior of classes by saying that we just think about values and functions, and then we have a pipe operator to chain all these things together.

So we can model an object-oriented system just with values and the pipe operator, which looks a little bit like a PHP, because our pipe operator is basically like an arrow, so [unintelligible 00:18:14.17] which means “Oh, I cannot interact with object-oriented systems with classes in existing JavaScript code.” But we can, because we also added to this an external syntax (it is called), which is finding – you can define an external that binds to an existing JavaScript function, and you can tell the external binding if it’s like a new constructor, if it’s like a class constructor or whatever, or if it’s like a method function; you want to call this, or you put in a value and then it calls the function on this value, like with a method.

So we can interact with the more complex features of JavaScript, but in the core language we don’t need that. And when we look at a ReScript file - so we have a ReScript file which is .res, and you compile it with the compiler, it will create an equivalent JavaScript file right next to it. And by default, when you define a value or a function inside a ReScript module, this value will automatically be exported or exposed as an export in this generated JavaScript file.

Our recommendation is to write your functions and values just the way you used to in ReScript. You can do for loops, you can do while loops, you can do your typical array map and whatever… We have all the bindings there for all the JavaScript Web API collections and arrays and whatever. And then you open a new tab with the JavaScript output and you can see that the compiled output looks very similar to the actual ReScript code, if done correctly.

[20:05] And since this idea of ReScript file is [unintelligible 00:20:08.08] you can integrate it really easily in existing codebases. So if you decide on “Okay, I just want to have one React component written in ReScript”, we have dedicated – first of all, we have JSX syntax integrated in the language. This is a one-to-one equivalent thing. You can just use JSX in the language, without Babel and whatever. The compiler will compile it into equivalent React.createElement( ) calls, or in the new JSX API, what’s out there now… And then you just have this one React component, compile it to JavaScript, and then import it from other React components as if it would be a JavaScript component.

This partial integrations is one of our most interesting features, because people can first try it out and see if it fits their use cases. A lot of people are having – they cannot just rewrite their whole codebase. Nobody can do that. And with us, it’s like, okay, if you want to just try out one part of the application, and maybe it’s a very complicated part, and you’re like “Maybe this brings us some value, because we have very complex interactions” or maybe I’m building a code editor or a rich text editor, something with a lot of state and a lot of state transitions; maybe let’s try this with one React component that is written in ReScript and let’s see if it works. If it doesn’t work, if you do it correctly and you have always liked the JavaScript on the side to see the output, if you do it correctly, you can even after some time, when you decide this is not yours, you can just remove the ReScript files, check in the JavaScript source files, maybe rewrite it a little bit to make it a little bit cleaner, and you’re done. You don’t lose much in productivity there. And you’re also not forced to rewrite it again in your specific other language you want to use, or JavaScript. This is just the insurance from our side that you are not locked into the system if you don’t like it.

So let’s say I’m like Feross and I’m excited, I’m like “Hey, ReScript. Let’s give this thing a shot.” I know nothing about it, I write React-based web apps, and I’m at least interested enough to hop in and see what it’s all about. What do you tell folks? Where do they start? What should they avoid? etc.

Yeah, so the most important thing is we have everything on our website, ReScriptlang.org. We’ve hopefully structured the documentation in a way that it’s easy to follow. We usually recommend to start out with the manual, which is more written in a narrative style. So you start at the introduction, and you go through the installation, and then you can dive through the most basic features.

We didn’t mention the more advanced features yet on the manual, because we thought it would be easier for most users to just use the most basic stuff, and they can build all kinds of React apps with that. After you get some idea of the language, it is very important, because a lot of people are coming from a JavaScript background. They want to interact with existing JavaScript libraries. We’ve got a section there for interoperability for the external bindings I was talking about… So you need to get familiarized with “How do I bind to an ES6 module? How do I bind a value to a function that is exported from a CommonJS module, maybe the default export?” Or how do I map to a JavaScript class there? This is probably the first thing you should definitely check out, and at least try… Because a lot of people have this urge to jump into the ecosystem and look for existing ReScript bindings that bind to some JavaScript library, but this takes away a lot of learning possibilities. If you’re in control of writing your own bindings to externals, it’s much easier to do stuff, generally speaking.

As soon as you’ve got this, we also have a ReScript React documentation section, which covers actually all the basic concepts of React. We tried our best to also cover all the React topics, because oftentimes we just refer – like, some people refer users to the original resource, so “Go to reactjs.org, learn React, and then come back to our resource and learn ReScript React.” We don’t do that. So you can go from topic to topic there. How do I use JSX? How do I create elements? How do I mix them up with existing components and how do I export it to JavaScript so I can use it in JavaScript? From there on, it is usually recommended to just drop into your React codebase, run npm install ReScript in your dev dependencies, and set up a config file with Npx ReScript in it, and just point to the folder with your components. Then create your first ReScript file, write your first component, try it out, and wire it up in your existing JavaScript app, and that’s it. From there on, you can just play around with all the features and see if you like it.

It seems kind of like Swift in that way. When Apple was trying to encourage everybody to switch over to Swift, they had these larger decks of C codebases… And you could just sprinkle Swift in, file by file, or maybe even class by class; in this case maybe component by component. You’re like “Well, I’m gonna write this component in ReScript, and it’s gonna generate this nice-looking output.” Do you check that in the source code as well, or…?

That’s a really good point. Yeah, we actually recommend checking in the JavaScript output files, because – first of all, if you’re trying to bring new technology into your company, you need to convince your coworkers as well. And if they see – it’s a matter of politics as well. So you check in the source code, they can review ReScript code and their progress, and they can also see the equivalent JavaScript. Second of all, it’s also very useful to spot regressions if you’re doing some bindings and then you mess up a binding, and then suddenly the output changes. You see that as well, which is super-useful. But people will see the output and they’re like “Oh, I can understand that. This is not that scary.” And since ReScript is so fast, the compilation itself, it will also not have a heavy toll on your CI workflows, or on the consistency for your coworkers; if you check in the JavaScript source code, it’s already in there, so they don’t need to even run the ReScript compiler first. This has a lot of advantages, just bringing in the technology and make your coworkers like you afterwards.

[28:33] Now, what happens when they start editing the JavaScript output, not realizing what that .res file is? They’re just like “I changed this file and then you just recompiled right on top of my changes.” I guess that’s the magic of version control, you can always just go back in your Git history and dig that thing out.

Yeah. We also generate version headers, so it’s usually a warning on top that this is generated.

Yeah, very obviously generated.

But this is actually also a good point - if you’re on vacation and then someone needs to do a hotfix because something happened, even if they don’t know ReScript, they can still hotfix the JavaScript source until you’re back, and then you just fix the ReScript code.

I think that’s smart, because honestly, something like this is a very hard adoption, because it’s just so out there. It’s new. We’re gonna talk about people using it, and the association, and the fact that it’s not all that new, but… You know, nobody ever got fired for continuing to use React and JavaScript. But maybe for pulling ReScript in, if they didn’t have these paths for a) incremental adoption, which is component by component or file by file, and then b) actually having both versions right there, and the ability for people who don’t wanna touch ReScript, but have to hop in and fix a variable assignment or whatever the bug is - I feel like it really does make it less risky.

At the end of the day, if your team is like “We’re never gonna use this ReScript thing. Stop writing ReScript”, you have the JavaScript files right there; you just get rid of the ReScript files and it’s just some well-formatted JS that you just didn’t write by hand. So I think that’s a pretty cool thing for adoption.

Right. And I think one thing I didn’t even mention yet - because a lot of people like to do immutable JS, or this immutable data structure story… I kind of liked it in the beginning too, but then I realized that immutable data structures come with a cost. In ReScript we have a concept of zero cost interop, which means that we take a concept and translate it to idiomatic JavaScript without any runtime overhead. One of that is we have record types that compile to plain JavaScript objects. So they look like JavaScript objects, but they behave like immutable data structures. The optimizations for the immutable data structure so that it’s immutable is done during the compilation process and not during runtime.

This is also really great, we also have runtime-specific data structures built into the standard library. For instance, immutable lists; they’re also sometimes very useful. Those are compiled to also JavaScript objects, but with an [unintelligible 00:31:15.07] attribute. Very easy to check out on the playground, actually. If you try to use that, you’ll see straight away the output on the right side.

But we also have immutable data structures if you need it, and some of them are zero cost and default. This is also really, great to explain to someone why this might be useful… Because you cannot run into these weird issues where you try to use the object spread, and you think you’re immutable in JavaScript, and then suddenly you do some change in an object and you mutate it, and then you get side effects. This is super-annoying.

I’m still trying to wrap my brain around zero-cost, immutable data structures.

[31:59] So in practice, if I was using ReScript – just a totally random question, but I’m just thinking of what I would actually experience as someone who’s decided to introduce this into my project. When I use a dependency that I just found on npm, what’s the process for most packages that I would find in an npm search for bringing that into ReScript? Is it a lot of work to write the bindings and all that stuff? Doesn’t it have the same problem as TypeScript, where the definition files will get out of date or out of sync over time?

I’m gonna let Feross ask all the questions from here on out.

[laughs] Yeah, this is exactly what we are trying to figure out for the community as well. This is actually a philosophical problem - how do you make sure that all these npm dependencies, or these ReScript bindings to these libraries are always up to date? My current approach, my practical approach is you don’t try to write these bindings for the general community. It sounds a little bit weird.

For instance, if I’m trying to write bindings for the full JavaScript web API, when you think about how complex this thing is, the web API itself - it has nodes, and nodes are super polymorphic, and they can have a list of attributes, and these attributes don’t necessarily need to exist in certain values, and in certain situations they do… And in a static typed system like ReScript, which is also very simple - the type system is not as clever, or not trying to be as clever as TypeScript; in TypeScript you can have an integer, and an object, and a string being in one type. This is not really possible in ReScript. You need to think a little bit more simply. So you cannot really bind to a JavaScript function that accepts a string or an object or a number or whatever. So we need to make decisions. You can write a binding that binds to this function, but it only accepts one version of it. So it only accepts an object. And then you name this function [unintelligible 00:33:58.25] You give it a name that tells the user that this is the parameter. Then you have another one with integer, or something.

So there’s a lot of opinions into “How do I write these bindings?” and that’s why I recommend to learn the external syntax and just – you define it like a variable, basically. It’s like one line of code, you’re like “Oh, I want to map to the event DOM handler type”, or like one method of it; I just create one binding with this particular interface, and then use it.” Later on you can extract them into modules and just reuse them very easily. So you can either share them – I usually actually copy paste them around in some projects. If you’re really cautious about that and you want to share it in your different codebases and you want to make sure that it’s always up to sync, you can of course extract it into an npm package… But many of us actually don’t have that many ReScript codebases and it’s actually easier if you have it in-line, and then you can edit it as you need, and then later on publish it independently from that.

But this is more like this vendoring problem… So you can have N dependencies on npm, and those have another N dependencies, and then you’re like “Okay, how do I fix this one bug, which should be easy to fix, but then I need to go to five different maintainers to fix that?”

So my recommendation would be write them ad-hocly, and if you’ve got a collection of useful bindings that have practical proof, then it’s a good point to start sharing them with the community… Because some people start it, and then they get overwhelmed with how complex it is, and then they stop it. Then some people rely on that, and that is a problem. So we try to educate the people to really think about what they want to depend on, and if they need to depend on it.

So Patrick, if you were to meet some developers and interview them, and at the end of these interviews you could pick one to be like “This is the person that ReScript is for. This is our perfect user today”, what is that person like? Are they senior-level, are they experimental, are they building production apps? Are they in a large team, small team? Give us an idea of who should be adopting ReScript right now.

So our ideal developer is a product person; someone who wants to build nice-looking an performant products, and someone who’s not too pickery about paradigms, or dogmas we often have in the community, also in JavaScript or in Java or wherever. It shouldn’t be like a black/white thing, so people are not saying “Oh, I only want to do functional programming, and I only want to do object-oriented programming”, but they are more like “I want to build this (I don’t know) crypto wallet with this particular design” and are excited about it, and get their stuff done, in a timely manner as well.

Good answer. So if you’re that person out there – actually, Feross, you’re kind of that person, aren’t you? You’re a product person, you like to build stuff fast, and high-quality, and kind of in small teams, and you also work somewhat autonomously a lot. I think a lot of the difficulty is large teams, like “How do I introduce ReScript?” That’s why the incremental aspect is cool, because it’s hard to sell that to your boss when it’s going out on a limb for benefits, but how obvious and clear are those benefits. But you’re in a kind of position - and myself as well - where we can make the calls on the technology choices, and build cool products quickly and with high precision and high reliability, it sounds like.

What are the big wins for somebody like Feross? I know we’ve kind of touched on them, but if you could say like – I mean, zero bugs was nice… If it compiles… And no tests. Don’t worry about tests. It’s kind of like the TypeScript of as long as the types make sense… But there’s no any type, so you actually have to have types. All of my types are just any types, because I’m just a dynamic kind of a guy. But what would Feross win if he just picked up ReScript for his next startup or his next side project? What would he feel, what would he appreciate?

[39:48] I kind of feel like - because I’ve seen a few projects already that are out there, and I can also mention some companies later on - what I’ve seen there is that there are quite a few startups using it. And for them, it’s actually really good, because… I didn’t even mention that too much, but as I said, the type inference in ReScript is really good, so people can write their code without much fuss. They don’t need to annotate every single thing. They can just write down the code, try things out. If they don’t like it, delete the code again. But it’s not like the compiler always complaining about certain things, so they can move really quickly. Later on, when they start growing - they have legacy code, but they have a much easier time upgrading, because the platform is not moving as fast as for instance the JavaScript platform. JavaScript can be really churning when you think about it. The community is smaller, but more focused. We have a very nice forum where you get nice support, also by the core team members… It’s very easy to upgrade codebases later on, and stay up to date. You also can grow, because there is always – as I said, the compilation times scale linearly, so you don’t have to worry about later on doing this churny work of “Okay, I need to implement some caching, I need to put this into a separate package so I can compile it independently, and then the other one” - no, you just put everything in a monorepo, just compile it once, put it on CI, build it once; everything works just the way it worked with ten files, and now with a thousand files it doesn’t matter anymore.

So growing is much easier with that one… And this is probably my major observation. Also, bigger companies profit from that, because feature teams for instance can choose the technology, and if they need to integrate it in existing JavaScript codebase, they can do that as well. So all use cases are kind of covered here.

I was kind of joking about the whole testing thing, but is there a testing story, or is there tooling around testing? Or do you just say “Don’t worry about tests, because we’ve got you covered”?

Yeah, we – of course, testing is important. We tend to test business logic…

Because that would sell me, you know? Wouldn’t that sell you, Feross? It’s like, actually, tests - I know they have their value, but with our tool, with our language, just go ahead and forget about them. You’re not gonna need them.”

You always have to worry about what’s the normal, untyped JavaScript app, which is like “Do the two parts even connect together correctly? Did I rename the function in one place and I didn’t rename it in another place?” There’s no way to know until you run the app in production. So you need to have some integration tests. It sounds like with this you wouldn’t have that problem. With any kind of sound type system you would be able to just ditch those tests.

Yeah. Anytime you’re asking “Did this other part of my program send the right thing I’m expecting?” It fixes that problem. But like you said, any typed language does that. What I would love to do is not write any tests. Wouldn’t that be the ultimate productivity? Just write the code, and it’s gonna work. [laughs]

That would be the golden dream, right?

Yeah. So that would get me on ReScript right away. I’d be done with every other language. I’d be like, “Alright. No tests, no bugs, ever. Boom.”

Yeah. We definitely need testing, and we usually – we’re currently tinkering with very simplistic recommendation for testing… Because right now you can use Tape, or you can use Jest, or whatever… But we are not too fond of it, because it adds another layer of complexity again. When you add Jest, suddenly you have a lot of configuration again you don’t want to necessarily worry about… So what we are currently tinkering with is like a minimalistic test “framework”, which is like a hundred-lines file [unintelligible 00:43:51.26] code, and you drop it in your project and then you can just use that test framework, with the standard set of test functionality you usually expect, and just run it with Node. Just run a Node script, and you can run every test individually, like with tape, for instance. I really like this idea of reducing complexity on the tooling side, and we try our best to always follow this philosophy. So hopefully, the testing story will be as clean as the rest of the toolchain.

[44:26] Well, there’s lots of stuff here, and it’s worth pointing out it’s not Patrick just working on this, on your nights and weekends; this is a long-time effort by lots of people. As we mentioned at the top, different projects kind of came together, different people came together and created ReScript out of these other things that were all working together. The core team is seven folks, which is a pretty big core team. So there’s lots of people working on it. Tell us about the community. I know there’s also the ReScript Association, which is kind of like a foundation, like an entity that is building this thing… So flesh out the community story so that people who are thinking about giving it a shot know what all is there. It’s not somebody’s side project toy language that they wanna learn how to do a compiler in, so they built ReScript. It’s not like that; it’s serious business.

Yeah. So the original project started out in Bloomberg, where Hongbo Zhang, the author of the compiler started this whole effort. I think this was five years ago already; he started working on this until Facebook came out with ReasonML, and got the idea, and Cheng Lou got this really nice idea of making these two things work together, the Reason project and the BuckleScript project back then. Facebook and Bloomberg kind of collaborated on this thing until it grew a few years, and the community started to shape around it. We had a few startups in there, we had a few bigger plays in there; for instance, we had Sotheby’s, which is a bidding platform for expensive artwork, which is located in [unintelligible 00:46:09.22] I think… And we have companies like Draftbit, a startup which has an online editor for creating mobile apps, like a no-code tool with a lot of interactions and a lot of complex workflows. They’re really happy with that, of course. And Facebook, they have been using it in the Facebook Messenger app, on the web version, which is also fully written in ReScript.

One of our core team members is Ricky Vetter, who is also working on the Messenger team… So we’ve got the insights from that, as well.

We have companies like Ahrefs using it. They are a huge player in the SEO sector, for analyzing SEO data. There is Ubisoft Club, or Ubisoft Connect now; I think they rebranded. They use parts of ReScript in their React Native app. And there’s also some interesting companies, like in Japan, Elm Inc. - they built an app which is called [unintelligible 00:47:06.12] It’s a smartphone platform for the field triage of stroke patients. So when you think about these medics or paramedics currently in the field, and someone has a stroke, and they have a response app where they can ask for help, and ask for symptoms. This was very important that the app doesn’t crash. And for these use cases, where things should not crash, no matter how tricky it is, ReScript is really good, so these companies adopted it.

Or [unintelligible 00:47:37.12], which created an app for mission-critical railway safety. So when there’s a train passing down, like in Swiss or in France, passing down a red light, they stop the train and then they need to fill out this form, and there’s a very complex logic behind it. If you make a mistake, you can get in trouble, because there’s a train standing on the tracks, and if another train goes by, then you have–

You want that formula to work, is what you’re saying.

[48:07] Yeah, yeah, sure. And companies like TinyMCE - they are building a rich-text editor platform with ReScript, and for that it’s also fantastic. These really complex domains - this is where ReScript shines.

On the team, we’ve got, as I said, Hongbo Zhang, who is now also working for Facebook, Cristiano Calcagno, who is one of the cleverest scientists I know. He has been working on the Infer project, if you know that, for code analysis and static analysis of all kinds of languages. He has huge knowledge about analyzing code, which is great for us, because we have a lot of dead code elimination analysis going on right now for ReScript, because it’s fully typed. Super-nice to analyze.

We’ve got Cheng Lou, who has a huge vision on products, and designs, and lean, clean interfaces. I love that as well. Maxim Valcke, who is our master brain on the syntax level. He has been investing so much time into writing a syntax parser that is efficient and small. It’s super-fantastic work. And myself, of course, for working on the documentation; I’ve been doing this within the ReScript Association, as you already mentioned. The ReScript Association was founded with the goal to support the community and support a language with financial infrastructure, so people can send donations to it who are relying on the technology. So if you are a company who wants the language to succeed, the best way to invest money is to invest it in the association. They’re reallocating the money for developing the documentation, growing the editor tooling, working on core essential libraries, finding other projects, organizing conferences… We had like two conferences already - ReasonConf 2018 and 2019, and also a Reason conference in the U.S, which will most likely of course be rebranded to ReScriptConf.

So in the past 2,5 years we also collaborated with research institutes and companies, we collaborated with Ahrefs, which I already mentioned, with the Tezos cryptocurrency - they’re also really invested in this, because they want their crypto wallet apps to be stable, and they chose ReScript for their web frontends, and stuff like that. Or subsidiaries of Tezos, of course. Tezos is a huge project.

So this is how we try to set a foundation for the language on the community side, on the open source side, but also we have a strong commitment on the business side with the core team, who is working at Facebook, and all other companies that depend on it.

How about you personally? How are you paying the bills?

I’m getting funded, of course, with the work at the ReScript Association, but I’m also doing contracting right now… But I’m actually gonna start working together with another company who is using ReScript, which is [unintelligible 00:51:17.22] They’re building a sales-enabling platform, and I’m really excited about this… Building something neat.

Building cool stuff is always fun. How did you come to the project? We didn’t cover your personal journey to ReScript. What got you excited, what got you into it?

I don’t know, I started out in FlowType, basically. I was trying to contribute to the FlowType project, which is kind of the equivalent of DefinitelyTyped for Flow… And I tried to get involved with this work. This excited me, and Flow was a really nice project with the type inferences and such, but TypeScript kind of won this war, I would say, or the marketing… And I kind of felt disappointed, because I didn’t like the idea of TypeScript at all; the performance metrics, and stuff like this.

[52:10] In 2017 I got introduced to Reason, and I got really hyped up with the idea of having this polyglot platform, like having one language but it compiles to different things, and maybe you can have alternative syntaxes mixed in together… Which was the initial pitch I got in my head; but later on I got more involved in this, and started meetup groups, one in Vienna and one in Munich. And I also organized the first Reason conference in Vienna in 2018…

This kind of grew in me, and I was like “Okay, there is one thing that’s terribly missing in the Reason community, and that is a unified documentation platform.” Because every platform was one separate website, and it was really hard to figure out where to find what information, and define a user flow/funnel. So I started this project naively, I was like “Oh, I will just unify all the platforms into one website.” I did this for like 1,5 years, and at some point people started to like it because it was very useful. Then at the second time we said “Okay, maybe we should raise some funding for that” and we started to think about this ReScript Association thing. Then I got to know all the people, like Cristiano, who has been very supportive of our work, and he liked the ideas, and he introduced us to the team… And ever since we started growing. Then in 2020 we really started the new brand, and then said “Okay, we have this core team, and now I’m part of this.” I don’t like this idea of having a core team, but I think it’s important to have someone reliable for the technology you’re using… And if nobody feels reliable, why should you use this? That’s why I’m excited that I’m on there.

Pretty cool stuff. Feross, any other questions or thoughts from you before we call it a show?

No, I’m gonna try and find a nice simple project to give this a try on.

Yeah. Let me know how you like it.

That makes me wonder, are there good example apps or is there a version of the to-do MVC? Is there a real-world open source app that has a lot of frontend implementations? Is there anything like that, where folks can just poke around and look at a – not a complex ReScript thing, but maybe like a semi-complex one. Anything out there we can point folks to in the show notes?

Also, is there anyone who’s using it for specifically cryptography code? I’m just thinking the project that might make the most sense for me to try it on is a little cryptography module that we just open sourced for Wormhole. It’s not that many lines of code. It probably wouldn’t take too long to port it to a new language. That’s the kind of code too that you really want correctness on, and it’s worth the extra cost for maybe making it a little bit harder for a random contributor to contribute, but you get more correctness guarantees. I’m just curious.

[55:12] That’s a tough question I cannot answer, but maybe I can follow up later with that…

…because I have some ideas in mind, but I’m still not sure if – because some things are already existing, but they’re still in Reason syntax, and we don’t want to particularly point people to Reason resources, which doesn’t make any sense… Even though it’s the same compilation platform. The best real-world example app is ReScriptlang.org. It’s a Next.js app. Check it out.

So the playground as well?

Yeah, the playground is also written in ReScript. I’m not entirely proud of it, but it’s pretty damn stable. So that’s at least something.

That’s something to be proud of, yeah.

Yeah. And there are some open source apps… One is called Pupilfirst, but I’m still not sure if they’re still on Reason syntax, or if they already converted… Because we have this one command to convert the whole codebase and that’s it.

Well, why don’t you do this - hit us up with links afterwards, and we’ll put them in the show notes, if there are any ones that you would point to…

Absolutely.

…that way you don’t have to come up with them on the spot. And then – I mean, surely, Feross, the Tezos team is doing some aspect of that. I don’t know what exactly they’re using it for, but… They’re a cryptocurrency, but there also is cryptography involved. [laughs]

Yeah, yeah. That’s what I was thinking. It sounds like a great use for it.

Yeah, totally. I would definitely be interested in seeing the results of that conversion, Feross, if you ever end up doing it. I think it’d make a good blog post, or even just like tweeting out the links of the before or the after of that module would be pretty cool.

Are there any automatic tools to get you started most of the way? Something [unintelligible 00:56:51.15] from JavaScript.

No, there’s nothing like that. But we have an explicit section in the docs about converting a JavaScript file over in a few steps, because we can drop in raw JavaScript in a type-safe manner, or at least in a constrained manner; you should check it out… So you can take one expression or one function, drop it in as raw JavaScript.

Yeah, I did see that in your docs, to embed raw JavaScript… %%raw( ), and then everything inside the parentheses there is just raw JavaScript. So Feross, there’s your path to an easy port. You just wrap your entire module in that, and then you’re done. You’re in ReScript land.

Yeah. Well, listeners, links to all the things, even some things maybe not brought up, which Patrick has hooked us up with, will be in the show notes… SO check those out. Definitely keep up with Feross in case he does that port. He’s @feross on Twitter, maybe he’ll tweet about it… And check out rescript-lang.org as well.
I should mention that this episode was requested by a listener of the show, long-time Changelog member and a friend of ours, Brett Cannon, who also happens to be on the Python core team. So you have his interest. So there’s smart people who are interested in learning more about ReScript. Hopefully, this episode gave some people a start on a path down that way, at a very interesting language and toolkit and a view of making web apps.

That’s awesome… Patrick, thanks for joining me. Feross, thanks for hanging out. We appreciate it. That’s JS Party for today, we’ll talk to you next time.

Changelog

Our transcripts are open source on GitHub. Improvements are welcome. 💚

Player art
  0:00 / 0:00