
Deno is a free and open source JavaScript runtime built on Google’s V8 engine, Rust, and Tokio. It’s designed to offer a more secure and standardized alternative to Node.js, with native TypeScript support. Deno 2.
Loading summary
Host
Deno is a free and open source JavaScript runtime built on Google's V8 engine rust and Tokyo. It's designed to offer a more secure and standardized alternative to Node js with native TypeScript support. Deno 2.0 just released and it's a significant update focused on improved compatibility with Node JS and addressing developer feedback. Some of the key features are backwards compatibility with Node JS and npm, native support for package JSON and Node modules, and a stabilized standard library. Luca Castonato is a software engineer for Deno, and he spoke about the project on Software engineering daily in 2023. We're excited to have Luca join the show again to talk about the many changes introduced in Deno 2.0. Kevin Ball, or K. Ball, is the Vice President of Engineering at Mento and an independent coach for engineers and engineering leaders. He co founded and served as CTO for two companies, founded the San Diego JavaScript Meetup, and organizes the AI in Action discussion group through latent space. Check out the show notes to follow K. Ball on Twitter or LinkedIn or visit his website Kball LLC.
Kevin Ball
Luca, welcome to the show.
Luca Castonato
Hey, thanks for having me.
Kevin Ball
Yeah, absolutely excited to have this conversation. Let's maybe start. Do you want to I know you've been on the show before, but maybe reintroduce yourself to our listeners, who you are, your background and what your role is with Deno.
Luca Castonato
Yeah, so I'm Luca Castonato. I work on Deno. I've been at the Deno company for four years working on all kinds of stuff there. Initially the website documentation, then I moved into working on the open source runtime. I then spent a year and a half leading our Deno deploy team that builds our cloud product and now recently have worked more on JSR and our new JavaScript registry. Well, yeah, not really Deno's project, but something that we've initially worked on and then yeah, Deno2 most recently getting that release stripped.
Kevin Ball
So let's talk about Deno 2. What's in it? What's in the box? What makes this a major Release.
Luca Castonato
Yeah, so Deno 2 is Deno's like we're ready for enterprise release. You can use Deno. So Deno's existed for, I don't know, I think we did our 1.04 years ago if I recall correctly. It was in 2020, May 19th. I don't remember but it's been a while and since then we got a lot of feedback from people that like Dito is a pleasure to use and they're really enjoying it. And it has like a bunch of built in tooling, which it does, but there was also a lot of feedback that was things along the lines of, oh, I can't use this at work because I have a giant node project that I can't move to. Fused Deno overnight. And that makes sense. So, I mean, we spent the first four years trying to figure out where's the ideal, like, what do we want to go to? How should the ideal JavaScript world look like? And then over the past year and a half, two years, we've been trying to figure out how do we make this work in a way that existing users with existing projects and existing frameworks and existing libraries can adopt Deno, sort of in an incremental way. And Deno 2 is the release that does that. You can create a next JS app on your computer and run it in Deno and it works with no changes needed. It just works. But you still get access to all of Deno's built in tooling like the Linter and the Formatter and the test runner and the coverage reporting and all that kind of stuff, the language server. But yeah, you can sort of do this on existing projects. You don't have to create a new greenfield app to get started with. So that's really what Deno 2 is all about.
Kevin Ball
Got it. So I know a few of the things that were making it a challenge to adopt because I also looked at it back in 2020 and I said this looks really cool. And also I could never pull this in. But do you want to maybe spell out what were the pieces that weren't there if you were using it before and that now if you come to Deno 2, they'll just work?
Luca Castonato
Yeah, absolutely. So one of the biggest things that Deno1 didn't really do is Node modules support. So the Node modules folder and NPM packages. So Deno has its own API surface that is modeled more after web APIs than after node APIs, because web APIs are generally more modern, right. They use Promises and Async, Await and Iterators, these kinds of things, and not legacy node streams. And a lot of those things unfortunately are new and thus there's a lot of old code that can't use them because they're using node APIs. So one of the things in denote2 is we added support for all the built in node modules. So think of like node, fs node, crypto, node, I don't know, v8, node, VM, node inspector, all these things that you can require or import into your code. Deno just implements them out of the box now with exactly the same API Surfaces Node, which means that if you have existing libraries that are written against those APIs, you can just use them now. So that was the first big part. And then the second big part was the ability to understand Node modules. So Deno and Deno 1 has an ability to load external modules, obviously, but it doesn't really use Node modules because we considered Node modules to be sort of clunky. You have to set up a package JSON. You have this folder in your repository that you need to deal with. You have a bunch of different lock files, you have four different package managers you need to choose from. It gets very complicated very quickly. So we had our own module solution that is based on web standards, based on HTTP imports, and more recently on JSR. But yeah, so in Deno 2 you can now also just import any NPM package. We understand your local Node Modules folder. So if you want to move over to this pure future where you don't have to deal with Lock files and Node Modules folders on your disk, you can. But by default we understand those out of the box now. And then the third thing is Deno now has a lot more package management built in. Previously users may have used import maps to Deno, which is a web standard, to help manage dependencies. But now Deno supports package JSON and it can like create your Node modules folder from your package JSON. So it like has the NPM install functionality baked in. We can read things from your private NPM registries, things like that. So it's. Yeah, really a lot of things that just make it easier to pick Deno up and stick it into your existing project and just have your existing project work.
Kevin Ball
Yeah, it's kind of the plays nice with others release in some ways.
Luca Castonato
Exactly.
Kevin Ball
Yeah, I'd love to dig into a few of those pieces. So one you mentioned sort of support for some of these built in Node modules and node APIs. And I'm curious, like, how do you see the evolution of server side JavaScript runtimes? Like, is there a server side standardization effort? Because browser APIs, everybody's trying to agree on what those look like. Server side, what is that story?
Luca Castonato
Yeah, that's a fantastic question. The answer to that is something called Winter cg, which is an effort that Cloudflare and Deno and some folks from Node JS as well. Some of the runtimes joined up to create a community group within Whatwig a couple Of I guess it must have been two years ago at this point to try to figure out what is the common subset of APIs that all these server side runtimes should have. And currently a lot of this common denominator is node APIs, but really in the limit. I don't think the world really wants to continue using Node fs APIs that were designed in 2008. Right. Like not a great time. So we're trying to figure out there two things. What web APIs are there that should work in servers and how should they work. So take like Fetch or the web crypto API. And then the other thing is what features are there not web APIs for that should work in server side runtimes interoperably using modern APIs. Think for example of TCP sockets or like things, how to read your environment variables or arguments passed to your script, things like that. Right. So those are Another part that WinterCG is trying to figure out. What is a common API that we can use here? And we're like an open community group in the W3C that anyone can join. And yeah, we have contributors from all over trying to figure this out.
Kevin Ball
And what would you say the sort of state of maturity is there? Like, is this something that all of the runtimes are already kind of in line with, or are we still hashing out and trying to get to some sort of consensus at all?
Luca Castonato
So different parts are different levels of maturity. I think we've collectively agreed what the baseline set of APIs is that everyone implements. Everyone implements Fetch now. Everyone implements response request headers, web crypto broadly as well, Maybe more obscure APIs like A2B, B2A sort of things like that. We've collectively agreed on those on the APIs that are like novel APIs that are not web APIs. I think there's more work to be done there. We don't have any released standards yet or has anybody implemented them? I think the closest thing we have is the sockets implementation in Cloudflare Workers, which is sort of going in the direction of sort of where we want the Winter CG socket API to go. But yeah, this is still very much something that is going to take a year, maybe longer to develop into something that can be actually shipped across runtimes. And a lot of this is not even just designing the API, but it's also writing tests to make sure that it works interoperably everywhere and then obviously getting user feedback, talking with all the database connection library authors. Think of your PSQL like Node postgres or MYSQL or, I don't know, those kinds of things to then go and actually adopt them in their libraries. That's the step after that. So, yeah, more work to be done. But yeah, we're making progress slowly. It's standards after all.
Kevin Ball
Absolutely. Well, and it's a measure of maturity. That working group exists at all.
Luca Castonato
Absolutely.
Kevin Ball
Means that we're more likely, I think, to see evolutions and more people trying to create these runtimes. Where do you see the sort of dimensions of competitiveness in runtimes? Why would someone choose a Deno versus a Node versus BUN versus workerd versus whatever?
Luca Castonato
Yeah, I think part of it is obviously like workerd, for example, you can't use workerd unless you're running on cloudflare. Makes it very easy. If you want to develop for Cloudflare, use workerity because that's your only option. And if you're not developing for Cloudflare, you don't use workerd because you can't use it. Right. But between these other ones, I think it's a lot more nuanced. It's like broadly, there's a lot of things that are very similar across them. I think one thing that's wildly different at this point is stability. Like Deno and Node have been out for a long time. The first commit to Deno was I think six years ago. @ this point all the bugs that we get are things that we've done recently is like, not old features. Like all the old features. They work perfectly fine at this point, they're stable. Another one is tooling. Right? Like Node has some tooling within, but it's much less than, let's say Deno. Deno has a built in formatter and a built in linter. It has benchmarking tooling, it has a built in language server, it has TypeScript support out of the box. I could go on about this. It has like compiling to a single executable. We've had that for nearly four years at this point. So I think that's a lot of that. And then the other thing is, are there things around it that would entice you to use one runtime over another? So, for example, are there libraries that you would like to use that favor a particular runtime or are there frameworks that favor a particular runtime? For example, if you want to use Fresh, which is a web framework that Deno has been working on, you probably want to use Deno because that's what it was built for. But yeah, conversely, I don't know if you're using Elysia, that may be something you want to use Bun with, because that was built for that. But yeah, really, I think. I don't know I'm going to use Deno, but I'm also biased. So everybody make up your own mind. Try out things. They're all so easy to use now.
Kevin Ball
Totally. Well, and one of the things that you alluded to there, which is a kind of perpetual question in the JavaScript ecosystem, is like the extent to which you get everything together in one. You know, Deno bundles a lot of pieces together for you versus are you doing mix and match and are you making your own choices on all those different pieces? I'm kind of curious how Deno approaches this question of what should be bundled with the runtime versus what belongs in user space.
Luca Castonato
Yeah, so the inspiration for why Deno has all these things built in is not the JavaScript ecosystem. Surprise, surprise, it's the Go ecosystem, the rest ecosystem. These are languages. GO was released I think the same year as Node JS. But unlike JavaScript, it has a bunch of built in tooling. Like in its tool chain, when you install Go, it has a built in formatter, it has a built in linter, it has a built in package manager, it has all these things that come right out of the box and it turns out that people really, really like this. If you ask people what is great about using Rust, one of the top answers is going to be like, it just works out of the box, right? Like I can have a GitHub action script that installs cargo and then that comes with a formatter and a linter and a testing framework and a benchmarking framework and a package manager and like it compiles my code and all that kind of stuff all at once. And that's really what we were going with, having all these things in Deno natively. I think the question of what do we actually decide to include is what do we think we can do? Well, formatting, we think we can do very fast, very good formatting. So that's something that we built in. We think we can do the same. For linting, testing, benchmarking. In Deno 1, we had a bundle sub command that would take your JavaScript code or TypeScript code and bundle it into a single file. But we realized that this was not where we wanted it to be. Bundlers are incredibly complicated and we did not think that we could at this time at least offer a competitive bundler built into deno. So in Deno 2, we removed it because we don't want to ship something that's sort of half baked and doesn't really work very well. We want to ship things that you can rely on them. You don't have to think about whether you should use them or not. You can just use them because they work, they're stable. And our bundle was not that. So, yeah, we removed it. But other than that, I think, yeah, things that we think we can do well, those are things that we'll include.
Kevin Ball
Yeah, things you can do well. And you mentioned a little bit the Simplicity piece, which reminded me of, I was looking at, I think it was a release YouTube video you all did, where you were really going after Node around Simplicity. I'm kind of curious, like, as you absorb more and more pieces to be able to be Enterprise ready or plug and play, how are you approaching sort of keeping the experience simple?
Luca Castonato
Yeah, I think the biggest part of that is having good defaults, right? Like our defaults are. Take for example, TypeScript. When you set up a TypeScript project in Node, you don't just have to open a file and write some TypeScript code in it. You have to set up a tsconfig file and you have to make like 18 decisions, right? You have to decide, do I want strict mode on or off, what libs do I use? What version of Types node do I use? Like, there's an endless amount of configuration that you have to do before you can write the first line of code. Which makes things very not simple because that means between two projects, even in the same company, you can have wildly different configurations. And like, before you can start reading code, writing code, you first have to go look at all the config files to see how this project is set up. That is one of the things that Deno completely eliminates. Like, we have a config file that you specify dependencies. Then if you want to, you don't have to, you can. And other than that, you don't have to have anything in there for like a standard project, right? Like, you don't have to set up your TypeScript config. There's a default TypeScript config that all Deno projects use that is like all the options you should use, not the options you shouldn't use. We've made this decision for you, don't worry about it. The other part of it is if there's parts of Node that we sort of need to put into Deno for backwards compatibility, we try to shield you from them if they're bad in Some way. We don't, for example, encourage you to write CJS code in your project. We encourage you to write TypeScript code with ESM. And that doesn't mean you can't use CJS. You can, but we very actively steer you in the direction of using ESM to sort of adopt modern tooling, use libraries that are actively maintained and not outdated. We have a lot of documentation that tries to guide you to do things in modern ways. Like all of our documentation on if you look up, like, how to make an HTTP request from Deno, it's going to show you how to do with Fetch, not with Node HTTP, because that's the future, right? Using fetch, not using Node HTTP. A lot of things like that just make things much simpler.
Kevin Ball
Yeah, you sort of alluded to this when you talked about the TypeScript versus CJS, but I'm curious. So a lot of very opinionated frameworks will provide you an escape hatch where they say, we're going to have these defaults for you. We highly recommend you go with it. But if you really have some strong reason to change it, here's how you do that. What does that look like in Deno?
Luca Castonato
Yeah, I mean, we, for many things have that same option. There's a, like, as I said before, we really want you to Write ESM and TypeScript, but you don't have to. You can write a CJS file and you can write like JS file rather than a TS file if you want, and we'll let you do that. And if you really want to turn off, like, I don't know, trying to think of some obscure typescript option. No implicit any. I don't know, you can go into your Deno config file and find the place to turn that off, but you shouldn't. It's therefore like you're migrating an existing project and you temporarily need this for a moment. But stop, don't do it. Stick with the defaults.
Kevin Ball
Yes, don't do that. Bad. But that is really important for migrating legacy stuff, because you never know what you're going to run into there.
Luca Castonato
Yeah, no, absolutely. And I mean, that's really why we've added a lot of these escape hatches in Denote two. Denote two, for example, has the ability to work both using a Local Node Modules folder that was created by Deno, Work with Local Node Modules folder that was created with like NPM or PNPM or yarn, or work with our Global Node Modules folder where you don't see the Node Modules folder at all because it's like hidden in a cache directory somewhere. And the default is to use the global one, because that's nice and clean and you don't have to deal with it. But sometimes if you're, like, in a existing project that has a complicated PNPM workspace or, like a YARN workspace with Yarn resolution plugins, or, I don't know, crazy things, right? Crazy big project with weird configuration, Deno will just accept that, and it will work with your existing nodemodules folder that was not set up by Deno as an escape hatch. And at some point, if you decide, okay, I'm all in on Deno, you can start making that move, right? You could switch over from Yarn workspaces to Deno workspaces, and then have Deno install your Node Modules folder and maybe eventually completely get rid of all your local Node Modules folders and just have a global one. But it's not something we force you to do right away. You can sort of adopt it incrementally and then over time move to this nice, pristine world of Node Modules folders. Can you tell I don't like Node Modules folders?
Kevin Ball
I can't. Well, and let's talk a little bit about modules and registries and things like that, because another big thing that came out this year was, or at least that I saw an announcement about this year was jsr. What is that? Why is that? And how does that interact with Zeno?
Luca Castonato
Yeah. So, I mean, the reason Deno was created initially was Ryan Dahl, the creator of Node, came back to node after 10 years and thought, okay, this has gotten too complicated. And, I mean, a similar thing happened with npm. So NPM is obviously Node's package management system, where you publish your packages. And there's been a lot of innovation on the client side, the package manager side of this. We initially had only npm. We got yarn, we got pnpm. Now there's a bunch of other tools that will also let you install NPM packages faster, better, more securely, whatever. But we really didn't have anybody that was pushing NPM the Registry. Like, if you look at NPM the Registry, they really haven't changed in 10 years. Right. The last major change they did was added a little TS icon in the top left to packages that have type definitions. And that was, what, like, three years ago? And then they have a Files tab that's been in beta for probably also three years, that when you click on a file, doesn't put the file in the URL, so you can't, like, link to it. You can tell that there's not been like a lot of active investment in npm. So that's what JSR is about. JSR is a new package registry. So the server side part of the packaging story where you can publish your packages to and jsr natively supports TypeScript. Jsr packages can import from npm, they can be imported by NPM packages, but yeah, they natively support TypeScript. They have built in documentation generation, they have a much more secure publishing flow that uses oidc on GitHub Actions to sort of prevent people from accidentally leaking private access tokens which is, yeah, supply chain security. I'm sure many people are worried about that in the JavaScript space. It's really a head on attempt to try to fix all the things that NPM hasn't done in the past 10 years. But yeah, doing it in a sort of backwards compatible way where you can import JSR packages from NPM and import NPM packages from JSR so that these things can work together and it's not like a stop the world and migrate sort of thing.
Kevin Ball
It reminds me a lot of Pica, which I don't know if that project ever went anywhere, but I remember talking with Fred K Shot or listening to a podcast with him trying to do this where at least in that world part of it was trying to push to being ES modules first. And it Sounds like with JSR similarly pushing for TypeScript first.
Luca Castonato
Yeah, like JSR is very much TypeScript first, JavaScript supported by TypeScript first and then ESM only. So you cannot publish CJS to JSR for example, we've made a hard cutoff like stop CJS development instead ESM only going forward. And that allows us to do incredible things that you could never do. If you have like have to do with CJS and ESM and not typescript like documentation generation. The fact that for every package that is published to jsr, we can automatically generate documentation for every symbol for every export in your package. It's huge. It's like Rust has had this for 10 years, Go has had this for 10 years and in JavaScript we've never had this because NPM didn't implement it and it's not an open source project so nobody can implement it for them. Right. It's like a closed source private thing that GitHub is keeping alive. And JSR is yeah, different. It's an open source project, it's hosted by the Deno company, but really it's a very open project where you can contribute things and if you Want to have a new tab on the package page that shows you some cool new information. It's a bit of pr, right? It's not behind a locked door. And you need to become a Microsoft employee first.
Kevin Ball
Yeah. So you mentioned that you can install NPM packages with jsr. How do you deal with NPM packages that were not TypeScript? For example, are they not installable via JSR or like, how does that work?
Luca Castonato
Yeah, so NPM packages, you don't install NPM packages like through JSR or JSR packages through npm, but rather they're complementary in the way that NPM packages can rely on JSR packages like they could depend on JSR packages and JSR packages can depend on NPM packages. But ultimately it'll be your package manager like PNPM or YARN or even NPM itself that pulls the JSR packages from JSR and the NPM packages from npm. And this is just done through like you can think of JSR as like a private registry of sorts for NPM if you're using npm. And that way you can use all existing NPM packages, whether they're TypeScript or not. But you only get the features, the documentation generation, for example, if you're actually publishing to JSR. So if you're publishing your TypeScript source.
Kevin Ball
Code to JSR, that makes sense. This episode of Software Engineering Daily is brought to you by leanware. Struggling with development teams that say yes to everything but deliver on nothing. Leanware offers a refreshing approach. They're a Colombia based team delivering top tier software development with full transparency and world class engineering standards. They've honed their craft over nearly five years, sticking to technologies where they have senior expertise. This means no compromises on quality ever. Their C level executives are always accessible, ensuring seamless communication and a genuine partnership. Plus, being in a similar time zone to the US makes collaboration effortless. Don't settle for less. Partner with leanware for software development done reliably. Visit leanware Co or see the show notes to get started. That's leanware Co leanware redefining software development with exceptional quality and realistic expectations. You mentioned documentation generation. You mentioned some of the supply chain security. Are there other benefits of going to JSR over npm?
Luca Castonato
Yeah, it's a lot simpler. I mean, at least in my opinion. You can create a package by like the simplest package is a single TypeScript file and a JSR JSON that has a name, a version and an exports field. And the export field is just the path of your TypeScript file. And that's it. There's no tsconfig to set up. Very importantly, you publish the typescript. You don't have to publish like the JavaScript+d.ts files. No, you publish the typescript so you can publish a new package in a couple minutes rather than having to go through and set up the configuration and make sure that it works across CJS and ESM and all these things. Right? JSR just handles all that for you. So I think a lot of it is like really, it makes your life a lot easier if you don't have to deal with all this configuration kind of a recurring topic.
Kevin Ball
Recurring topic. Well, is that showing up anywhere else that we haven't talked about yet for this?
Luca Castonato
Yeah, sure. Denodeploy, we can talk about that very briefly. Is our cloud hosting product. Same sort of deal, right? You can like write your JavaScript code, put it in a GitHub repository and just link it to Deno deploy and it deploys and you don't have to deal with configuration. Like a lot of the things that we do at Deno are like this. Our linter is like this. You don't have to configure your linter, you don't have to configure your formatter, you don't have to configure your tests, you don't have to configure your editor, you don't have to configure your package manager. It just works out of the box and you can tweak it if you want to, but don't just stick with the defaults because the defaults are pretty good.
Kevin Ball
Speaking of Deno deploy and I think one of the interesting things that you all have is you have this dual identity as open source projects, multiple jsr, Deno, all these different things, but also for profit company. And I think one of the challenges going back to NPM that they faced is when they ran out of started running out of money and then Microsoft absorbed them and then stasis ensues. So how is Denoise making itself sustainable here?
Luca Castonato
Yeah, I think the answer is different for different parts of Deno. I'll start with jsr. So with JSR we don't want JSR to be a Deno product. And really JSR is not a Deno product. It just happens to be developed by a bunch of Deno developers. But that's beside the point really. JSR is going to go into a foundation at some point. We don't have all that settled yet, but it will go into foundation at some point. It's going to be a community project that is owned by the JavaScript community as a whole that does not have a single point of failure. Right. The Denote company fails. JSR is not going anywhere. Not that the Denote company is going to fail. We're going to do great.
Kevin Ball
But it's always worth having that escape path, right? Because you never know what will happen.
Luca Castonato
Yeah, exactly. And I think it's also really helpful for a foundational part of the ecosystem, like a package registry, to not be owned by a single entity, but instead be something that can be shared across many different foundation members. Right. Something that can be governed in an open way. But to go back to your original question, like how is the Deno company itself remain sustainable? I think that's also a great question because I think we've seen in many open source projects, like I almost redis, for example, recently, that this can go wrong really quickly if you're not careful. And I think the way to avoid this is to sort of have a solid idea of how the company is making money versus how the open source runtime is operated. And for the Deno company, we do not make any money off the open source runtime. Right? There's no like pay to play features in Deno. There's no like multi cluster networking mode that you can only enable if you pass a Deno token flag with a secret key or something. No, this doesn't exist. Right. The Deno runtime is completely open and then the Deno company makes money through hosting. We do consulting for enterprises, but also we do hosting and the hosting is for example, things like Netlify's Edge function product is under the hood. All Deno systems, right. It's built on the Deno runtime hosted by us for Netlify. And there's other companies like Deco cx, which is one of the fastest growing E commerce platforms in Brazil that are running their entire infrastructure on Deno. And these are the ways we're going to make money. And we are making money, right? These are different from the open source runtime. They are ways that we can monetize the use of the open source runtime, but not monetize the open source runtime itself. Deno is not going to be an open core thing where you have an open core and a paid set of enterprise features around it. But yeah, you have an open source runtime that is free to use MIT license, you can do whatever you want with it. And then we happen to offer hosting and with that we financed the continued development of the open source Runtime, do.
Kevin Ball
You see a world in which Deno itself moves into a foundation?
Luca Castonato
I mean, everything's possible. I don't envision that happening right now. I think the way the model works right now is pretty good. I don't think there's any governance issues within Deno right now that would require, that would be solved in any way by moving into foundation or anything like that. I think we work very well. We ship features on a very regular cadence, bugs get fixed. I'm not worried about that. But I mean, yeah, it's obviously always a possibility that things change in the future. So maybe, I don't know. But also Deno's open source, MIT licensed, right? If you ever don't like something that we're doing, there's this big button in the top right of all GitHub repos called fork.
Kevin Ball
Yeah, absolutely. What does the future of Deno, the open source runtime look like? What types of features are you working on? What are you excited about?
Luca Castonato
Yeah, so a bunch of stuff. I think initially the first couple of months, we're going to be preparing for our first long term support release, which is another thing that we announced with 2.0, which is coming in about a month. And we're just going through all of the issues that are being reported after 2.0. Right. Major release and people have tried like with the weirdest node projects that you could possibly imagine and there's edge cases that we need to fix. So we're going to spend a couple months working on that, but we're also going to be working on new features to Deno itself. I said that we removed the bundler from Deno 1 because we didn't think it was good enough. We're thinking about how we can add that back in a way that is actually competitive. Right where it is not like terrible, but it is great and is something you can actually use for your systems. And other than that, obviously we're increasing or improving all of our other tooling all the time. We're looking into how to do plugins for the Linter right now. We would love to work more on some performance work. Like our HTTP server, for example, is already twice as fast as Node, but we still think there's room to grow. We're looking more into how we can make it easier to adopt Deno in enterprise environments where you may be using Kubernetes or something like that, how to integrate it with tracing and telemetry. These are things we're thinking about. But yeah, I mean our issue tracker has 1800 open issues right now. So yeah, we're not going to run out of work anytime soon.
Kevin Ball
Speaking of that and the fact that it's open source, how much of the development is done in house versus how much of a sort of community development team is there?
Luca Castonato
Yeah, so I think the majority of the work is done by Deno, by Deno employees. We're a company of, I want to say 25 at this point, where maybe half of them work pretty much exclusively on the open source runtime. But there's also a lot of people that have been contributing to the Deno standard library, which just went 1.0 as part of the Deno 2.0 launch, that have been contributing to the permission system in Deno that have been contributing to help output to documentation. If you look at our release blog post, there's always a section at the bottom of the blog post that's like thanking everyone that's contributed to the release. And yeah, they get longer every time we do a release. So I'm very happy about that.
Kevin Ball
For folks who are interested in getting involved in that. What does the dev environment look like for working on Deno itself?
Luca Castonato
Deno is built in Rust, so it's actually very easy. You just check out the repository and run Cargo build. Also have to install Rust first, so you have to. But I mean, other than that, it's pretty easy. There's a lot of Deno though that's not written in Rust. I know Rust can be a bit of a challenge for many people because it's a completely different language to JavaScript, but a lot of Deno is actually written in JavaScript. A lot of our web APIs are implemented in JavaScript. Essentially anything that's not native IO is implemented in JavaScript and there's always things to do there. In our node compatibility, a lot of things are implemented in JavaScript as well. Our standard library, which lives outside the Deno runtime but provides a bunch of utilities that any JavaScript project can use, including non Deno ones that's written entirely in TypeScript as a Deno project published to JSR. That's also something that's super easy to contribute to. But obviously our docs as well always love docs work. We have an example site that you remember what the URL is. I think it's docs.deno.com examples where currently we have a thing where I think you get some free stickers for every example that you write or a shirt I don't remember. You have to check our Twitter. I Think it's announced there somewhere, but yeah. And then also we have a discord. So if you have questions about contributing, you can always hop on there and ask questions and there's members of the team that are there to help you and help answer questions.
Kevin Ball
So actually, first clarification question. So you mentioned, you said rust, you have JavaScript, not TypeScript for some other portions of it, and then TypeScript for the standard library.
Luca Castonato
Yeah. So the standard library is all written in TypeScript. Do you know runtime is written partially in JavaScript, partially in TypeScript, and a lot in Rust.
Kevin Ball
What's the reason for not having it all in TypeScript?
Luca Castonato
Historical reasons, mostly. When we started out it was. So one of the challenges here is that we don't really want to rely on a JavaScript runtime to build the JavaScript runtime. You don't want to have a circular dependency because that means you can't build on new platforms. But that also means that you cannot use TSC to compile your TypeScript because TSC is written in JavaScript. So if you don't have a JavaScript runtime, you can't transpile your TypeScript with TSC. And when we started out with Deno, there was not really any good way of transpiling TypeScript to JavaScript that was not TSC. Remember, this is like six years ago, so now that's no problem. Now we have typescript transpilation in Rust and we can do that all natively, which is why we now have some parts of the code that are written in TypeScript and are being transpiled to JavaScript during the build using Rust. But a lot of the code that was originally written six years ago, four years ago, three years ago, just didn't have the luxury of having a Rust TypeScript compiler yet that we could transpile with. So those had to be written in JavaScript because we just didn't have the ability to transpile as part of the build pipeline. Because, yeah, we can't have circular dependencies on the JavaScript runtime.
Kevin Ball
Unfortunately, that makes sense. And how do you all decide happening in Rustland versus what's happening in jsts?
Luca Castonato
It's mostly a question of like, do you need Rust to do it as step one? So like native IO talking to the kernel about sockets or files or, I don't know, file watching, all those kinds of things. You can't implement a JavaScript runtime on top of a JavaScript runtime because something needs to expose like the kernel syscalls for opening a file or Something like that to JavaScript in the first place. Right. And that's Rust. That's what Rust is for us. A lot of our module loading, our typescript transpilation, our linter and formatter, those are also written in Rust. On the other hand, all of the sort of API surface that you touch. So when you write Deno, read file, the thing that checks whether the first argument that you passed is a URL or a string, and then dispatches it accordingly to the kernel, that is done in JavaScript. So you can sort of think of anything that requires native access or requires very high performance in some way that's written in Rust. And everything else that's sort of the glue between the user and the native syscall that's written in JavaScript. Our fetch implementation, for example, is written pretty much entirely in JavaScript, with the exception of the thing that actually sends the network request out. But all the handling around how streams work and how headers work, and what a response body is and what a request body is, and all those things, those are all implemented in JavaScript or TypeScript.
Kevin Ball
That makes sense. And are there. Like, when you cross that boundary, when you're going back and forth, do you have to copy all of your data over, or are you able to expose data that's living in JavaScript land directly to the kernel? How heavy is that boundary?
Luca Castonato
Yeah, it really depends. Honestly, I can go into a lot of detail here, but I think generally it is faster to call between two JavaScript functions or to call between two Rust functions than it is to call from JavaScript to Rust as a blanket statement. The reason for this is like, strings, for example, are represented differently in JavaScript than in Rust. In JavaScript they're WTF16, in Rust, they're UTF8. You need to convert between them when you call from one into the other. But then there's also certain things like APIs, for example, that only deal with numbers, or only deal with booleans, or deal only with certain types of strings. Those are essentially free. You can't see this if you're listening to the podcast, but I just finger quoted me, or I forget what, I don't know what that's called. Whatever.
Kevin Ball
Air quotes.
Luca Castonato
Air quotes, that's right. Yeah. So numerical things are essentially free to cross between JavaScript and Rust. But yeah, strings, objects, those are more expensive. And then when you get into things like array buffers, it really depends on, for example, is it a synchronous call, is it an asynchronous call? Those have different costs. There's a giant matrix of like, if you do this, it becomes very slow. If you do this, which is essentially the same thing but slightly different, it becomes much less slow. So do this thing instead. This is one of the biggest things that our performance team has been working on for a long time, is reducing the cost between JavaScript and Rust because we have like 800 different call sites. I think it's 800, yeah. Between JavaScript and Rust. And if you can make all of those 1% faster, then pretty much the entire runtime has gotten 1% faster. Right. And you've made a code change in one place, which is really cool. So we continuously make changes to, for example, how to transfer strings, how to transfer unit data, arrays, all these things. As an example, there's some work that we're currently doing that will make all transfers of strings from JavaScript to Rust essentially two times faster across the entire runtime. Every single API that deals with strings will have its overhead reduced by some amount purely due to like a single change in a single place.
Kevin Ball
Yeah, two times is a lot. So you're like removing a copy somewhere or something like that?
Luca Castonato
Pretty much, yeah. We did some work with Igalia, which is a open source consultancy, on upstreaming some changes into V8 that make it. They change how V8 exposes strings to embedders that let us use these strings in a way that is more ideal to us. Right. Previously, like, you always had to copy a string out of V8. Now there's a lot of cases where you don't have to copy the string and you can just use the string AS is, while V8 retains ownership of the memory. And this requires a long breath. Right. This is work we started maybe in March, I want to say, or in February, and it's now showing fruit, but it's going to make everything faster. So it's totally worth it.
Kevin Ball
Talking about this boundary more, I know that node has this whole like node API standard if you want to build like native plugins or things like that. What does that look like in Rust? If you want to connect to some sort of native written library or what does that look like in Deno? I guess it doesn't have to be Rust.
Luca Castonato
Yeah, the first way of doing it is to just use an API because actually Deno also supports an API because otherwise a lot of our. A lot of the node packages wouldn't work. So yeah, as I said, like Deno2 needs to work with existing libraries and a lot of existing libraries use an API. So Deno implements an API that's step number one. An API is not ideal though in many ways. There's ways to do faster foreign function interfaces between JavaScript and a native API. So there's also Denoffi, which is a way to do FFI with the standard C FFI interface. And there's some libraries. For example, There's a Deno SQLite library that uses FFI that is twice as fast as the node library of SQLite that uses an API just because it's using a different boundary between the two. Right. The JavaScript part and the Rest part and the Native part are the same. It's just call between them that changes. And yeah, that works pretty well. And it also works really like our FFI stuff. Works really well with Rust. I think there's some tools that one of my co workers has written which I think is called Deno Bind gen that lets you write some Rust code and then during the compilation it'll generate a file for you that you can import in deno and a TypeScript header file that types your entire API essentially from JavaScript. You don't even have to deal with the fact that you're calling it to Rust. It just makes it feel very native.
Kevin Ball
That is nice because I think, yeah, with a. If you're doing a cffi, you've got to make explicit what all those types are. But Rust has types like. Should be able to take advantage of it. Yeah, awesome. What else would you like to talk about today? We've got a few minutes left, but I think I've hit all of my big questions.
Luca Castonato
We could talk about Fresh, which is our web framework.
Kevin Ball
Let's do it.
Luca Castonato
Yeah. So Fresh is a web framework that we've been working on for maybe a year and a half that is sort of slowly been slumbering over the last six months or so while we were working on Deno. But it's coming out of Slumber mode and fully into Fresh to release mode. So for those who don't know, Fresh is a web framework that uses Preact under the hood. It looks somewhat similar to maybe Lake Remix or Next js, if you're familiar with those. So it has server side rendering as a native feature, but what sets it apart from Remix or Next JS is the fact that we don't ship all of your JavaScript to the client. So in next JS, the way that next JS works is you do an initial server side render and then you send the entirety of all the JavaScript that was required to do that server Side render to the client and you do the same render again on the client. I mean, that can be inefficient.
Kevin Ball
Yes. The uncanny hydration valley you run into it.
Luca Castonato
Yes, yes. So Fresh doesn't do that. Fresh does server side rendering only essentially in the beginning. And then you can opt certain components, so like components one by one into rendering on the client as well. And we call those Islands. So you can think of these like as islands of interactivity in a sea of static content that was sort of server side generated. And this works really well because it means you can have E commerce sites that have a interactive cart, have an interactive add to cart button, have an interactive carousel and everything else is static. You don't need to ship a markdown renderer to the client. There's a bunch of stuff you don't need to ship to the client. Right. You get much faster first load performance, you drain your user's battery life much less. Because they don't have to execute a bunch of JavaScript. They didn't need to. And yeah, Fresh is like a very ergonomic way of doing this. You can create routes in a file system router thing like routes folder called file index tsx and it gets rendered when you hit the index of the page. Right. And to make something an island, you just put a component into the folder called Islands and now it's an island. It's all very simple.
Kevin Ball
Sounds a lot like Astro.
Luca Castonato
It has a lot of very similar principles to Astro. I think Astro and us sort of both did islands at roughly the same time. There's a couple of things that are different. Fresh is like very. Would feel very familiar to people that have used Remix or Next in the past because it leans very much into JSX and it doesn't have its own file format. But that also means that you can't use like Vue components or Svelte components. With Fresh, it's really preact only. But yeah, I mean, all the web frameworks are the same nowadays anyway, so choose whatever you fancy.
Kevin Ball
Yeah, I mean, this idea of sending less JavaScript, I think, has gained a lot of momentum these last couple of years. And so we have different takes on that. Islands being one of them. So you said file based routing, similar to how Next at least used to roll, though now they have their app router and all of that. You've got Islands architecture. It looks like it's kind of signals based, Is that correct?
Luca Castonato
Yeah, we support preact signals out of the box. You can do things like create a signal on the Server, pass them to two separate islands, and then when the islands rehydrate, the signals are still attached on the client, so the two islands can communicate with each other. Which is like a very core part of how to make sort of interactive applications where you have islands across multiple parts of the page. Supports TypeScript out of the box with no configuration. Obviously it's a Denote project.
Kevin Ball
There's a little bit of a trend here.
Luca Castonato
Yeah, it's weird how there's no configuration thing keeps sliding in everywhere. But yeah, it uses web APIs for its request and response objects. Like, integrates very seamlessly with features.
Kevin Ball
Works with other runtime frameworks besides Deno.
Luca Castonato
Well, I don't know. Maybe if somebody wants to try. I haven't tried.
Kevin Ball
Fair enough. Nice. Yeah, that looks good. And then in terms of. So any sort of React based library that works with Preact should work with Fresh.
Luca Castonato
Yeah. Yeah. And you can use Preact Compat. If you have some library that actually relies on React, you can just switch it out to use Preact Compat instead, and then it'll continue to work with Preact.
Kevin Ball
Nice. And last question, I assume, like so many of these other things, it's fully open source.
Luca Castonato
Absolutely, yeah. Denoland fresh. On GitHub, where we're about to do a 2.0 release, there's a roadmap. Please try it out and give us your feedback.
Kevin Ball
Awesome. Well, Luca, this has been super fun. I feel like I have a few things to go and try out now, which is great. Anything you would like to leave people with before we say goodbye?
Luca Castonato
If you want to try out Deno, we have a great new tutorial series on YouTube if you're interested in learning. Published by Eve. Does a bunch of cool tech things. Check it out. YouTube.com Denoland Sounds good.
Kevin Ball
I think. Then we will wrap with that. Everybody try Deno because life is too short to be configuring things.
Luca Castonato
Yep.
Kevin Ball
All right, cheers.
Episode Summary: Deno 2.0 with Luca Castonato
Introduction
In this episode of Software Engineering Daily, host Kevin Ball engages in an in-depth conversation with Luca Castonato, a seasoned software engineer at Deno, to explore the significant advancements introduced in Deno 2.0. Released on December 18, 2024, Deno 2.0 marks a pivotal update aimed at enhancing compatibility with Node.js and addressing extensive developer feedback. This episode delves into the key features of Deno 2.0, the challenges it overcomes, and the future trajectory of server-side JavaScript runtimes.
Deno 2.0 Overview
Luca Castonato begins by outlining the substantial updates in Deno 2.0, emphasizing its readiness for enterprise deployment. He highlights that since its initial release in May 2020, Deno has garnered positive feedback for its built-in tooling and developer-friendly environment. However, early adopters faced challenges integrating Deno into existing large-scale Node.js projects. Deno 2.0 addresses these issues by enabling seamless integration with existing Node.js applications.
“Deno 2 is Deno's enterprise-ready release. You can use Deno with your existing Node.js projects without needing to make significant changes. It just works.” — Luca Castonato [02:12]
Key Features of Deno 2.0
Backward Compatibility with Node.js and NPM:
“You can create a Next.js app on your computer and run it in Deno, and it works with no changes needed.” — Luca Castonato [02:12]
Native Support for Package Management:
package.json and Node modules, simplifying dependency management and reducing the complexity associated with traditional Node.js setups.“Deno now understands your local
node_modulesfolder created by NPM, making it easier to integrate with existing projects.” — Luca Castonato [03:56]
Stabilized Standard Library:
Overcoming Adoption Challenges
Kevin Ball probes into the specific barriers that hindered the adoption of Deno before the 2.0 release. Luca identifies the absence of Node modules support as a primary obstacle. By implementing Node APIs and understanding existing Node modules, Deno 2.0 facilitates a smoother transition for developers with established Node.js projects.
“Deno 2 now supports all the built-in Node modules, such as
node:fs,node:crypto, and more, allowing you to use existing Node libraries seamlessly.” — Luca Castonato [03:56]
The Future of Server-Side JavaScript Runtimes
The conversation shifts to the broader landscape of server-side JavaScript runtimes. Luca discusses the WinterCG initiative, a collaborative effort involving Cloudflare, Deno, Node.js contributors, and others under the W3C umbrella. The goal is to standardize server-side APIs, mirroring the consensus-building seen in browser APIs.
“WinterCG is working towards a common subset of APIs that all server-side runtimes should implement, moving away from legacy Node.js APIs to more modern, web-standard APIs.” — Luca Castonato [06:43]
State of Standardization:
“We've collectively agreed on a baseline set of APIs like Fetch and Web Crypto, but there's still work to be done on more novel APIs.” — Luca Castonato [08:15]
Competitiveness Among Runtimes
Kevin and Luca delve into what sets Deno apart from other runtimes like Node.js, Bun, and Workerd. Key differentiators include:
Stability:
“All the old features in Deno work perfectly fine at this point; the bugs we encounter are typically related to recent changes.” — Luca Castonato [10:02]
Built-In Tooling:
“Deno has built-in tooling like a formatter, linter, test runner, and TypeScript support, eliminating the need for third-party tools.” — Luca Castonato [12:08]
Ecosystem and Frameworks:
“If you want to use Fresh, a framework built for Deno, it makes sense to use Deno as your runtime.” — Luca Castonato [10:02]
Bundling vs. User Space: Maintaining Simplicity
Luca explains Deno’s approach to bundling tools, drawing inspiration from Go. The emphasis is on simplicity and reliability, with good defaults that minimize configuration overhead.
“We provide good defaults so developers don’t have to worry about extensive configuration, unlike Node.js where setting up TypeScript can be cumbersome.” — Luca Castonato [14:23]
Deno 2.0 removes the built-in bundler from the initial release due to performance concerns, committing to reintroduce a competitive bundler in future updates once it meets quality standards.
Migration Flexibility in Deno 2.0
Deno 2.0 offers flexible support for existing Node.js project structures, allowing developers to incrementally adopt Deno without disrupting their current workflows.
“Deno 2 can work with Node Modules folders created by NPM, PNPM, or Yarn, giving you the flexibility to migrate at your own pace.” — Luca Castonato [17:23]
This feature is particularly beneficial for large projects with complex dependency management, enabling a gradual transition to Deno's optimized environment.
JSR: A New Package Registry
One of the standout discussions revolves around JSR, Deno’s new package registry designed to address the shortcomings of NPM. JSR offers several enhancements:
TypeScript First Approach:
“JSR is TypeScript first, allowing you to publish TypeScript packages without needing separate declaration files.” — Luca Castonato [22:35]
Enhanced Documentation and Security:
Backward Compatibility:
“JSR can import NPM packages and vice versa, ensuring backward compatibility and a smooth migration path.” — Luca Castonato [22:35]
Benefits Over NPM:
Sustainability and Open Source Governance
Addressing the sustainability of the Deno project, Luca outlines the strategic separation between the open-source runtime and the company’s revenue streams.
“The Deno runtime is completely open-source with no monetized features. The company makes money through hosting services and consulting.” — Luca Castonato [26:58]
JSR Governance:
“JSR will be governed by a foundation, making it resilient and community-driven, independent of the Deno company’s fate.” — Luca Castonato [26:52]
This model ensures the longevity and independence of critical infrastructure components like the package registry.
Future of Deno
Looking ahead, Luca shares exciting plans for Deno, focusing on enhancing performance, expanding tooling, and improving enterprise adoption.
Performance Enhancements:
“We're working on making string transfers between JavaScript and Rust twice as fast by optimizing how V8 exposes strings to embedders.” — Luca Castonato [38:53]
Tooling Improvements:
Enterprise Features:
“We are continuously improving our tooling and working on features that make adopting Deno in enterprise environments easier.” — Luca Castonato [29:00]
Community Development and Contribution
Luca emphasizes the importance of community contributions to Deno’s growth. He explains that while the core development is primarily handled by Deno employees, the community plays a significant role in expanding the standard library, enhancing permissions, and improving documentation.
“The majority of the work is done by Deno employees, but we have a thriving community that contributes to the standard library and other aspects of the project.” — Luca Castonato [31:24]
Getting Involved:
Cargo build.Fresh: Deno’s Web Framework
Towards the end of the episode, Luca introduces Fresh, Deno’s web framework designed for efficiency and performance. Fresh leverages an “Islands” architecture, allowing selective hydration of interactive components while keeping the rest of the page static.
“Fresh uses an Islands architecture, where only specific components are interactive, reducing the amount of JavaScript sent to the client and enhancing performance.” — Luca Castonato [41:38]
Key Features:
Preact Integration:
File-Based Routing:
Server-Side Rendering:
“Fresh doesn’t send all JavaScript to the client. Instead, it allows you to opt-in interactive components as needed, improving first load performance and reducing resource consumption.” — Luca Castonato [43:35]
Comparison with Other Frameworks:
Conclusion
The episode wraps up with Luca Castonato urging developers to explore Deno 2.0 and Fresh, emphasizing the streamlined experience and enhanced capabilities they offer. He invites listeners to engage with Deno’s tutorials on YouTube and participate in the community to contribute and provide feedback.
“If you want to try out Deno, we have a great new tutorial series on YouTube. Check it out at YouTube.com/denoland.” — Luca Castonato [46:09]
Kevin Ball concludes by encouraging developers to embrace Deno for its simplicity and efficiency, underscoring the value of minimizing configuration overhead in software development.
“Everybody try Deno because life is too short to be configuring things.” — Kevin Ball [46:29]
Key Takeaways
For developers seeking a modern, secure, and efficient JavaScript runtime, Deno 2.0 presents a compelling option with robust tooling and seamless integration capabilities.