Deno with Luca Casonato === [00:00:00] Hi there, 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. Try it for free at logrocket. com today. My name is Paul and joining us is Luca Casanato. He is the creator of Fresh and a software engineer over at Deno. We all know one of the most favorite runtimes that people are breaking into these days. We're going to be talking about what's new with Dino and what's new with Fresh as we close out 2023. Welcome back, Luca. Hey, thanks for having me. Yeah. So like we just mentioned, we're going to be getting into Dino and Fresh two things. This is a double whammy podcast because you are the creator of Fresh. That's pretty awesome. When did you get into Fresh and what? Motivated you to start something new all on your own. Yeah, that's a great question. I've been at the Dino company for three years and I think maybe one and a half years in or so. I decided that we wanted to have like an open source web framework. Fresh was actually born out of an internal framework that we had that [00:01:00] powered our dashboard for our cloud product, deploy , but that was an open source. So we wanted to have something that was open source because we thought it was pretty cool. So we started out as a tech demo showcasing sort of the features that, you know, has and how you can use them to build websites and people seem to really like it. We put some more time into it and actually, I think halfway through this year. Marvin joined who's , one of the maintainers of Preact and he's been maintaining fresh for the latter half of the year and has made some super awesome additions that we can talk about. You guys basically just rolled your own front end framework, essentially. You had one on the inside, and now you have one on the outside. Do you feel like, in your space, and where you work, in, runtimes, JavaScript, you know, is it common for this to happen? For people to say Next. js or Astro like, there's a lot of things out there, but we use our own thing. Yeah I think JavaScript is much like JavaScript developers are much happy to reinvent the wheel than like many other sort of. Software developers and I think part of that is that it's [00:02:00] just very easy to do right like there's a very low barrier of entry Usually to starting out a new JavaScript project you put a couple of JavaScript files into a folder and call it a day Right and now you have a new framework making that work well and getting the documentation and everything there is obviously like a whole other step, but I think it's very easy to do in JavaScript. And maybe even too easy sometimes. Yeah it's one heck of a modular ecosystem. So too easy can be an argument that some people can pull out of their pocket sometimes. Well, Before we get too in the weeds with Fresh and your journey with that, I want to focus on Dino because you have been there for a little bit. People have been, adopting the ecosystem and writing more things in it. What is new in Dino since we last had you on in 2023? What stuff gets you excited? We've made a bunch of additions to Dino. I think a lot of the things we've done are related to stabilizing the ecosystem and letting more people onboard onto Dino. A big part of that is our continued effort on backwards compatibility with node. [00:03:00] So in the beginning we really started out, with this idea that we needed to make a hard cut with node to just. Get back to basics and figure out what things are going wrong with node and what things need to be improved. And I think we did a really good job of that. We figured out this whole built in tooling story. We figured out getting modern APIs that are based on promises, getting this whole like ESM only module system in place. And then. About halfway through last year, we decided that we were now at a position where the foundations were good enough that we could start backporting some of the things that people have from Node to let people more easily migrate to Deno in pieces, right? Previously, it was really difficult. You'd have to migrate your whole app all at once, or you'd have to learn a whole bunch of new things all at once because you couldn't really do half Node APIs, half Deno APIs. It was like one or the other. And. We now have a very extensive sort of backwards compatibility library with node where you can just import node colon modules using the import system. So for example, node [00:04:00] colon FS Oh, that's node colon net. And yeah those just work out of the box. And then we extended that earlier this year with NPM colon, which allows you to just pull in like any module from NPM and have that work. And like node is just automatically. Polyfilled in there correctly and things just work so you can run express and fastify and Chalk and all those things that you're familiar with from node just right out of the box and and take them with you when you're migrating. That's huge. Like npm colon, come on, it doesn't get easier than that. And the reason why this was such a big push for you guys is ultimately Dino is a different runtime, right? And the work that has been going in this year, is it accurate to say that it's just been bridging this runtime back to the node? Like you said, making it backwards compatible, and there's a lot of under the hood work. That needs to go into that. What was one of the biggest challenges that you feel like the team faced during that process? I think there was a couple ones like one of the big ones was sort of a philosophical one I guess where [00:05:00] we weren't quite sure how deep we wanted the integration with node to be like we wanted to Make sure that there's still a clear Sort of cut off between this is where node ends. This is where, starts. And you didn't, we didn't really want to have them intermingle too much. And I think we did a pretty good job of this. Like we still don't allow you to write common JS code at the your application level, because we really still want this to be in like ESM only ESM. Um, right? Because there's a lot of benefits to that. And there was a lot of like hard philosophical questions. Like, where do we draw this line? And then the other one is obviously just implementation. A node is. very old by software standards, it's 10 years old. There's a lot of, it's grown very organically over the years, which means a lot of API's have sorted, have been added at different points in time and they have various levels of polish and abilities for users to integrate into them in ways that maybe wasn't originally intended, and people just figured this out after the fact that, hey, if I overwrite this property on a stream, I can get this behavior that I really want, even though it's not really a public API. And then you have to polyfill out, not just the [00:06:00] actual public API, but all of these Intricacies that people rely on that aren't really part of the API to and that's really difficult. So we spent a lot of time sort of making the node test suite. So the test suite that node itself runs work with Dino. So we could run nodes, actual tests against our. polyfill implementation to see that what we were polyfilling actually was correct and was what people were expecting and then this catches like maybe 80 percent of things and then there's a lot of things that you just Don't know about or don't realize that people are doing until you get the bug report that, Hey, this specific version of talk from three and a half years ago, it doesn't work because it like uses some obscure JavaScript feature in this weird way. Right? Yeah. And yeah, you can't figure that out in alpha or beta. You just need to realize that during when somebody tries it out for the first time and there's 2 million modules in NPM. Um, Two million. Wow. test all of them upfront. So what [00:07:00] about things that you guys added in terms of new features? The shiny polish, the car wax, you know, HTML doc generator. Can you talk to me about that? Why is it so cool? Yeah. So that was actually a feature that we just added I think in the last release, 1. 38. So we've had a documentation generator built into, for a long time where we can take your TypeScript code or your JavaScript code with js. comments and emit some documentation for it. Some people may have used TypeDoc in the node world. It's like that, but spruced up and. For the modern era, right? It's something that people are familiar with if they've come from go or rust or sort of other ecosystems that have automatic documentation generation. And previously we've had this for the CLI. So you could see the documentation in your CLI and you could see it through Jason and come up with your own visualization for it. And we now have a HTML output. So you can just run, doc dash dash dash HTML and. Just it can then emit a bunch of HTML files into a folder and you can host those on your server, host it on GitHub [00:08:00] Pages or Netlify or Deno Deploy and get documentation for your library that way. Charging through some of the new features you guys have. JSX transform, there's a whole new like compatibility with JSX right now. Can you talk to us a little bit about that? Yeah so Deno has supported JSX for a long time but we recently realized that The JSX transform that is pretty common I don't know how familiar everybody here is, but usually JSX works by being transformed into sort of function calls, like , every JSX element is one function call, which means that if you're doing server side rendering you're doing a lot of function calls, especially for large pages, and a lot of the HTML that people or the JSX that people write is relatively static. So we realized that if we could precompile some of those JSX things to static strings, there's a lot of performance gain to be had. So we built a new JSX transform, actually Marvin, my colleague who's working on Fresh now did this where we're seeing like 7 to 20 times gains on many large [00:09:00] pages for jSX rendering, and this is features that is going to be integrated into Preact natively. We're hoping that other frameworks adopt this too, and it'll be integrated into I don't know, Babel and yes, build and all the other sort of build tooling that uses JSX. I think it's a really good innovation to just make things faster all around. Do you feel like pre compiled web builds are like the direction that we're going to be moving in when we have Angular which kind of takes a similar approach. We have Svelte totally rethought the way we do that. And now this sounds similar, right? yeah, yeAh. I think we're moving to a, in a direction where, so I think actually maybe this is best described as a pendulum, right? Like initially we started with PHP where you had these templates and you inject a little bits of dynamic content into them and then people didn't like that, we swung all the way to JSS or to like client side JSX where you had like an empty HTML document and everything was rendered by JavaScript dynamically all the time. And this was like. Terrible for accessibility and terrible for like speed and performance and [00:10:00] I don't know just wasn't great. And then we swung back to People wanting to do like static site generators with go and like hugo. I think was a pretty popular one for a long time and now we're arriving at a middle ground where you write jsx both for server side generation and for client side components, and the framework just knows how to compose these together in a way that yeah, makes sense, right? Like it can render the static part statically, it can render the dynamic parts dynamically, both either on the server or in the client, just a matter of like where it makes sense for any given use case, and I think we're seeing this , definitely in Svelte and in Next. js, we're seeing this, and Remix has done a pretty good job of this also. And just to tie off our conversation about Dino specific stuff before we move into talking about your projects, fresh bun, it's like that other guy out there, what do you guys think about bun? And how do you view like your sector of, or I want to call it like market size of like, what type of developers and [00:11:00] application you're targeting versus the bun ecosystem. Or are you guys like forbidden enemies? no, I think it's great to see more competition in the space of JavaScript ecosystems. It pushes everyone forward. I think we definitely saw this when Dino originally came around. There was Node had been thinking about implementing Fetch for a very long time and it never happened because there was always people who opposed it saying this doesn't make sense on a server, this just doesn't make sense, right? And then D Node did it, and the Node folks realized like, you know what, we were wrong and we should implement Fetch, and they implemented Fetch. And I think we're gonna see this with a lot more things, having more people pushing different ideas means that ultimately we're going to have more run times that have a lot of good ideas because there's just more place to experiment. And yeah I, I think like bun is at a different stage of maturity and sort of compatibility than Dino is. I know bun markets itself very heavily as like node compatible and fast. And. that's great. it's also very node compatible now. you know, It's written in rust. It's very fast too. [00:12:00] And has all this built in tooling, right? That, that like bun and node both don't have. So I think there's like significant standout features that the runtime still offer between each other. And I think that's great. And I think there's still a lot of space in the ecosystem for people to explore different ideas. Like one of the things that we've been experimenting with the last little bit here is a built in database into, like what if your runtime has a database that just is built in and you can use it locally and you can use it when deployed to a cloud. And it just works out of the box. Has built in support for like queuing and time to live rows and all these kinds of things. Wouldn't that be cool? And it turns out that, yeah, that's cool. People like that. And I think innovations like this, where we're going to try out new features and . See what people think of them is going to be more frequent and yeah, that's makes me very excited. Positivity is the best way to be. So sharing ideas and building on each other. , I'm glad to hear that you guys feel that way. And we're just pushing the ecosystem forward altogether. We're going to hop in a fresh now and talk about. specifics about fresh, [00:13:00] the beautiful web framework that has probably the cutest logo you'll find anywhere. riGht before we do that though, I just want to remind our listeners that this podcast is brought to you by log rocket. So if you're making a web application and you want to spend more time building and less time debugging, maybe you have a Dino app because we can plug in. NPM modules right away. You can plug the SDK right in there. You can use log rocket to do things like have AI fine and surface patterns that you might not have noticed heat maps, session replay, and a whole lot more. So head over to log rocket. com today and check it out for free. Now, focusing back on fresh, let's just start with what. Made you want to bring this public? Cause at the beginning of the pod, you mentioned that this was like an internal thing that you guys were using for Dino deploy. What made you want to push it public? Cause that's a significant undertaking to really adapt it for the masses. Yeah. Yeah, definitely. Just yeah, making things public, you need to write docs, right? It's it's a big endeavor. So the thing that really drove us to write fresh in the first place was that we were unsatisfied with a lot of the frameworks that were out [00:14:00] there. Particularly this was around the time that Remix was just released and we realized that. Remix did a lot of things similar to Next. js, but did a lot of things better. Namely, it was much more sort of web standards oriented. And that felt really nice to use. But at the same time, it had a lot of those drawbacks of Next. js, where you had to perform all rendering twice, both on the server and on the client, because You couldn't really granularly send components to this client to render because yeah, every, everything was rendered on either the server or the, or sorry, on both the server and the client. And with Fresh, we wanted to take a different approach. We realized that the edge was a thing that was happening at this time, Dino was obviously involved there too with, you know, deploy. And we realized that server side rendering is a dynamic server side rendering specifically is something that's. Very viable to do now. So you don't have to send a bunch of sort of client side code to a client to be able to do nice customizations. So we wanted to build a framework that was centered around server side rendering, [00:15:00] but without constraining users. In such a way static site generators do, where the sort of interactive components just become really lackluster. And we didn't want to do this in such a way that you have to learn two separate templating languages, one for the server and one for the client like PHP style. But instead, really, you should be able to... Just write one application and then mark certain pieces of that application as being sent to the client. And the framework would figure out how to do that by itself. And this is actually sort of a direction we're seeing Next. js go into now with server components. I think there may be a different implementation of this , that's maybe more magical and, more difficult to get correct all the time, and I think it's, it still errs on the side of sending too much rather than just the right amount. But the way Fresh does this is through idea called islands, where in a sea of static content that you server side render, you have these little islands of interactivity, which are JSX components that you mount to specific nodes that you rendered on the server and, yeah, , you hydrate them on the client. So this means, for example, if [00:16:00] you have a blog page and like you have blog content and maybe you have a comment section underneath and a title image at the top, you don't want to have to render the title image and the blog content with its markdown render and all that kind of stuff on the client, right? You want to render that once on the server. In response to the request, like on the edge and then have the comment section, which maybe is very dynamic, have that render on the client in an island and so we built a framework that works like that and that was really fun. People really enjoyed using that. Internally. And we wanted to show the world because I don't know. It was a cool experience. Why not? Maybe you'll end up taking it to the moon throughout the years. So, Islands are. Definitely an interesting concept. I know Astro is a huge fan of the island paradigm. How do you guys deal with state sharing between islands? And what sort of pluggability do your islands offer? Can you put anything in an island? Any type of component? That's a great question. So on the state sharing, we rely a lot on signals nowadays. When we initially released Fresh, this was a question that was not solved very [00:17:00] well, but then there was some good timing because Preact had just released Preact Signals around that time, a couple months after the initial release of Fresh. And then we decided to adopt those as our mechanism to, to share state. So one thing that we support, for example, now is That you can create a signal on the server, pass it to multiple islands, and then when those islands hydrate on the client that serve, that, that signal is recreated, and sort of these connections between the multiple islands are maintained across that signal. So you can use signals to, I don't know, update Like have an input field that is attached to a signal that gets updated when you input something and then have a different component that renders the output of that island, like whenever it changes somewhere else on the page. Yeah, signals. That's a great way of doing that. And then I forget what the other part of your question was. So it was about sharing state and then as an example in Astro, I could have a react component and then a solid component. I'm not sure if that's something you should do and push to like load all the frameworks in there. But what type of [00:18:00] pluggability do you guys support? Or if, let's say you do support everything, you're like, we really want to focus in on this one type of island. Yeah, support Preact as the client hydration framework which is very similar to React if anybody's used that well. Okay. Everybody's used React, right? What am I saying? Yeah, no, it's, but it's much smaller than React. The sort of idea is that this will give you all of the benefits that you would get from sort of the reactivity of the react gives you, but with a much smaller bundle size, we don't support using filter view or solid or anything for islands, just because we have this. feeling that , we can do a much better job at sort of integration. If we give you one blessed path that works really well, rather than giving you many paths that all work like if you have, I don't know, if you integration and a solid integration and a felt integration, it's just a much more work to maintain than if you have one integration and you can plumb this through in ways that. maybe you're always limited to [00:19:00] a least common denominator problem if you have multiple frameworks because the best experience that you can offer is the lowest common denominator that all of these frameworks support, right? You can't build like foundational features of your framework on new features of solid, for example, because like they wouldn't work with So you, you have to always use the slowest common denominator in this. Makes things, I don't know, challenging, because then you have to come up with abstractions yourself that bridge the gap between these frameworks, and then it's really not even, you're using Svelte and Vue, but you're using like a dialect of Svelte and a dialect of Vue that sort of works slightly differently than you're used to just because of these sort of bridging abstractions. So yeah, we just use Preact. It's one of those things too, where it's we've had folks on here who have talked about Astro. I myself have used Astro, great building experience, like honestly phenomenal. One of those selling points is I can put solid view and react all in my Astro app. And it's like, that's cool. I still have to meet one person who has done [00:20:00] that with an actual use case. There is definitely, I would feel like some value in saying this is like the one way we do it and we're going to make it awesome. It's going to be like really good when folks, let's say people listen to this podcast. Everybody's done react. Like you say, they haven't done preact and they're like Okay. You tell me it's the same, but it's like, I know it's different. What's like the number one thing that people maybe have like paralysis with if they're hopping into the preactive ecosystem. I don't know. Oh, you really have to think about it. the same. It's the same. They are the same thing. No they work very similarly. I think the biggest thing that you would run into is if you do something weird and you get an error message. You're going to get a different error message between React and Preact. you use a different DevTools extension. That's the difference. I don't know, it's pretty similar. You use hooks the same way. You, I guess you can, so in Fresh, you import hooks rather than from React. You import them from Preact slash hooks. I don't know, it's pretty similar. If you know what useState is and you know what useEffect is, and you know how to use, how to write JSX with React, you can write Preact.[00:21:00] It's one of the best answers you could give. Cause now it's very enticing for people to go over like rest assured. They're almost, they're pretty much exactly the same thing. So some other features are fresh, just, we're running up on time, but there's so much to talk about with fresh. Cause it's really neat. Zero JavaScript. Shipped to the client by default and it's really been built for speed, right? Are there any other like core tenants that you guys are keeping in mind besides speed? Because everybody wants speed. Everybody wants good developer experience. But I like how you mentioned some of the like ethos that you guys were talking about in the Dino conversation. Yeah. What are some thoughts that you guys are having on the fresh side with that? I think the, that's like a lot of the ethos of Dino extends into fresh. Like we really want there to be one integrated experience that works well for everyone and can deliver 99 percent of what you need right out of the box. And this means that like fresh, for example, when you run the installer, it asks you, Hey, do you want to set up tailwind? Because a lot of people want to use tailwind [00:22:00] and fresh just has a out of the box maintained first party tailwind extension. That gives you tailwind. And these are sort of things where we don't want you to have to rely on third party packages that may or may not be maintained. You don't really know who to report bugs to and like where to look for documentation for. But rather we would much rather have you have a fully integrated experience where like taking Dino as an example, you can have a testing library and a lintern, a formatter and documentation generator and a benchmarking library and a. Single app compiler. And I don't know, like 10 other things, all built into the same binary. And if you need something, you like. run dno help and it's there rather than having to scour npm for I don't know, you want to use, I was giving a talk recently where I was like a sort of preparation trying to set up ESLint to support JSX and to support TypeScript at the same time. And man, it's not fun, right? You install ESLint and then you have to go install a bunch of plugins and then you have to go install the JSX plugin and then you [00:23:00] have to create a config file and set them all up and then they conflict with each other. Ah, terrible. We just want this to work out of the box. So like one of the really core tenets of Fresh and, you know, is just make things work out of the box. and this means that if you want to have a performant web app, that should works out, work out of the box. And this means that sort of the core guiding pieces of the framework that we give you, they must be fast, and they must be composable in such a way that when they're composed, they're still fast. And this requires a lot of care in the way we design APIs and the way we expose APIs to users. But I think ultimately it's very worth it for users, right? Because this means it's much more difficult for you to shoot yourself in the foot because probably things will work out of the box. And one thing we realized, for example, was that islands were great in the sense that like you have ways to do interactivity without having to make your entire app interactive, but only parts of the app interactive. But we realized that for many applications that wasn't good enough because there was many applications where you would have a wrapper component that was interactive. Like maybe you [00:24:00] had like an accordion menu. Or something where we're like clicking the accordion to open and close it that's interactive, but then the content inside is static. And then islands weren't really good at this because islands meant that like everything under the island had to also be interactive. So that meant you like had to go ship your markdown renderer back to the. Client. So at some point we added support for passing Children to islands where the Children were rendered on the server and you could have these wrapper islands where everything outside was static and everything inside was static and just sort of that like middle component was interactive and this unlocked a lot of use cases for people. It was very intuitive to use. We had great feedback on it and this is the way we like to develop. Yeah, features are fresh and, you know, What are you guys looking for help from the developer community slash what's on the horizon that you guys are fielding in work to push out next? yeah there's a lot of work we've been putting in on performance recently. Like this JSX transform has been a significant push that we've gotten a lot of feedback from developers that as [00:25:00] their pages grow, the sort of server side rendering speed becomes subpar. Because of all these like function calls that are happening. So we invested some time and built like an end to end integrated solution to this, which to the user is transparent. Like you don't have to really change anything. Things just magically get faster. And we've put a lot of work in other places to make things faster, like in our router, in our static file serving and fresh. And yeah there's also a bunch of sort of feature work we're doing related to kinds of partial interactivity that are not island. So one of the features that we launched just recently was partials, which allowed you to replace part of the content of your page with a new server side render without having any client side components a good example of this is like you have a documentation page that has a sidebar where you can choose which page you're on, right? And then you have a header and a footer that are static. And then previously with Fresh, you would have a full server side rendering when you click to a different page in the [00:26:00] sidebar, right? Like you would, the header bar would have to get re rendered and the footer bar would have to get re rendered. The sidebar would have to get re rendered. And obviously the content gets replaced and this was like a whole page navigation. And with partials, we now support when you click that link, just swap swapping out the content, but you don't have to now ship the content renderer, the markdown parser to the client that can all still be on the server. And we just transparently. Can replace this content in the middle of the page. with very little effort from the developer. Reminds me of a like remix nested roots, similar. Yeah it's actually, that's a good analogy. They're pretty similar to that. But I think they're even more customizable. One of the features that are coming up soon is... A way to add partials, not just on navigation, but on other interactions. So for example, when you press a button we could fetch in a new bit of content and put that into the page, even if the URL doesn't change or when you'd select a different size. You have a merge [00:27:00] store or something some online store, and you have a size selector. You're selling a T-shirt, you have a size selector. You select a different size or a different color. You wanna fetch a different image and you don't wanna reload the page. You don't wanna change the URL. And this is all things that we'd like to support. Very soon here that are built on the same idea of partials. Awesome. Luca, we are getting up on time here. So let's hop into that section of the podcast where we remind people where they can listen to you, your postings, blogs, or whatever, wherever you are, where are you located online? I'm hanging around on Twitter occasionally still sometimes. You'll find me most just giving I don't know, talks online. , if you look up my name on YouTube you'll find some talks of mine. Yeah, and then I hang around on our Discord at, on the Deno Discord a lot. So discord. gg slash Deno. And I write a bunch of blogs for the Deno blog which you can find on our website, deno. com. And if folks wanted to go check out fresh, you can go over to fresh. deno. dev. And do you guys have docs and a starting [00:28:00] template there? That's great for beginners. If they've never seen it before. Yep. Yeah. You just click on the documentation button and it'll send you right to the getting started guide. Awesome. Luca, thank you so much for your time. It was great to have you on again, and we'll be looking forward to the next one. Thanks. It was a pleasure. Thanks for having me.