Deno 2.0

Rate this content
Bookmark

Deno 2.0 is imminent and it's bringing some big changes to the JavaScript runtime. In this talk, we'll introduce the new features including import maps, package.json auto-discovery, and bare specifiers. We'll discuss how these improvements will help address issues like duplicate dependencies and disappearing dependencies. Additionally, we'll delve into the built-in support for deno: specifiers on the deno.land/x registry and its role in providing a recommended path for publishing. Come learn about how these updates will shape the future of the JavaScript ecosystem and improve backwards compatibility with Node applications.

36 min
14 Apr, 2023

Comments

Sign in or register to post your comment.

AI Generated Video Summary

The Talk discusses forced optimization with Node and Deno, with Deno aiming to pursue the same goals in a more expansive and modern way. Deno has built-in support for NPM and enforces security constraints. It also has a key-value database called Deno KV, which will be a core part of the Deno 2 API. Deno Deploy is a serverless Edge Functions platform powered by FoundationDB, optimized for fast reading and ideal for building eCommerce sites or application servers at the edge. Deno 2.0 is coming soon with more features under development.

1. Forced Optimization with Node and Deno

Short description:

My talk is about forced optimization, the original goal with Node was to force developers to easily build optimal servers by using async IO. These days, building optimal servers requires more than just async IO. With Deno, the goal is to continue pursuing the same goals but in a more expansive and modern way. The system needs to be maximally accessible, have excellent latency, and be serverless.

My talk is not called Dino 2.0, it's called forced optimization. There's this trick you do when you apply for conference talks where you give some title and some description and the night before you make it up as you're going along.

Yeah, so Node is quite old at this point. Maybe 13, 14 years old. My original goal with Node was to force developers to easily build optimal servers by forcing them to only use async IO. Not 100% true. There's synchronous IO in Node, but to a large extent, at least with network IO, you're kind of forced to use non-blocking IO. This is really standard these days. Essentially, any platform is making use of non-blocking IO. But in 2008, this was not the case. There was a lot of people writing kind of threaded, blocking IO servers.

These days, easily building servers and optimal servers needs more than just async IO. There's a lot that goes into this. You're managing cloud configurations. You're choosing a database. You're thinking about how data might be replicated around the world. Especially if you're using Node, you're navigating a plethora of tool chains and workflows that may or may not work nicely together. You're dealing with supply chain security. Just doing non-blocking IO isn't getting you all of the way there. With Deno, the goal is really a continuation of this original goal, but a little bit more expansive and modern. Deno continues the pursuit of the same goals, but thinking about this kind of holistically as a service that you're building and deploying to a public cloud. In order to achieve this, there are certain requirements that I think are obvious. First and foremost, I'm interested in building systems that are maximally accessible, that have a very large developer base. That is why JavaScript. JavaScript is not necessarily the greatest language on earth, but it is the most accessible language on earth. This system needs to have excellent latency everywhere. Whether you're accessing the system from Japan or you're accessing it from New York City, you should not be penalized for where you are in the world. This system should, I don't know if you're in agreement with this, but the system should be serverless. You want things that scale down to zero and scale up to as large as necessary. This is a big deal these days is that there is a lot of configuration that goes in here.

2. Deno: Frameworks, Security, and Compatibility

Short description:

You're dealing with Terraform, config files, and frameworks in Deno. The goal is to reduce boilerplate and improve security. Deno 2.0 is under development and aims to address compatibility issues with Node. Deno provides a prompt for file system access and takes a hard line stance on import specifiers. Node built-in modules are available in Deno.

You're dealing with Terraform, you're dealing with various config files from every possible library. You're dealing with lots of boilerplate, lots of frameworks. What are frameworks anyways? It's just boilerplate that you kind of lay down in advance in order to get running. We want to reduce that as much as possible in order to move people forward.

It should be secured by default, right? JavaScript is a great language for security because it is actually a sandbox and has the ability to restrict people from accessing the underlying system. Deno is attempting to meet these requirements and ever more getting closer to this. Deno 2.0 is coming out this summer and we're working towards this, right? We're kind of ever thinking about this in terms of how do we build kind of optimal cloud services, optimal servers.

