Server-side rendering React natively with Reason with David Sancho === [00:00:00] Hello and welcome to PodRocket, a web development podcast brought to you by LogRocket. LogRocket helps software teams improve user experience with session replay, error tracking, and product analytics. You can try it for free at logrocket. com. I'm Noel, and today we're joined by David Sancho. He's here to talk. About his latest talk, server side rendering react natively with reason. David is a software engineer at Ahrefs focusing on working with reason and functional programming overall. Welcome to the show, David. Welcome. Thanks. Thanks Noel. Glad to be here. Awesome. Yeah. I'm like, I'm excited to talk. I feel like this is not kind of a realm. We typically have, like on the podcast or just in, in our sphere usually. So I think this will be an exciting one. So yeah, let's talk about, functional programming a little bit. Why I imagine most devs like are aware of it, have, maybe dabbled a little bit if they're listening. But I guess why, like, why are you driven to functional programming? And especially within the context of react and server side [00:01:00] rendering, why should we care about it? So yeah most developers are familiar with the term. Maybe not depending on the degree of experience or maybe the degree of exposure to functional programming or the imperative or other fashions of programming. so, Yeah, the idea to functional programming is to, of course, be more declarative. Instead of imperative that's like the one sentence kind of Yeah. For me, all started when I know eight or six, six or seven years ago I started working with react react kind of enforces you a little bit of purity or immutability style in your code. And that was the beginning for me. And I think from many people who adopted the stack of react and maybe Redux at the time or whatever state management. So all of these was the interaction and then I started getting. I was working on a big code base. I was working on Typeform at the time and our code base was like insanely big 30 people working on a more repo monolith whatever.[00:02:00] I started facing a lot of problems that function programming. to solve and every time that we adopted or we refactor some of those patterns those problems went away. So that's what I got hooked into it. Then the whole design space from react got inspired by Elm. So I rapidly tried to learn Elm as fast as possible. so, And then when I started coding in Elm, that's where like the whole thing exploded and I realized that there's. From the typical code that I do from the entire degree of function programming is. It's super big and yeah, I got hooked into that. Got hooked. Yeah. Nice. Nice. Yeah, it's a good story. So what I guess like what is reason then and how does that help us when we're writing React? So yeah, Reason is a programming language, different programming language than JavaScript that I think is the most common one or TypeScript, JavaScript, I think are the most mainstream ones. Reason is a new programming language that it's built on top of Ocala, which that's, it's an old programming language[00:03:00] that comes from French academia. From the eighties. And tries to get back these functional paradigms from the start. So like the language is built on top of functional programming paradigms, but it's not extreme, that doesn't push it to extreme. So sometimes you can get away with what you want to do. It doesn't block you from pushing to production. Block to, to do like what you were, are used to before. It, it has a very strong based on theory. So all the features compose together because they are being studied for a long time. Which is something that you don't get when you work on other languages. But yeah, Gumball is this niche language. So reason is just trying to get this whole theory speed and all this perfect language tries to fit it into JavaScript people by giving a nice syntax that looks familiar. Because one of the blockers for. It's syntax it's a little bit old, it's a little bit like too polished too functional, I [00:04:00] would say. So people get very lost into that. So the creator of React, which is Jordan created this kind of like syntax on top of OCaml so you could instantly get those apps to speed to. A language that has all these functional semantics ready for you, that you can more or less map one to one with your JavaScript knowledge. Cool. Cool. So what is the, I guess maybe just to make sure we're painting a super clear picture. What is the relationship between Reason, OCaml, and then like , the code that eventually gets spit out and like return is this stuff actually ending, does it end up going through the OCaml compiler or what is that series of steps Good question. So the graph of things is that you write in Reason , you compile it back to OCaml so you transform the Reason code into OCaml and then you pass it to the compiler. The compiler can be both OCaml itself. So you can execute native code. As a binary, same as Rust or C or all of these tool chains, or you can use Melange, which is the compiler that emits JavaScript.[00:05:00] So that those are the two branches from you can compile a reason code, Then that makes sense to me. So . How does that tool chain end up looking say we're running a production application here and it's, it was written in reason. What is actually running? What are the files sitting there? What is that? Like webpage from the browser what ends up happening? The actual stack is very similar to what you can get with JavaScript or maybe PHP or any sort of web framework, of course. But the idea that you would write a reason file the syntax is going to be more or less look like JavaScript, but you would be writing native, right? We call reason native to, to classify the, you're writing on the native tool chain and your typical web server, you could return like get a response of course I get the request return back a response. And the classic yeah, the classic one function for your Lambda or everything like Are we still returning just like HTML and JavaScript files to the browser? Nothing fancy. Is that what's [00:06:00] being spit out here? That depends on your use case. For example, in Ahrefs, we have a big backend half of them are endpoints that are termed JSON. You can return the HTTP classic or you can return uh, HTML page. If you work with React, you can either server side render. I think that we're going to talk a bit about that, but you could maybe not. And just return a HTML page that is blanked. And then React renders on the front end and you've got the classic render client side render on the browser. Perfect. yeah. Cool. Yeah. I do want to get into server side, like SSR, but I want to ease our way over there. So Like why go through all this work? Why should a dev care to have to worry about Oh, I'm not writing reason that's being returned. I'm writing, I'm having to think about a different language and what's actually running in the browser, like what's the benefit. The benefit is always based on the status quo, right? I think the status quo now is probably you, if you are in the React world you use Gatsby, Next, Remix, like all these metaframeworks. And I'm, I don't hear saying [00:07:00] maybe no. So I think the alternative is more to what reason brings into the table. It's obviously like the language itself. I think that's the biggest sell. It's just like the language is contract to be safe and opposed to TypeScript, which is safe as well. But there's has a lot of Skype like a lot of you can shoot yourself in the foot if you want very easily. You can have a sort of all no checks any types. You can just lie to the type a lot that never happens in reason, right? You can do it, but it's extremely rare. So like the entire language is it, I believe it's a, so a more solid foundation for your bucket code, for example, as same for the front end. So like the language itself is one, one big cell. The other one is the speed. When you compile to native you are comparing like a compile language with a transpile language, even though it's running node, it's really optimized for just in time compilation that is V8 and the whole event loop. I think that's very well done for their team, but you're comparing two different [00:08:00] worlds where one is compiled goes directly to the machine. And the performance is, it's just different orders of magnitude different. So you might, not everybody cares about performance, but when you really care about performance, we have found that these, it just has some limits. I guess at that point why is reason particularly well suited to be a replacement? If we're ripping off the band aid saying, okay, we're not going to write note anymore. Why write reason? Reason comes with a few different motifs. I don't want to abuse the word reason. Sure. So yeah, reason is it was designed to work in the web. So it comes with JSX similar with you have with JavaScript. So you can write your components as. As usually in React. So that's like a good default. But there as well, like the ecosystem is ready for the web. There's still a few still missing pieces here and there. But overall, the whole stack of using Dream, which is a famous web framework in OCaml. There's Opium. There's a few of those options that are very popular. And then you [00:09:00] have, of course, like Postgres driver, SQL driver I don't know, like all the sorts of tooling that you might need while you work like JWT I don't know, like all the libraries are ready. So that's, I think that it's well suited for that. One of the unique, currently unique benefits from using Reason is that you can compile to both targets. For example, if you compare it to Rust, again, another kind of like popular framework, you can compile to WebAssembly or you can compile to a native executable. In our case, we can compile to JavaScript as well. So if you want to have like validation type safe, end to end JSON encoding, all these kind of like nice utilities that cross the boundary. Reason is perfect for that because you can compile those out. If you don't pay the price to do web assembly. So it's all these kind of like in the middle ground of the entire spectrum of technologies. Maybe for people who aren't super familiar, with this ecosystem why is being able to compile to JavaScript beneficial? Like in a [00:10:00] typical setup, how, like, how does that actually help you? Yeah. Some architectural differences that you need sometimes to have some logic that you want to run on the front end and on the back end. The classic example is validation. You can think of validation as very tiny validation that you need in your form. That's kind of like a small use case. For example, in, in my previous company we were TIFORM. So we had forms and we wanted to validate the logic of the form. So answers can be correct on the client, but as well on the server, right? So you malicious people could not push wrong answers to forms or try to get discounts or yeah, or also validation security. So our effort was to re implement the library that re implement the library that they need to work perfectly from on the front end using JavaScript, for example. And our backend was written in Go because in our, in the first test we had the responses API was called was written in PHP and that was nightmare to maintain blah, blah, blah. So they [00:11:00] refactored to Go. So we needed two implementations that they mirror each other. So tests need to work in both. If there's some mismatch, the whole thing blows away. And that memory stuck with me because it felt a super simple problem where why don't we just call the backend, right? Why don't we just, and it's like the facility or the possibility to compile to JavaScript and have the same functionality. In some particular cases, it's just unbelievable, or the other approach might be when you have a small team and you treat your developers or your team as full stack, which I'm not super particularly fond of the concept, but the idea of you can do damage everywhere. If the language and the constructor of the language is across everywhere. That's what like speeds you up a lot. So because all of this and performance, I think Reason is like a good sell overall. Yeah. So let's talk about the form validation example. Just cause I feel like that's an easy one. Let's say we had a [00:12:00] reason code base, how does that actually manifest? How do we go from having this reason code and then having JavaScript form validation? That, like we can run and ensure we have parody when doing server side or client Right. I introduced before Verifas Melange, but just because there's two code names. So one is you imagine you have one file that is Reason. This file, you can compile to both the JavaScript version and the native version. The JavaScript version is going to be just like export function, classic JavaScript. You can export a default function called validate, and you can send. Some random object this random object, of course in this example, for example, let's say it's a JSON. So when you run this function on JavaScript, you need to pass a JavaScript object when you call this function in native you need to call to pass a JSON Mm hmm. well. It's very, It's very important because. Of course you want the language between both to be compatible. If I say string and I say string on both sides of course, like [00:13:00] the native strings and the JavaScript strings are, they might not be the same. So we want to like call, call them with a universal code. So there's a little bit of rules. But at the end of the day you always send JSONs here and there, or sends strings here and there, or like lists. So like your data layer is very uh, universal. So it doesn't need to worry much. If you want to send, I don't know, like maps as JavaScript, that might have some problem, but yeah rarely I have been in those situations. Gotcha. So is there tooling in place? Does reason come with tooling to make that setup easier? Or how do I go from like, I have a reason file to, okay, now I've got this, JavaScript being run The story or the tooling for combining to both. It's still very experimental, so it's not something that of course I can maybe send you a tutorial or whatever, but it's not something that most people can get up to speed very fast because it requires a little bit like. the package manager [00:14:00] and the build system if you come from the JavaScript world, you're not very used to something called, you know, so learning these two tools might be like a barrier. So sometimes if I want you to get involved into that, it might take you a while compared to other solutions, of course. But yeah, we always working to get this barrier as low as possible. Nice. So yeah let's then talk about like how that factors into like server side rendering and how that looks. Yeah, let's just start from the beginning. What is like reasons approach to doing server side rendering? So since now a reason hasn't been advocating for any solution to server side branding, we, we have solutions for have re implementation of React in native. But there, there was no, like a single solution to, to do service rendering. They come with a client side rendering story as or if you want, you can maybe use Node compile to JavaScript, then run Node and then do the classic [00:15:00] Express or any JavaScript framework. Gotcha. is there any plans to go elsewhere or do you think that'll be the long term solution? I mean, My solution is going to native. So try to get React. To run on the server natively. So the idea is to, let's try to get rid of node, if that makes sense. And try to embrace the run time that is a bit faster, . How does that look? Let's react on the server. How does like server rendering work in that realm? Hmm. yeah server rendering react is very simple. The concept might sound like very unfamiliar to any person that works in React mostly because they are very far from the actual logic, right? So you work with React that. You create components and those components are being called by someone else, some, somewhere in another place. And if you introduce Next or Gatsby or whatever, they call the random method for you. They create the pages for you. They [00:16:00] create the routes for you. So you are very far from the server or what's what server terms. But when you get in deep into how these tools get into it with each other, it's, I think it's very simple react by definition is you have a tree and these three are either strings or function to the return strings. I said, string stuff components instead of JSX or whatever, but it's just you have a tree that represents your application turns to be written in HTML. This HTML on the wire needs to be represented as a string. So you have a tree of functions that might return strings and that's it, so the simplification of all of these is the server doesn't need to care about the effects. They don't care about use, use state. They don't care about use memo. They don't like all the things that you use are not something that react on the server occurs. And you do a single pass. So again, there's no virtual DOM, there's no [00:17:00] reconciliation, there's no re rendering. So you need to get the tree, return a string and that's Cool. How was that work going? Has it been pretty smooth sailing? Do you think that in the foreseeable future will be at a point where that's, possible to do this kind of native react? Yeah I, the project started one year ago and I think we deployed on with six months of work, I think we got it into production. So very fast we tried to get it into like test our assumptions and prove the solution that worked. So we implemented that the implementation is a small, but the tooling around and all of what I explained before, it wasn't a bit tricky but when that's all solved I think that the classic problem with surface rendering is that you don't have access to the window. Like all the JavaScript APIs, like document, get elements, select, like all of these are not there. So all your code needs to be. Server dependent or server aware, right? So this is more like the challenge that we're facing, but , once these problems are being [00:18:00] sorted I think on a drift, we're going to deploy like all the services are going to be surrendered by default. So the work is ongoing and anything I think it's very possible. Yeah that's really cool. Nice. How is are there other people using this in the wild that you know of, or has it mainly been at Ahrefs that Right there, like the whole reason ecosystem is very niche. I think before back in the days, five or six years ago it was like a full of people, all the JavaScript people were writing reason doing backup script where like everybody was on the community nowadays is very niche. So we are almost, I know all friends or all know each other, know where do we work each other and hang out from time to time. But yeah there are a few people that are deploying the server side rendering solution. I have one friend that is pushing in to have the whole reload and the whole kind of development of testing and all the tooling around being sorted out. And part of my company, of course, [00:19:00] is they're helping me making this code to be universal. So part of this is creating like these solutions that work with the two targets or two environments. So there's a lot of like we're going on it's just all of them are being just the Lego pieces. So there's more pieces that eventually we can create something that it's going to be more easy to be consumed. But for now, I think I'm hopeful to create this. Nice. Cool. Cool. What I guess is there anything else like motivating you guys, the community to keep working on this? Like I know we're writing, like writing more functional reason code is maybe justification in and of itself, but are there, I don't know. Is there are the benefits like in, in performance or like compile times or anything like that? I think it's fun to say because now the back in the day we look at a TypeScript or at least I was not part of a team when they decided to go with reason, but they didn't want to use TypeScript or flow or all these alternatives because there was like not type safe [00:20:00] across the boundary. So what we had in nature of five or six years ago is that you change a database field and the compiler was you through until the front end in every place that it misses the field or misses the type or whatever it cuts everything. We had that from like back in the day. So every time that we see TypeScript, like getting up to speed and creating the tooling around, we thought we already have this at home, so in terms of safety, I think that you get on bear with reason of course, like the language itself is different because you still run on JavaScript but I think that's like on the same level. In terms of speed, of course, the TypeScript compiler is very slow compared to the Reason one again, like the performance, I think it's always like you take it for granted and when you work on a monorepo or we have I don't know, maybe 60 60 developers working on monorepo when performance is very fast and you need that when you work with a lot of people deployees and all of this needs to be very fast as well. So [00:21:00] you enjoy that part, right? So yeah, apart from that, I think that's the two main benefits of Reason are those, of course you can have access to all the tooling for OCaml, like the whole native things that, that they trick your head sometimes. So for example, in, in OCaml, there's no promises, right? The word promise doesn't exist. They call LWT, right? It's the same concept, like something that can happen asynchronous, but their construct of promises are completely different, right? Just learning that this is a LWT, you can compose them, run parallelly, join back, like with it's the same model as you could do it in JavaScript, but while learning OCaml or learning these native paradigms. They teach you what you didn't know about JavaScript, so they teach you the stuff that you take it for granted when you're working in in, in the browser or in node. So I think that's, I think that's what I would recommend everybody. Not everybody, not reason is not for [00:22:00] everybody, but when you learn this new paradigm you go back and you feel that you growth. You grow a little bit Nice. Is there I guess that was my next, line of questions then is who would you encourage to come, look at Reason and see how it feels to write functional code for the front end, yeah, there's the classic there's a classic division between a builder on a innovator, like this balance between you are a developer that sometimes you can wear a hat of one or the hat of the other. But if you are an innovator, a person that is always curious, always try to push forward and trying to choose the tool that fits your kind of like your best problem rather than, Oh, let's use the tool that I'm using because I'm going to be fast and my company is going to be happy if I release faster. If you're an innovator, you want to push forward with learning. And if you happen to fall into the functional, you are attracted to functional programming. Recently, I think it's a very good sell they're friends of reason, of course, there's Elm, there's [00:23:00] Pruscript, there's Rescript even. So there's many siblings if you call them that are like good contenders to teach you all of these language constructors. Yeah, if you are into that, I think the community, those communities, because we are a little small, we are very friendly. So that helps you get questions and get replies by the person that creates the tool. So you can get very nice solution out of the box. Nice. How would you recommend people jump in if they are curious and want to check it out? If you are an extrovert, probably the best way is to join the Discord. Join the Discord, say hi, that you want to. Use this in your company or run a workshop or learn about it to do some sort of site project. I think that's the best. You, of course you can always like, if you're not an extrovert the position, I think it's good enough. And if that's not what you, what, if you have nothing that you can get from the condition of always go to cool discord. I think that's where most people have succeeded. Nice. [00:24:00] Yeah. I'll we'll be sure to get a link to the docs and the discord in the show notes. So people can can, people can hop in. Is there any anywhere in particular that just like the community, the ecosystem needs help. Is there anything that you guys have been looking for, need more eyes on, need more people trying out? There's always like efforts on documentation because when you. When, just myself, I spent like the last month trying to write some documentation for Reason, a website. And, it's incredible when I show it to people that are not are not like deep into the concepts, that they instantly say, oh, these five words that you say in the first paragraph they don't make any sense to me. And I'm like, oh no, I need three more pages, oh, I need to describe this more clearly. Or sometimes. Even more like they say, Oh why this is explained like this? And I'm like true. I'm very focused on how I implement it, how they solve it, that I'm very far from the user experience. So of course the competition [00:25:00] is that kind of the super hanging, low hanging fruit that you can with one hour on effort, you can have a massive impact. But of course, if you want to play with the language. Any integration is good. We previously had an integration with expo to write react native apps as well. There's people who tries to build on top of next, but for example, I think we don't have anything related with remix, for example. So having this integration, if you're a remix fan or you want to play with the language, plus doing the full stack in JavaScript, those integrations are invaluable. So if you are an expert on this particular part you can have a small community of people that you work together with and create like the place for starting a small. That's more integration. I think that's very good start. Awesome. Cool. Cool. Again I implore people to come check it out. Is there anything else that you wanted to mention David or we didn't cover? No, I think that's we've run through it, but yeah, pretty good. Awesome. Cool. Thank you so much for hopping on and talking about reason with me. I appreciate it. Thanks. Take it easy.