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
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.
2. Deno: Frameworks, Security, and Compatibility
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.
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
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
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)
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
7. Updating Counter in Deno Server
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
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
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
Q&A on Dino Features and Functionality