I want to go through a couple of aspects of this and a couple of features of Deno 2.0 that are under development and demo them, and just give you a sense for how this thing works. So first and foremost, Deno, when we started a couple years ago, was very much on a parallel track to Node. And this has been difficult for people to adopt. Because a lot of the JavaScript ecosystem depends on NPM libraries, depends on Node APIs, and implementing these built-in modules is relatively important for people to get up and running quickly.

So yeah, let me just try to demo some of this. Is that visible? Okay. So builtin.js. And you can import readfilesync from node colon fs. And you can readfilesync, say, some file. Etsy password doesn't actually have any nefarious details in it these days, but it is nevertheless kind of a good example of security. So let's just log out this file here. So when we run this with Deno, of course, Deno's big thing is that there is no security by default. There's no access to the system by default, rather. And so every time you try to access the file system, you're going to get a prompt. And what it's asking me here is, do you want to actually allow this? And you can say, no, I don't, in which case the program's going to fail. Or you can say, yes, I do want that, in which case you kind of get out this buffer. In Node, you're probably used to this without a Node specifier. And Node these days is moving, is encouraging people to use the Node schema in that import specifier. Deno kind of takes a hard line stance here that we are not going to have these kind of FSBear specifiers and whatnot. So this induces a little bit of incompatibility with Node. But I think for good reason, right? This is this is not not too big and it gives you kind of a nice error message that kind of tells you what to do. So hopefully hopefully it's not too confusing for people. So we've got Node built in Node modules.

3. Deno's Support for NPM and Compatibility

Short description:

Deno has built-in support for NPM, allowing developers to reach into the JavaScript ecosystem and make use of modules. Deno acts as the NPM client built directly into Node, providing deep compatibility and supporting add-ons with the Node API. However, Deno enforces security constraints to block network and disk access. While Deno implements the common.js modules and package.json semantics, it encourages the use of ECMAScript and prohibits the use of require. Let's see a demo of this by coding an express server and running it in Deno.

I just showed the FS module, but the compatibility layer is quite robust at this point. NPM is like this add on to Node that Isaac Schluter created. And this has always been kind of a tension between Node itself and NPM. But it's clear that the entire JavaScript ecosystem is in NPM and it is very useful to be able to reach into that ecosystem and make use of modules. And for that reason, Deno has built-in support for NPM now.

Deno, so think of it as like the NPM client built directly into Node. It can go and download those packages, doesn't actually create a local Node modules folder. It's pretty deep compatibility, so even supports things like add-ons with the Node API. It does supply these security constraints, so if that NPM package is trying to reach into the network or access the disk, that is going to be blocked by Deno's permission system. The NPM ecosystem, when you start looking into it, has a lot of old code out there, a lot of common.js, a lot of bizarre semantics around package.json. Deno implements all of that, but it's very much hidden behind this kind of cute NPM specifier. You can't actually use common.js as a Deno developer. We're very adamant that everything should be ECMAScript now, and you cannot use require. But when you actually reach into this ecosystem, reach in through this kind of NPM specifier portal, internally, it is actually loading common.js modules and doing pretty crazy stuff to make this possible.

So as a demo of this, let me code up a little express server here, and run this in Deno. So is that still visible? Yeah. I'll do this. Oops. And forgive my like vimming here. I'm extremely old and crotchety about this stuff. So import express from NPM colon express. This is kind of all you need here. And just a little bit of boilerplate. You go express, and that gives you an app, and then you can do app.get. And if you get the slash root, then you get a request and a response blah blah blah. Okay, and then you can do response send I think. Yes, send hello, maybe with the new line. And I guess you have to listen on port 3000, and it's always good to like consult log something, otherwise it's a little confusing. So this is going to be running at localhost 3000. Right, so now I've got something that is going to be using some common JS under the hood, right? Express is relatively old and let's see how this runs in Deno.

