Gabriel Nordeborn - Rescript
{/ TAB: SHOW NOTES /}
This week we talk to Gabriel Nordeborn, a core member of the Rescript team. Rescript is a langauge that compiles to JS but has some serious superpowers. Whether it is it's awesome pattern matching, or greate react integartoin there is a lot to love. Come learn about it with us.
{/ LINKS /}
{/ Paste show notes /}
{/ TAB: SECTIONS /}
[00:00:00] Introduction [00:02:38] First Project and Transition to Development [00:04:47] Discovering Rescript and Initial Impressions [00:11:09] Rescript vs TypeScript: Key Differences [00:22:56] Interoperability with JavaScript and TypeScript [00:25:21] The Art of Writing Bindings in Rescript [00:28:37] Tools and Integration with JavaScript Ecosystem [00:32:43] Rescript's First-Class Support for React and JSX [00:40:54] Exciting Features in Rescript Version 12 [00:43:55] Future Vision for Rescript and AI Integration [00:47:33] Conclusion and Final Thoughts
{/ TAB: TRANSCRIPT /}
[00:00:00] Introduction
Gabriel: So the philosophy is kind of that with a few very sharp tools you can get really far. And, um, we want to things to be simple, like to stay simple, simple data structures, simple types.
Not too much magic, essentially because we believe that makes things more maintainable, more approachable.
โ
Andrew: Hello, welcome to Dev Tools fm. This is a podcast about developer tools and the people who make 'em. I'm Andrew, and this is my co-host Justin.
Justin: Hey everyone, uh, we're really excited to have Gabriel Nordboe on with us. Uh, Gabriel, you work on, uh, the Rescript team. Uh, and rescript is the language I've had my eye on for a long time. It looks really awesome. Um, so it's like a. Purely functional, like strongly typed language that has a more of a sound type system than TypeScript has.
Uh, but it like compiles to JavaScript. Um, so I'm really excited to dig in and talk more about that. But before we do, uh, we'd like to hear a little bit more about you. So would you like to tell our listeners a little bit more about yourself?
Gabriel: Sure, of course. Hey, everyone waving for those on the audio podcast. Uh, my name is Gabriel. I am, um, out of, uh, uh, Stockholm, Sweden. Uh, I got two kids living here. I've been involved with, uh, rescript, uh, language itself for maybe three years or so now. Uh, and I've been working as, um, I've been a software developer for.
Well over a decade. Um, but originally I'm actually a behavioral scientist, so I studied a bunch of psychology in, in university. Uh, so that's where I kind of, uh, got into this and then I fell into the, the, the programming stuff as well. I've always been, been doing a bunch of programming when I was little, like back when, back when CSS was actual attributes on the dom nodes only?
No, like actual style sheets. And those things when guest books in PHP and my esquela was the big thing like that, that's when I. I had my, my, my starch in programming, so to speak. And then, then I tried to avoid going down the engineering route just because I didn't wanna get stuck by the computer for the rest of my life.
Uh, and it worked out really well throughout university. I did the psychology stuff and then, uh, when I we're almost done with university and I had to do like my master's thesis, uh, I slipped back in kind of, I did a web-based experiment, uh, and then. I ended up getting a job as a developer, and then that's the kind of where that comes from.
I, I've always been very interested in and involved in open source. That's very important to me, um, and something I value highly. Even before I did development, I was, uh, I was very interested in open source and using lots of open source software, helping out, like debugging and stack traces and whatnot.
[00:02:38] First Project and Transition to Development
Andrew: So was that first project kind of like the intersection of your degree in programming or was it just like some
Gabriel: No, it was a really, like a really weird, um, experiment. I, uh, I wanted to, there, there's like, there's, um, there's some, there's like color psychology, uh, a, a small, small, small branch of psychology with not lots of research in it. Uh, but there's a bunch of like, theory around colors and how colors can affect us and how that's like culturally bound.
Uh, so I did an experiment where I set up a. A WordPress site that kind of mimics a, um, a, uh, medical information site. And then I had my cousin who's a, like, um, a researcher for medicine. I had him make up a disease and then put that, that disease somewhere in, in the, the website. And then people had to find information about the disease, uh, ingested kind of, and answer questions.
And then the manipulation was. Three different color schemes. Uh, so did that affect the, the speed of, and the level of comprehension and those types of things? Um. Didn't really affect that. Like there was a small, like, uh, three-way interaction between like being a male and the red, um, color theme, which, uh, may had a, an impact that was, uh, like people were slightly slower on the red theme.
And then you could fear exercise a bunch of, oh, that's because back in the stone age when, uh, when your enemy got angry on you, like they had a red face, and that makes you scared and comprehension goes, yeah, you, you get the point.
Andrew: Yeah, that, that's interesting. I, I feel like Blue might have some, some association there, but there has to be a reason that every company uses Blue.
Gabriel: So blue is, blue is really like, that's soothing and, and, uh, calming and those, but apparently it's different in, in, uh, eastern cultures compared to western cultures. Red is more soothing there, apparently. Uh, so it's, yeah. Interesting. Uh, yeah. Thing, but when I, when I did that, uh, and after I did that and I came out to the, trying to get a job, turned out that this was back in.
2014 or so. Um, there was like two jobs in Sweden for behavioral scientists and 2000 jobs for developers. So I kind of, that was the logical, the logical choice. So I'm here at the computer for the rest of my life anyway, but I guess I gave it a shot at least.
Justin: So how did that lead you?
[00:04:47] Discovering Rescript and Initial Impressions
Justin: Like where in your journey did, uh, or what led you to discovering rescript?
Gabriel: I got started with PHP, uh, that was my base, uh, starting out. And then as all the things I've come to then love. I hate them at the first site. So, uh, we were doing lots of client work. I worked at a web agency, uh, and, uh, sometimes needed more interactive stuff than you could deliver with just service side rendering.
So like natural thing, uh, JavaScript, right? Uh, and back then, this was just when React had came out, essentially. It was still the very, like the new thing on the block. Angular one was the big thing, backbone. Those, uh, old frameworks. a colleague of mine showed me react. I instantly hated it. Uh, looked terrible.
Why would you do, I think I. Specifically said, like, why would you ever do anything with JavaScript if you just have PHP and the server, right? You have, you have your query, PS you can just re-render. Right? Um, but we had a couple of requirements which made that we, we had to use that. And so kind of got into it.
I, I, uh, warmed up to it. Uh, and then eventually, since I like to kind of think about these things and analyze, eventually I saw flow back, back when that was. Back when, um, that was the hot thing before TypeScript when TypeScript was a thing, but wasn't really that hot. This has actually, like, this time has actually existed.
Not, not a lot of like looking at the graphs now. You wouldn't believe that. But this was back, like flow was a hot, interesting, uh, Facebook project. Facebook had a massive kind of, um. Had a massive, um, momentum going with React and, uh, all of the open source stuff they did. Uh, so I looked into Flow, uh, saw that wow, there's a, there's a way to, um, discover bugs and issues before we ship it to the clients.
Excellent. I didn't have a background in any of the type languages in that sense. I've done a little bit of like c and stuff, but yeah, it doesn't really count. Um. So I thought flow was really interesting. Um, uh, and then I eventually also of course got into, uh, TypeScript. Uh, but we used Flow a lot, used TypeScript a lot, but it was always like, I was always looking for more, so to speak, in terms of, uh, type safety, uh, and those, and then back then in this was maybe 2018, the first time I, I saw this, uh, recent ML was a thing and B script.
Uh, so I, I kind of, uh, slipped into that, landed all that. And quickly realized that this is what I would like flow or TypeScript to become, for me to be happy with it. Well, maybe not. I mean, it wasn't perfect back then. Neither is it now, but still like, uh, if you compare it to the goals of Flow or TypeScript and the goals of recent backer script, um, back then.
That, that was much more what I was interested in, like as soundness in the type system, uh, the inference clear like, um, data structures, uh, that's easy to work with the mutability and not like I'm not at all, um, uh, hardcore functional programming enthusiast in that sense. I am, I'm very much a. Pragmatist, like I wanna do stuff that I, that works, uh, that I feel like works and, and, and that I can kind of prove over the long, long run works.
And, um, a type system that is sound that you can trust with, um, nominal types instead of structural types, uh, and those types of things in places where it matters. That just resonated with me very much, so I started getting into that. Uh, so that's kind of how I, how I got into that. Um. From the beginning, essentially.
Andrew: Cool. Well, we're, we're big fans of TypeScript on the podcast. I'm literally wearing a TypeScript sweatshirt right now. Uh, we sell it at Shop Dev Tools fm. Uh, but, uh, one of the features of TypeScript that I've come to love that a lot of people hate is like. It's a powerful type system, but you can like throw it out.
So I guess in a sense that I love the un soundness in some, in some places where I can like be the arbiter of my own destiny, even if the types don't quite work out. Uh, what does a sound type system mean in practice?
Gabriel: So in practice, a sound type system means that if it compiles, it works like the, if, um, this is true for the internal things, like, so like if you compile a program. Uh, the compiler guarantees that the code you've written works in the way you've written it, the way it's like outlined, so to speak. Then of course, you have the edges, so to speak, like values that come in from the outside.
You have to type them. The right way or handle them the right way. 'cause those are, yeah, things can slip in. But, um, if you have a program that's written only in risk script, for instance, and it compiles, it works according to what you've written, so to speak. That's the, uh, the g the, the, the guarantee of, uh, a sound type system.
Um, and again, like it's interesting that you with ness, um. And, um, I think we, we probably think more, more alike than you would imagine. Even though I, I go for the like, sound type system stuff. Uh, I'm not really, I am, I find type systems fascinating and fun, but I'm only interested in what it gives me in practice and what a sound type system gives me in practice is that I can trust that the things I write, the things I ship.
Will work according to the way I've written them. I can do refactors easily, but all like, the biggest thing for me is if I do a quick change in a massive application, it compiles. I trust that this is gonna work. I trust that this is, hasn't accidentally broken things. Outside of like behavioral, of course stuff, but, uh, this hasn't broken anything anywhere.
And I can also trust that the compiler's gonna guide me to handle all of the cases I need to handle. So, for instance, in ReSCript, um, everything is exhaustively shipped for you, uh, by default, which means that the compiler will make sure that you handle all of the cases. That you are supposed to handle for this to work in all of the branches you have, essentially.
So, um, if you have anum for instance, and you, you wanna do something with thatum, risk Script will make sure that you handle all of the possible cases of Thatum. Unless you explicit tell it, tell it explicitly, tell it that you're not going to essentially, and there's a massive productivity gain for me from that.
So looking back, I think like what you described, you can just opt out whenever you want to to get the productivity gains. I feel the exact same way, just that I do it through the I, I get my productivity gains in another kind of area, so to speak. Um. But then, then there's a whole category of of program languages and, and, and programmers that care deeply about, uh, that it's sound for the sake of being sound.
And I'm not one of those in that sense. Like that's not really what interests me. That's cool if that's the case, but I'm interested in the, the productivity it, it gives me and the guarantees it gives me.
Justin: Let's take a step back real quick.
[00:11:09] Rescript vs TypeScript: Key Differences
Justin: Talk about, uh, rescript more generally. So rescript is a programming language that compiles the JavaScript and it has a sound type system. Uh, what else would you say about it?
Gabriel: Uh, so Rescript is, uh, it's a programming language that's focused, uh, I would say it's focused on the web. Um, it's focused on, uh. Simplicity and speed. Like speed is a core feature. It's something we care deeply about, that we have a fast compiler, that we have a fast feedback loop in the editor, that we have a fast feedback loop wherever there's an interaction with, uh, the language itself.
Uh, we care deeply about simplicity. Um, the way I usually describe it is if you wanna like, contrast it to, to TypeScript. TypeScript, um. Wants to type the JavaScript you've already written or the JavaScript that you write, you're writing JavaScript and it, it wants to type essentially everything in JavaScript, right?
Uh, and it does it really well. So like, type script is. Fantastic at what it does. It's a, an amazing type system, an amazing like feat of engineering overall. Um, it tries to type, uh, all of, all of JavaScript and all of JavaScript has grown over the years to be a pretty massive shed of tools. Right. Um, can't really clean it up too much because you'd break a lot of the web.
Which is you don't want to, right? You can evolve the language. Uh, TC 39 is evolving the language, uh, but evolution is kind of slow and still, like there's a massive amount of features. There's a massive amount of ways of doing things. So imagine there's a shed of many, many tools. Some of those tools are really sharp, are really good, really well thought through a lot of the, those tools are.
Not that sharp doesn't fit that well together, or there's four or five different tools that do the same thing from different generations in a tool, like in a product line and so on. Um, ReScripts philosophy and idea is that if you open the Rescript tool, shed. You'll try and like where, where's all the stuff?
Like you look around and, and, and try and find all of the tools. But the, the point is to have, we want to have few tools but that are really sharp and work very well together essentially. So the philosophy is kind of that with a few very sharp tools you can get really far. And, um, we want to things to be simple, like to stay simple, simple data structures, simple types.
Not too much magic, essentially because we believe that makes things more maintainable, more approachable. Yeah. And all of those things, it's uh, it's that philosophy essentially.
Andrew: Um, so I was reading, oh, go ahead.
Justin: go ahead. No, take it.
Andrew: Okay. Uh, so I was reading through the docs and, uh, one of like the differences with TypeScript that it lists is that, uh, as you said, TypeScript, Ty tries to type the entire Java script like API, which is kind of crazy. There's lots of stuff that can happen, uh, just even the way they're able to like.
Know that code paths have certain values available and types have happened. Crazy stuff is happening there. Uh, on, but on the homepage, you, you guys say that you only do a subset of JavaScript. Uh, so in practice, like what does that mean? Like, what don't I have available to me? Like what programming constructs do I go to instead of other ones?
Gabriel: pl there's plenty of stuff you don't have available to, uh, so to speak. So, so one, uh, classes is the, the main thing maybe in, in rescript, like you can get a dev development workflow. Um. That's very similar to the ergonomics of classes and methods and those things, but you don't have actual classes in the language, you don't have in inheritance.
Those things is functional in that sense. Like we encourage you to, um, write functions that operate on data and that you can change together and those things. So like, um. That's, that's one example. Uh, there's plenty of others. Uh, like the, again, like the JavaScript API is is massive. We don't have generators, for instance, generator functions, although we're kind of interested in, in getting them.
But essentially when, when we look at what, what things to bring in to rescript from JavaScript, we want them to work well with what. We already have. So the core kind of features of the language, for instance, variants, records matching those things we want them to like, should work really well with them.
It should also add something because we, we view all of the, like adding something to the language is a huge cost in that you're giving people another tool that they. May or may not use, but it can create confusion around should I use this for this or that for that, and so on. So we want it to be as simple as possible.
So the bar for adding new stuff is kind of high, but we also wanna stay close to what, what, uh, JavaScript developers typically want to use. Um, so one example is asynchronous programming. We. Could have probably come up with a bunch of other, uh, ways of doing this than the native JavaScript way. Uh, there's tons of priority in both our kind of, uh, mother language OCaml, but also in, in other languages, uh, for how to do asynchronous and concurrency in those things.
But we opt to. Build Asin Kuwait into the language, just like it works in JavaScript just because it's familiar. It's something that's virtually everywhere in the JavaScript ecosystem. And it has some kind of interesting, it gets some, some interesting traits in Cript that makes it, um, more ergonomic, I would say, if I dare, than in, in JavaScript than, and TypeScript, so to speak.
Um, which are kinda interesting. It's a, it's a, it's a, a good example of when. Bringing something in and making it work well with the, the existing language yields a good kind of synergy, uh, effect, uh, so to speak. So, so for like, for async weight, the specifically it's in rescript. Everything is an expression, which means that, um, if you've ever, uh, done a React component and.
Your two layers of divs in, and you wanna write an if and you can't because it's not, you can't write expressions in the middle of jsx. Uh, you have to write the ary or some other, um, make it a function computed before or, yeah. Everyone has, has felt this, uh, in cript everything is an expression. You can put an if or whatever you want, a block of code wherever you want, essentially.
And what's, what's great about this, it sounds, doesn't sound. Much, um, just from the get go. But what's great about this is that it allows you to co-locate your logic where it's supposed to be. So if you're forced to break something out to a function when it doesn't, it's only really for this place you have, you're forced to do an immediately invoked function or a nested turnery of five levels or whatever.
Like if you're forced to do those things, you're doing them because of a. Limitation in quotes, um, of the programming language, not because that's what you want to do. And expressions everywhere is a, um, a very nice thing that lets you put code where it belongs. And for async weight. in risk of the, the big thing is a switch, essentially, like, it, it lets you pattern match on anything.
Uh, so it's like the switch in JavaScript but on steroids is usually what we say. So you have a switch and then you can switch on virtually any data structure and the compiler will make sure that you handle all of the possible cases for this data structure. And you can also switch on an a weight, uh, so you can switch a weight and something happens, and then you can pattern match on that promise, throwing or failing, rejecting. On it succeeding. So you can get kind of this nicely boxed in error handling. That's very succinct. It's, it's, uh, it's literally one extra line and it compiles to the regular, you know, the try catch, uh, and then have your, define your variable above in the scope and assign it or use of r if you're that kind of person.
Uh, and then, uh, yeah, you, you have your try catch and find on those things, but. Uh, you, it lets you integrate this right into the code where it matters, so to speak. So you're not, you don't have to do this ceremony of writing a tri catch, even though that's not really what you were after, so to speak. So that's a, a, a good example of when a feature from JavaScript blends very well into the, the, the core features of the language.
Uh, and that's the kind of things we try and find. Like, so when we, when we bring in new stuff, which like, again, like. There's the high bar, but of course we want to, we want people to be as productive as they can be with JavaScript through Rescript. Uh, so we wanna bring in stuff from JavaScript as well. Um, but there's a high bar, but when we do it, it's, it's important that it works really well with the rest of the language.
Justin: Yeah. The, the Await, the switch weight thing is really nice because I think one of the problems I have with Asing a weight is. Many people just don't do air handling. It's just like they only code for the happy path. Uh, because it's like kind of annoying a little bit and you see like a lot of libraries that come out that there's, there's one that I'd used for a long time that you essentially like wrap whatever, you're gonna await and await that thing and then it'll like return, uh, two pull essentially like.
Array with like two items. One could be the success case and one could be their case, and then that like messes up the like type inference and a bunch of other stuff. So it's like, I don't know, it's, it's nice and. I, I would go further to say there's like so many niceties just because it's like a functional language.
You had mentioned pattern matching earlier, like proper pattern matching. So good. I use ts pattern a lot in TypeScript projects, but you know, it's unfortunate that that's runtime. Uh, cost that you have to pay. And then, uh, proper like variant enums, uh, kind of like Rust has, it's like that's missing from TypeScript, JavaScript world.
The, the pipe operator, which we've been talking about in JavaScript for a long time, but like can't collectively agree on like how we want it to work. Uh,
Gabriel: It's, um, yeah, like pattern matching is probably the, the thing that when people, uh, go into rescript and then go back out of it, what that they miss the most just because it's, uh, it solves so many problems and quite elegantly as well. Like, and it's again, like, uh, you can emulate this well in TypeScript, I would say, like this pattern for instance.
Very cool. There's a bunch of other Panama libraries, but it's runtime. It's not first class in the language. Um. Um, in rescript, it compiles to really efficient JavaScript as well. Uh, it compiles to what you'd wr write by hand if you had to optimize it, which is a bunch of ifs, essentially, but you don't wanna look at that.
You wanna look at the nice, the nice switch instead. Um, but's, uh, one, one, um, thing about, um, switch weight on those things. Uh, one other, um, really good thing with having a sound type system is that you can do. Very much with statical analysis or static analysis, um, around your program. So one example is we have a tool called Reanalyze in Rescript that can go through your entire program and figure out exactly, for instance, say you have a variant case or you have a a record, it can figure out that this record field is never read.
It's constructed, but you never read it. For instance, it can figure out that it's never read nor, uh, written to or created. Um. And going back to, uh, async Await and error handling, it can also actually figure out that here's a promise that could reject, but we haven't handled the rejection, the possible rejection.
So it can kind of do that type of linting for you. And it's a whole program thing and it's also very fast. So it's, um, it's something I use all the time and, and one of the things I perhaps miss. Miss. One of the things I miss the most, I would say when I do TypeScript stuff, because I still do a lot of TypeScript stuff.
Um, um, and, um, being able to. reanalyze and have it analyze the code base and tell me what things are dead code. So like across the entire program, what things am I not using and down to the field level. Um, that is, uh, for me, who do a lot of work in big code bases, uh, of various, um, kinds, being able to.
Reliably clean up old code is, is actually one of the biggest wins for me with the sound type system. Um, just because otherwise, you know how it's like, uh, old experiments, things lie around. New person comes in, they browse the code base, they're supposed to find information about something. AI nowadays also, like the agent browses their code base, tries to figure out information, goes through a bunch of code that's really dead or old or in another convention or yeah, whatever, um, that should be removed essentially.
Outside of the obvious like gains of compilation speed and bundle size and all those things. So that's, um, that's something I really, that's a benefit of the soundness that you can do that with the type system.
[00:22:56] Interoperability with JavaScript and TypeScript
Justin: Speaking of soundness, you, you mentioned, um. You mentioned like there are types on the edge of the system that you have to like define to sort of like, and that's your, your like barrier of selling this, right? Like things outside of the rescript code or, and sound and type script has this same problem, right?
They have to. Define type definitions for everything. And like famously TypeScript has now, at this point in 2025, just a ton of type definitions for everything. Just about, you know, definitely typed is, uh, has a ton of types in it, but there are, like most libraries these days, it seems like they ship their own TypeScript types.
So when you think about like. Rescripts interrupt with the rest of the JavaScript ecosystem or like defining types for outside things. It's like what is the, what is the story around that?
Gabriel: So, um, I would say this is, this is definitely one of the, the points of the language where we have. A lot more work to do, or rather in the ecosystem, I would say. So, uh, in rescript interrupting with JavaScript or TypeScript, um, you write bindings, which essentially are ways of describing that. If you call this function in JavaScript, you're supposed to expect these parameters, it returns this thing, um, and so on.
It's a description of, of, of what outside world looks like. Um, and then, um. You get access to those functions in rescript and they admit the JavaScript is just what you'd expect, like the calls for, for JavaScript. The the big issues that we have around this is that. While Cript and, and JavaScript has a lot of similarities, there are also a bunch of things that you do in rescript, uh, in TypeScript and, and JavaScript that you don't do in rescript or can't do in rescript, so to speak.
Overloads is an example. Rescript doesn't have a concept of overloads, um, which is something I've really come to kind of, um, appreciate in the sense that it's very clear like exactly what things can do. Um, but it also means that, uh, you can't one-to-one express. A type script with, uh, code, with, with overloads in rescript without breaking out each overload to its own kind of function binding.
Um, so there are like differences in, in the type systems that make, make, uh, because what people come, uh, come to always is can't you? Build a tool that automatically generates rescript from TypeScript. Uh, and back before all of the TypeScript research, the, this was something that people were exploring, uh, but the results were never really satisfactory because of both the fact that it's, it's quite different.
Type systems. Um, but also that writing the bindings is, is kind of an art, so to speak.
[00:25:21] The Art of Writing Bindings in Rescript
Gabriel: Like you usually, when you, uh, when you use, um, a library, uh, you're, you're very seldom using all of it. So. Most often you're using a small part of it, um, and you wanna use it in your specific way. And there's a bunch of ways to write bindings in, in rescript that lets you kind of tailor the a PIA bit in how it looks.
So like you can have, you can inject default values for arguments, for instance. So one, one classical example is the read file in KPI of of node, um, or read file for that matter. Doesn't have to be the sync version, but that takes, um, a iPath and then, um, you can pass the string of the encoding, right? Uh, then coatings in most cases is going to be U TF eight.
Uh, so you can create a binding in rescript that has a default value of UT F eight string for the options, uh, parameter. So you never have have to write UTF eight in rescript, but the emitted JavaScript. Always has UTF eight, but it's not wrapped in another function. So it's not an actual, um, it's not a, um, a wrapping on top of the, the node API, it's, it's built into the binding itself.
So that's, so like writing bindings is kind of an arch, uh, so to speak. But then we have also going the other way. Going from using rescript code from TypeScript. And luckily there we have a bunch of nice stuff in Cript. Uh, we have a tool called Gen Type, uh, which can you just annotate your types and, um, rescript functions and values.
And then a TypeScript file for each RESCRIPT module gets generated with all of the types. In TypeScript, but translated from rescript so you can easily use them. Um, but this like the, the binding space is, is, is, uh, is of course a, a big problem. It's, and stems mostly from, I would say, from us being a small community.
So definitely type nowadays it has everything and then some. But back in the day when TypeScript was. Fighting it out with flow essentially. It also had a bunch of things, but most were ubs, right? The same with flow, flow type then and all those things. So we're kind of at that stage now where, um, if I'll say when we grow, uh, when we grow, uh, a lot, there's gonna be quality bindings.
But it's also a, a, a thing where I think people overestimate how much they. Use libraries and how much time they would spend writing the bindings for those libraries. But it's a thing where, where it's um, it's hard to say anything else than this is a, this is a problem. Essentially AI is gonna help some, like teaching the AI to write good bindings helps.
We're also experimenting with, um, so like rescript can emit TypeScript as an inter layer. So you can call rescript code type safely from TypeScript. But we're also experimenting with, okay, so can we have. Rescript, a compiler or gen type, uh, the tool. Can we have that emit a file that just checks that the bindings you've written would work with the TypeScript types of that library, so to speak.
So like if I have this binding for, um. Yeah, we'll say React for instance, for use Memo or whatever, if the, is this function signature of the binding I've written, is that compatible with the use memo from the React Types package, um, so to speak? So we're doing a bunch of exploration around how we can improve the situation because it is, it is a, it is a problem.
Um, if you're in the blessed path. Like you, you come in and you, you work with React, for instance, where we have great bindings and a bunch of other libraries where we have great bindings then. You are pretty much set. Like it's, it's going to be fine, but if you need to wander off yourself into writing bindings it, it can be kind of daunting.
[00:28:37] Tools and Integration with JavaScript Ecosystem
Andrew: So code is just the tip of the iceberg when it comes to the JavaScript world. Uh, for better or worse, we have lots and lots of tooling. We have linting testing tools, bundling tools, build tools, all different types of tools. What's the story for rescript integrating with those? Does it like, take, uh, boil the ocean view of it and kind of like do it all for you?
Or is it interoperable with like the common tools we use today?
Gabriel: Yeah. So, um, one of the goals of cript is to integrate as cleanly as possible into the JavaScript world. Uh, so this means, for instance, you use. PM or pmpm or whatever you want to use, uh, but you use a, um, the JavaScript ecosystem for packaging, for instance, you use the b like the same vendors that what what Cript does is for each CRIPT file, it'll emit a JavaScript file, uh, that looks.
As handwritten as we can make it look essentially like it, it's supposed to look roughly as what you'd write by hand, uh, in JavaScript. So, uh, our goal is to integrate like thinly into all of those things. Your bundlers linting, of course, is, is, is a thing where it makes more sense to kind of do it in, in, um, rescript itself to LinkedIn Rescript.
We also, like LinkedIn is another topic, uh, but basically like, um, we don't have that many linters because we have such a tight. Type system. We have a couple of like com compiler warnings and stuff, so we haven't really seen the the need for that, but you could link the, and I know people do like, you could link the JavaScript output people use the React hook links.
For instance, we did a bunch of work in, we have a version 12 that's coming up here soon. We have done a bunch of work for making sure that the rescript output can work with a React compiler, for instance, efficiently. Uh, all of those things that comes with tr uh, having a goal of interrupting as clean as possible with, with JavaScript.
Andrew: Yeah, that I, I, I was gonna ask that when we got to the React section, if it integrated with like, kind of the bleeding edge tooling of the React ecosystem, that's, that's super cool that you can run stuff on the output. And like it's good enough output that you can like translate that back to the, the rescript code.
Gabriel: Yeah.
Andrew: Justin, you wanna.
Justin: Typically this is, this is a, this is a bit of an aside, but do you typically like check in the JavaScript code?
Gabriel: Uh, I, I don't actually, but I've, that's, it's, uh, it's kind of a, a problem. Like we, we usually recommend you to check it in. I find it a bit noisy. Uh, but I've been, been working actually quite recently on, okay, so if we don't check in our code, how, how do we make sure we don't. accidental behavioral changes.
'cause imagine like, go back to this thing with, oh, we have a sound type system. I make changes, it compiles, um, I can trust it. Right? So that's good. But there's another layer in risk script, which is to emit the JavaScript. So what if there are changes in. They made the JavaScript that I wasn't anticipating now, like the com the compiler is very well tested and everything, so I mean, it's, it's not, you can trust output, but still, like when you do refactor, when you do bindings, when you do upgrade versions of the compiler or other versions of libraries, and it came kind of nice to, to just scroll through the actual like JavaScript changes also, like when you do a refactor that's purely on the type level or, or something like that, you restructure things work.
It's kind of nice to. When, when it compiles and you also see that there are no changes in the actual JavaScript, then it's gonna work, right? It's not gonna be any behavioral changes because the, the generated JavaScript is the only thing that matters to the end, end user because that's what, what gets run.
So, um, well I've been exploring building a, a sort of a diff tool for that. So you could have a CI action that always gives you a, um, A-H-T-M-L diff page. You can scroll through for that. Um. It's also interesting to do that type of diffing of the code you've made purely at the type level. So we could have a, that's for like, for generated JavaScript, you diff the generated JavaScript for the type level.
You could have a diff that just shows how the type signatures or the type output of all files have changed, so to speak, so that you haven't also accidentally made any changes, uh, that you, you weren't anticipating. And for us, uh, a goal is also that all of these things should be easy to. Plug in an AI that can do, for instance, so an AI could audit your generated JS changes or your type changes or whatever.
Like it's, it's always in the, kind of, nowadays, it's always in the, in the, the back of the head that it's supposed to work well with that as well.
Justin: Makes a lot of sense. Uh, yeah.
[00:32:43] Rescript's First-Class Support for React and JSX
Justin: So let's all, let's kind of switch gears and talk about React a little bit. Um, so re Skip has first class support for React. And I guess when we talk about React, we also like have to talk about JSX, which is like a language feature as much as anything else. So how do you handle, uh, react and like, what does GSX look like inside of Free Script?
Gabriel: So, um, JSX, we will start on that end. Uh, JSX is a first class feature of the language, which means that it's, uh, integrated into the actual parser. There's, it's an actual, like JSX nodes are actual a ST nodes in the compiler. Um, and so it's a first class kind of thing. Uh, everything works. With JSX, uh, then we have React of course, which is where we've put, um, especially historically, have put all of our efforts, so to speak.
We're very much trying to make one use case work really well, and then we try and move on to the next thing. And React has been, of course, with React popularity and, uh, the roots of the project React has been huge. Uh, so I would say we have, um. Very good React, support, uh, it's something we care a lot about.
It's an officially maintained, a package maintained officially by us, the, the, the core team. Um, but we've recently also started working a lot on, um, Trying to make other frameworks that work differently, work well as well inside of, um, rescript. So we've been eyeing solid js, for instance, uh, Preact, but that's kind of cheating because it's, it's still kind of react.
Um, but also other use cases because JS Jsx is kind of cool, uh, and especially when you have all of these. Nice features around pattern matching and, and, uh, and those things. You can do a lot of cool things. So I, for instance, I've built a framework that's, um, based on bond that's purely server side, but that has, like, you write components, just like you'd write your, your regular app.
Uh, there you write, uh, jsx components, uh, you render them, you have context. You just don't have the client side stuff. You don't have use states and everything. And what, uh, that JSX. Looks and works exactly like the JSX, you'd write in rescript for React, but in the end it gets compiled and down to calls to a framework called Hyper Ons, which is a small, small framework that just emits, uh, produces HTML from from, from jsx.
Um, so given that it's first class and you nowadays can switch out, react from to, to your own thing or another library, um. It opens up some, some pretty interesting use cases, I would say. Um, but yeah, historically react has been the, the main focus. Um, and there are a few things in. Like React lends itself really well to a language like Cript because of a couple of things.
First, of course, the, the thing I talked about before, expressions everywhere, switches and stuff. But also something as simple as prop drilling. That's not really an issue in Cript because you have the inference. So you never have to, unless you want to, you never have to annotate the prop. You can al always like, let the inference deal with all the problems, and that's a huge. For me at least, been historically a huge source of friction. Otherwise, that, that makes you kind of skip doing a few things because it's annoying to have to type it all of the way, the way through, uh, essentially. So, uh, I would say that's one of the big, big kind of benefits of, um, of a language like Cript and, and, uh, jsx and react together.
Andrew: It is, it's interesting how when you make JSXA language FE feature and kind of factor it out of React, like the way I think about React and what it is and what it's doing in my application, like almost completely changes. Uh, and it's really cool that you can use that for other things just like you basically created your own little.
Framework, uh, with not too many bells and whistles.
Gabriel: yeah. And JSX can be molded to, I mean. Of the web is still like XML based in, in most, most ways. Like, so, um, you can use it to just like other people do in, in the TypeScript world of course, like, but you can use it to emit, uh, XML or CV or whatever. Like, uh, it's just function calls at the end of the day, right?
So it's just a nice format for those function calls and, and structuring them, um, in a nice way. So it's, um. Yeah, it's, uh, I like, I, of course, like, like I said before, I, I absolutely hated Jsx when I saw it first, but I really, really, really like it now, and I have been liking it since, since a couple of weeks after hating it So,
Andrew: Yeah, I, I found that that trend in my life as well, especially like with music, I'll like hear something and have almost a visceral reaction to it, like, that's bad. And then it gets stuck in my head and then lo and behold, that's like one of my favorite artists a year
Gabriel: Yeah. And then the shame, right? Like you have to, you have to admit to No, I, I didn't say I didn't like this. No, no. You,
you mis must have misheard. Yeah.
Andrew: Uh, so react for around 18 versions was kind of the same, uh, react 19, I feel kind of, it threw, it, threw a lot of that out and became very different. You guys list that you support like the normal hooks, but React has a whole bunch of other hooks now. It has concurrent mode. It has a bunch of bells and whistles that it didn't in like most of its history.
Uh, does Rescript support those things or plan to support those things?
Gabriel: Yeah, I, um. Risk, like direct compiler is one example, of course, where we've actually had to do a lot of work to mold our output to, um, to work with the compiler. One, one example is that we now have a, a, um, JSX preserve mode, which means that, um. The, the la, like the JSX, you write in rescript, you can have rescript emit that as JavaScript as well.
So there's actual JSX in your JavaScript that gets admitted and that that's needed for the, the React compiler. I mean, there's, there's no, like that I'm aware of, no, nothing in the recent react versions that from a language standpoint cannot be. Supported things we traditionally have issues with, or is things like file-based routing, where in rescript everything is a globally unique module, so all files are.
Share in the same shared global scope. Um, in addition to binding. This is also one of the things that people think they will hate the most when they come to, to rescript. And some people like, like, gotta be fair. Like some people really do hate it, but most people don't like when they, uh, when they come into actually using it.
But that also means that we can't have a hundred different util rest files, which I would say is good, but we also can't have. A hundred different brackets, ID brackets, rest for file system routing. So you have to, when you wanna use that, you have to, um, write your, uh, your route files as JavaScript and then import script into that, which also works fine, but it's more work of course, and a bit of friction.
So, but I, I'll, outside of that, uh, I don't think there's, there's nothing I'm aware of in, in React that we couldn't support or don't support.
Justin: So let's see. As. As you think about like the rescript ecosystem, you, you mentioned earlier that there's like a blessed path. There's like some libraries that have really good support or I'm sure there's like some libraries that were just written for rescript itself. Um, what, what does that, like, what does that ecosystem look like?
What are some of the like very well vetted, very well engineered like bindings or libraries that are like pretty common in the rescript ecosystem?
Gabriel: Yeah. Uh, so, uh, of course React is one example. Um, we have a, uh, a very cool, um. Uh, schema library in the ecosystem, kind of like if you're a value bot. So, uh, which is, uh, by a, um, a person in the ecosystem who's very, very well versed in the schema stuff. And it's really fast, really innovative, uh, and very good.
Um, overall, we've traditionally had a lot of, uh, graph crail stuff that works really well just because graph Crail and V script. Nowadays, there's a bunch of other, uh, solutions to end-to-end type safety, of course. But traditionally, graph Cal when it came was gave, gave, um, a lot of like, possibility of end-to-end type type safety.
And that just lends, uh, lends itself quite well to rescript. Graphical is funny because it's, I've been working with it for ages now, and it's still like if you squint a little. GraphQL and Cript is really similar in the concepts they have. Uh, graph is like a subset, I would say, or, or a limited set of, of what Rescript has essentially, but like unions, enums those things, it's all, it all pretty much looks the same in graph as it does in, in Cript, for instance.
Um, so it, it, it maps really well, uh, back and forth. Um, uh. Uh, we have a bunch of other things like the node, node stuff, of course, um, bun, uh, and other things, um, as well. And then there's a bunch of, uh, innovative like own rescript stuff around forms and, and other things, uh, so to speak. Um, yeah, so there's a couple of couple of different different things and then there's lots of things in the works, uh, too.
Um, yeah.
Justin: So, uh, you're working on version 12. Uh, that's in, is it in beta now?
Gabriel: Yeah, it's in beta. It's, it's, uh, now I dare say it's, it's really close. Uh, but we've been doing a lot of things for version 12, so it's, uh, it's taken a lot of time to get this working really well.
[00:40:54] Exciting Features in Rescript Version 12
Justin: What are the big features that are coming out in version 12?
Gabriel: So version 12 has, um, the, the big thing for us that's been around for a while in rescript is that version 12 does all of the, like remaining big cleanups from. Our history, so to speak, in, in molding, rescript into this JavaScript focused, uh, language that we want it to be. Uh, so, uh, there's a bunch of things, uh, around that.
We've replaced the build system completely, um, which yields, uh, some massive speed ups in some cases I've seen. I, I have a couple of projects, for instance, where it's like 60% faster to compile from, um, from a clean slate. Um. And so on. So that's the thing. There's a bunch of other things in, in, um, in the language itself.
Uh, much better support for dictionaries. Uh, lots of more like powerful type things in how you can structure your types, how you can, uh. Move between types, how you can share things between types and those things. We have a couple of experimental features that I'm really excited about as well. Um, yeah, so it's, it's packed with things essentially, and we're starting to, like, some of the things in it is, is, um, are, are nice because they kind of give us a receipt that we, we've been able to, um. To make things work nicely together. Like, just like I talked before, like we want things to work well together. And that's usually quite a big challenge, right? To make things really work well. So one, one example is we've now gotten to a stage where, um, you can model JSON as a variant in rescript, uh, so as union, so to speak, uh, and with pattern matching and all of those features, that means that you can write. JSON decoders and encoders, uh, fully just in the language itself, right? So you can, you can get a, you can have a JS structure that you get from an API, and then you can pattern match your way on, on that to what you expect it to be. So for instance, like, oh, this js, I'm, I expect this to be an object. It's supposed to have a user prop.
That's supposed to be another object. It's supposed to have a name prop with, that's a string. It's supposed to have an age prop. That's an. Float or rent or whatever, uh, and so on. So like, that's a, uh, kind of a testament to all of those things working really well together, right? So like the, the features of the language come together in a nice way.
Um, and we 12 has, um, a lot of things around that essentially, and then a bunch of optimizations and yeah, again, like it's, it's packed. So we're looking to, we're really looking forward to getting this out. And for us it's, it's kind of, um. Now that we've finally done a bunch of, uh, like we've cleaned up a lot of things, we've replaced the entire standard library, for instance, to something much more, uh, closer to JavaScript, um, than what we had before.
Um, and we worked hard on, on making sure that that transition is hopefully going to be quite easy. So we built an entire like migration framework where you can, uh, automatically migrate, uh, from. From the old standard library to new standard library, even if the signatures of the functions are wildly different in the old standard library to the new one, uh, and so on.
So we're hoping that from version 12 and on, um, we're, we're going to be able to focus more on just sharpening the language rather than, than get making sure that everything fits well together like we've been doing now.
Andrew: Sorry,
Justin: Andrew, we have a few future facing questions. Maybe we could just like lead into those and wrap up.
Andrew: yeah, let's do that. Um, so we just talked about V 12 a little bit. You got a lot of exciting things coming, like jam packed release For sure.
[00:43:55] Future Vision for Rescript and AI Integration
Andrew: Where do you wanna see rescript go in the next five years? What, what, what's your vision for the ecosystem?
Gabriel: So, um, I would say continue bringing things in from JavaScript and molding it to like the useful things, molding it to, to our, um. To, to work in, in the rescript ecosystem, so to speak. But I'm, I'm also quite interested in and excited about, uh, general AI stuff. Like how a language like rescript is suited for agent DEC coding, for instance.
And that's something where we've actually spent a lot of time now with V 12 for se, for example, something as. Mundane as error messages is hugely important for an agent to be able to recover, right? So you wanna get to a, to a place where you can put an AI agent on your code base and just have it bang its head on the computer until it kind of compiles, right?
Um, and in order for it to be able to do that, you have to have error messages to kind of hint on. On what's wrong in a good way and how to fix it. Especially for a language like rescript that's small, where you don't have the benefit of there being massive amounts of training data, uh, for it. Right? Um. But risk, it lends itself really well to, to ai, uh, coding just because the feedback loop is so fast. It's really simple. Um, if it compiles, it works, all those things. And also that we, the type system is simple in a way that makes it possible for us to. I would say in, in, if not all, then most situations give you an actual good error message.
Like we don't now, but we could. Right. So that's the, and we spend a lot of energy in trying to make this really work. 'cause most often when something doesn't compile, you're doing something wrong and we can kind of figure out what you were kind of intending to do and like, here's a. In the best case scenario, we can just say that, oh, this is supposed to be this thing instead.
Like, um, but in, in, in the more common case, maybe there's maybe three different routes you could take from here and we could present that to the user or to an agent and, and let them kind of decide on which, which way to go essentially. So there's a bunch of things, um, I'm working on right now that I'm really excited about.
Uh. That specific thing, because of course, like AI is going to be big, uh, in the future as well. Um, but we also like, like just finding all of these like patterns that make you. Able to write good apps. So like one thing that's very popular now is, um, errors as values and exhaustive error checking for all the code, like the, like effect for instance has.
Uh, and that's the thing that's actually first class in the language of rescript. So. And you can do it all. Also very driven by inference. So, uh, we have, uh, the result type, uh, we have options, uh, and result types built into the language of rescript. And there's a concept, I'm not gonna bore you with the details, but there's a concept called polymorphic variants in, in, in rescript, which are essentially structural unions of things. So in rescript you can write functions that return results. You can mix them freely between async and not async because you have async Kuwait and all of these functions, as you call them throughout your, your application, the type system can track all of the possible errors that can be produced by those result types and then force you to to handle these whenever you call.
Function, like a great pattern that's thankfully getting popular now as well. Uh, right. So it's, um, but the cool part about it is that it's all native and built into the language itself. Um, and it's all inferred. So you don't have to write any annotations, you don't have to pre declare. You can go into function.
Two of the 10 functions you call in your decode function and have that produce another error. And then all of the call sites in your code base. That interacts with that is going to be force you to handle that automatically, so to speak. So there's a bunch of those things as well. That's, that's interesting to see how we can kind of Yeah.
Get closer to and make easier.
Andrew: Yeah, errors is value. Seems like a super useful feature. Uh, we've talked about it a lot on this podcast. Um,
[00:47:33] Conclusion and Final Thoughts
Andrew: well, thanks for coming on. Uh, Justin has to give up his room. Uh, well, thanks for coming on. We covered a whole lot of ground here about rescript. It's a very interesting language and I might give it a try.
Uh, I, I particularly, we didn't talk about it, but your rescript relay package looks like phenomenal. Like, just like there's barely any Read me there. The API is so nice. So thanks for coming on and ta telling us all about rescript.
Gabriel: Thank you very much for having me. Very enjoyable. Thank you.
โ
Discussion in the ATmosphere