4. Deno's NPM Install and Deno KV Feature

Short description:

I'm going to run 'deno run express' to show you how Deno handles NPM modules. It's fast, transparent, and provides security permissions for free. Deno KV is a secret, advanced key-value database built into Deno.

So I'm just going to do deno run express. You'll see that it's trying to access the CWD. I think this is something inside of Express. Maybe reading argv or something. We have to allow access for that. It's also trying to read environment variables. I'm not sure why Express is trying to read environment variables. Maybe for node end or something. But let's allow that. And then it's trying to get access to run the server on port 3000. So we'll allow that.

And finally we've got our little web server running that is using Express under the hood. And as you can see there's no node modules folder. This all kind of got installed automatically. So if you know what you're going to do, you can say allow read. You can allow it to read things in the local directory. You can allow net and allow env to bypass those prompts. And I'm going to add this reload flag just so you can see it download these NPM modules. Luckily the Wi-Fi is working. Great. So that is what an NPM install looks like in Deno. It's completely transparent. It happens very fast in the background. And it kind of just works like that. And you get the security permissions for free. So this is making Deno more accessible and getting us closer to this goal of building servers, building cloud services that you can just kind of hammer out in a couple of seconds.

There's a new feature in Deno that we haven't really talked about yet. And you'll have to keep it secret because it's not yet announced. But we have a feature called Deno KV. And this is a pretty advanced key value database that is built directly into Deno.

5. Deno's Key-Value Database (Deno KV)

Short description:

Deno has a built-in key-value database called Deno KV. It allows you to store JavaScript objects and perform key value operations like get, set, list, and delete. Deno KV supports atomic transactions and is built into the CLI and backed by SQLite. It will be a core part of the Deno 2 API, making it easy to build application servers with a key-value model.

It allows you to store JavaScript objects. It has normal key value operations like get, set, list, delete. It has atomic transactions. And I'll talk a little bit more about that. I'll just say it's relatively advanced in that regard. And it's really built into the CLI and backed by SQLite.

So this is already in Deno. It's behind an unstable flag because it's still being developed. But when Deno 2 is released in a couple of months, this is going to be a core part of the API. And the idea is that you can get started building application servers. Maybe not things that really require a lot of relations and a whole lot of data. But I think a lot of applications actually fit pretty well into a KV model like this, especially one that is consistent and has transactions.

So let me demo that a little bit. And let me use VS Code for this one just so I have some runDeno in it. And muscle memory is just VIM always. OK, so I've kind of auto generated some boilerplate here. By the way, OK, I'll refrain from commenting on that. I'm using VS Code for type completion and stuff with this kv API. So the way this works is you do dno.openkv. And this takes in a wait. And it's red here because this is an unstable API. And so I need to do unstable. You won't have to do this once this is actually working. And what this gives you is a reference to this database. And let's just console log this. By the way, is this visible? You guys should just let me know if this is completely unintelligible. And terminal. Just here. OK, so dno run main. Oops, main ts.

6. Using the Key-Value Store in Deno

Short description:

This section covers how to use the key-value store in Deno, where the key is a JavaScript array. It demonstrates setting and getting values, without the need for permissions. Deno's default database is backed by SQLite.

So again, this is behind an unstable flag. So if you're just running it without anything, it's going to crash. You have to provide this unstable. But yeah, now it's open to the database. So what? So let's just kind of build up this example a little bit. So kv set. And the key for this, this is a key value store. So there's kind of this hierarchical key space. And the key is a JavaScript array, actually. And instead of kind of serializing out a string with kind of slashes in between, this gets relatively messy. We just use an array here. So let's pretend that we're creating a users table. And Alice, I think, is my example. So we're going to set users slash Alice. And the value is just going to be something, some JavaScript object, right? And if we await that, then we will have set this thing. And of course, you can kv.get this. And we'll just grab that key. And I'll just console.log this x here, delete this one. So right, now we've pulled out this Alice object. You'll see there's this version stamp there. That's a little interesting. We'll get into that. But I think another thing to note here is no permissions are necessary. There is kind of a default database in here, and you can kind of configure this to kind of store it in a file. Locally, this is backed by SQL lite. So these are actually stored in a SQL lite database.

7. Updating Counter in Deno Server

Short description:

Let me expand the example into a server that counts requests. We'll update a counter to demonstrate the transactional object. Set up a web server using the Deno built-in server API. Run the server and handle net access. Define a key 'counter' to store the integer. Use 'kv atomic mutate' to update the counter.

So let me expand this example a little bit into a server that counts how many visits, how many requests have gone to the server. So we're just updating a counter. So the purpose of this is to demonstrate this transactional object, this transaction here.

So yeah, what we're going to do, let me modify my example here. So rather than setting a user's table here. Well, first of all, let me set up a server. So import serve from HGPS, oops. dno.land std HGPServer.ts. So this is the dno, built-in dno server API. And this takes a request, and it returns a response. Return new response. Demos are always much harder when standing in front of a bunch of people like this. Response. There we go. OK, so this sets up a little web server. And let's just comment out these bits here. And we'll just run this. And now that I'm running this, it's asking for net access. So just so we don't have to do that each time, let's just do allow net. OK, now it's listening on port 8,000. And we can curl local host 8,000. And we get hello. Great. Maybe make it slightly smaller.

So what we want to do is update this counter now. So let's store this. Let's just define this key to be counter. This is where we're going to store this integer. And what we'll do is say kv atomic mutate.

8. Incrementing Counter and Building a Platform

Short description:

We're incrementing a counter value using kv atomic mutate. The value is retrieved asynchronously and logged. The counter is persisted even after program restart. This demonstrates a stateful application without dependencies or a database. We're building a platform for real applications that run worldwide.

And what we'll do is say kv atomic mutate. And here we'll say type is sum key, and then the value is going to be a little bit messy here, but just bear with me. New Dino kv UN64. And let's just ignore what that means for the time being. And we'll commit that, commit that transaction and await that. And it's complaining because I don't have an async here.

So now we're incrementing this counter value. And let's grab that value out of here. So we'll get key. And let's await that. It's all asynchronous. And I'm just going to console log that for the time being. Make sense?

So let's try this one more time. Oops. So now, when I curl this, this is the value that I'm getting back from this get request. And you can see that the value here is a KVU64 one. And if I hit it again, you'll see that those things increment. So let's just grab out that value, value, value. Let's just call that counter and counter. And oops, not console log it. Let's actually return that in a response here. Cool. OK, so when I'm running it now, I should get 6, 7, 8, 9. And if I kill this program and restart it, that counter is persisted. Cool. So we've got a little stateful application where I didn't need to install any dependencies. I don't need any sort of database.

Let me segue a little bit here. This is all local development. And I started this by saying, what we're trying to do is build a platform for real applications, not just a single instance of this, but instances that run worldwide that are pretty real, in a sense.

9. Deno Deploy: Serverless Edge Functions

Short description:

Deno Deploy is a serverless Edge Functions platform that runs in the cloud and in 35 data centers worldwide. It uses the technology of Deno and is powered by FoundationDB, a scalable and strongly consistent database. Deno Deploy requires zero configuration, provisioning, or orchestration and is optimized for fast reading. It allows for fast local reads, making it ideal for building eCommerce sites or running application servers at the edge.

Deno Deploy is kind of the other half of Deno, right? Deno is open sourced, MIT licensed, very much like Node thing that runs on your terminal. Deno Deploy uses a lot of that technology, runs in the cloud, runs in 35 data centers worldwide, and is a serverless Edge Functions platform. It's powering, for example, Netlify Edge Functions or Superbase Edge Functions. Just have to explain that.

Now, here's the real part of this. Let's take this example and let's deploy it worldwide to all of these data centers so that we are incrementing this counter kind of statefully worldwide. The interesting thing about this API is that it also maps not just to a SQLite database that runs locally, but to a georeplicated, strongly consistent database in Deno Deploy. This is powered by FoundationDB, which is, you look it up if you don't know, but it's powering things like iCloud or Snowflake. Scalable database. This requires zero configuration, zero provisioning, zero orchestration, and it's really optimized for fast reading so that you can do fast local reads in like 20 milliseconds because that's what you're doing. That is often what you're doing. If you're building an eCommerce site, you are listing a lot of products from the database, and that needs to be really fast. If you're running at the edge, if you're running your application server everywhere all at once, you need to be able to read that data very, very fast.

By the way, I've got some instructions here if you want to try it out, but let me just wave my hands and say this is very much under development still, so you'll have to beg me for access if you want that. But let me demo it here. And let's see here, dash.dino.com. So this is Dino Deploy. I won't go through this, but I'll create a new project. I'm going to just use the little in built-in editor here that we have. So I've created a new domain name. Hopefully, this is visible. FunnySwan75. Let me just rename this to Node Congress. Hopefully, that's not taken. Okay, so now I've got nodecongress.dino.dev. It's returning a Hello World server. And let me just take this code, copy and just delete this, and paste that in there. And save and deploy. Hopefully, I'll get a zero returned here for kind of a zero counter on the left side. Oh, five already.

10. Building Real Application Servers with Deno

Short description:

The idea is to build a real application server with just a few lines of code, fulfilling the idea of forcing optimization on users. Deno 2.0 is coming out soon, with more features under development such as cache, persistent queues, background workers, and object store. Deno restricts programs to distributed cloud primitives, helping developers build optimal global services. A new computing abstraction is emerging, similar to how Bash is to JavaScript as ELF is to WASM.

Geez, you guys are fast at this. So every time I'm reloading this, I'm checking the value of that counter, right? And yeah, this page should load fast in Tokyo or wherever. Yeah, you know, I guess let me go back to my slides here. The idea here is that you can just open an editor, hammer out a couple of lines of code and have a real application server that doesn't just run locally, but is kind of prepared to scale. And I think this is getting you very close to building real applications in just a couple lines of code and really fulfilling this idea of kind of forcing optimization on users. There's more under development here. There's cache, persistent queues, background workers, object store, of course, ever better backwards compatibility for people. Like I said, Deno 2.0 is coming out this summer and this KV stuff will be underway here soon. It will be released in Deno Deploy soon. My goal is still the same, right? With Node, the goal was to restrict I.O. primitives, restrict programs to async I.O. primitives to help developers build optimal local servers. And in Deno, it's just an expanded version of that. Restricting programs to distributed cloud primitives, the right primitives to help developers build optimal global services. And let me just leave you with this analogy, right? I think there is a new computing abstraction emerging here, right? Bash is to JavaScript as ELF is to WASM. There is kind of a post-UNIX future emerging and people like James are working on this in Winter CG. And yeah, I'll leave it at that.

QnA

Q&A on Dino Features and Functionality

Short description:

Thank you for your time. Dino aims to be browser compliant and does not intend to fix JavaScript floating point arithmetic. There is currently no way to allow access only to specific libs, but research is being done in TC39. Dino can be hosted on various cloud providers, while the FoundationDB backend is specific to Dino deploy. KV expands the scope of applications beyond traditional KV data stores. Elf is the executable binary format in Linux, analogous to launching Wasm executables from JavaScript. The speaker clarifies that they were not using the root user in the terminal. Pagination is possible using the cursor API, and self-hosting with the same functionality as donut.dev is only possible to some extent due to the proprietary nature of the FoundationDB backend.

So thank you for your time. Thank you, Ryan, if you can take a sit. Please remember to ask your questions on Slido. We have two right now. So the first question is, thank you for the great talk, by the way. It was very interesting. Would Dino try to fix JavaScript floating point arithmetic in the future? No, I don't think so. I mean, Dino is trying to be browser compliant and that is really an issue for TC39 and the definition of the language. Dino's not going to try to kind of step outside of that. Okay, cool. And the next question is, there is a way to allow access only to specific libs? No, so I think what this question is referring to is kind of allowing, for example, network access to one dependency but not allowing it to other dependencies. This is not possible as far as we can see. We would love this feature. There's work happening in TC39 and I think there's gonna be some talks about this later but this is very much research and at the, excuse me, at the moment the permission system is kind of process based. Cool. And will the person be able to host KB on existing cloud providers to trust and GDPR? Yes, so you can take Dino and you can go deploy this wherever you want. You go put it on AWS Lambda, you'll have a local SQL lite version of this. You can put this on Cloud Run, you can put it wherever you want, that's all accessible. The foundation DB backend is specific to Dino deploy. And what do you envision KV being used for the most? Yeah, we think that I think traditionally KV data stores are pretty limited in their feature set. And so people tend to reach for relational databases very often with these transactions and this consistency model. We still believe that there's a world where relational databases are necessary and applications obviously, but I think this expands the scope quite a lot. So lots of, you know, it's hard to put a number on it, but you know, some number of, you know, simplish applications to medium complexity applications I think can fit very well into this KB abstraction. And what is Elf? Elf is the executable binary formats in Linux. So, you know, the analogy I was drawing, I should have explained it a little bit more, but Elf is so short, right? So, you know, you're using Bash, you're using whatever ZSH in Linux, and that's kind of a dynamic programming language. It is a dynamic programming language, a really crappy one, but you can launch into binaries written in C, written in C++, written in Rust, right? Those are Elf executables. And the analogy is with JavaScript, you have this kind of shell, this JavaScript dynamic language where you can launch into these Wasm executables that are written in C++, Rust, et cetera, for more complicated behavior. Thank you. We just have one minute left, and why are you always using the root user in the terminal? Sorry? Yeah, that's one of the questions, why are you always using the root user in the terminal? Oh, no, I'm using my own user, was I logged in as root? No. Cool. In your first kb example, would it be possible to list all users? Yeah, and you should look at the documentation, there's a cursor API, so you can do pagination through the, you can list, say, the users table and paginate through that pretty easily. Cool. And is there a way to self-host with the same functionality as provided by donut.dev? To some extent. This FoundationDB backend, this kind of distributed KB store is proprietary. Okay, thank you. We've run out of time, but thank you very much. We practice our clap, so let's give it a 10.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
JSNation 2023JSNation 2023
28 min
SolidJS: Why All the Suspense?
Solid caught the eye of the frontend community by re-popularizing reactive programming with its compelling use of Signals to render without re-renders. We've seen them adopted in the past year in everything from Preact to Angular. Signals offer a powerful set of primitives that ensure that your UI is in sync with your state independent of components. A universal language for the frontend user interface.
But what about Async? How do we manage to orchestrate data loading and mutation, server rendering, and streaming? Ryan Carniato, creator of SolidJS, takes a look at a different primitive. One that is often misunderstood but is as powerful in its use. Join him as he shows what all the Suspense is about.
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Jotai is a state management library. We have been developing it primarily for React, but it's conceptually not tied to React. It this talk, we will see how Jotai atoms work and learn about the mental model we should have. Atoms are framework-agnostic abstraction to represent states, and they are basically just functions. Understanding the atom abstraction will help designing and implementing states in your applications with Jotai

Workshops on related topic

JSNation Live 2021JSNation Live 2021
156 min
Building a Hyper Fast Web Server with Deno
WorkshopFree
Deno 1.9 introduced a new web server API that takes advantage of Hyper, a fast and correct HTTP implementation for Rust. Using this API instead of the std/http implementation increases performance and provides support for HTTP2. In this workshop, learn how to create a web server utilizing Hyper under the hood and boost the performance for your web apps.
Node Congress 2022Node Congress 2022
57 min
Writing Universal Modules for Deno, Node and the Browser
Workshop
This workshop will walk you through writing a module in TypeScript that can be consumed users of Deno, Node and the browsers. I will explain how to set up formatting, linting and testing in Deno, and then how to publish your module to deno.land/x and npm. We’ll start out with a quick introduction to what Deno is.