/\ \ /\ \ /\ \ _ /\ \ _ /\ \ _ /\ \ /\ \ /\ \
/ \ \____ / \ \ / \ \ /\_\ / \ \ /\ \ / \ \ /\_\ / \ \ / \ \____ / \ \
/ /\ \_____\ / /\ \ \ / /\ \ \_/ / // /\ \ \ ___\ \_\ / /\ \ \_/ / // /\ \ \ / /\ \_____\ / /\ \ \
/ / /\/___ // / /\ \_\ / / /\ \___/ // / /\ \ \ /___/\/_/_ / / /\ \___/ // / /\ \ \ / / /\/___ // / /\ \_\
/ / / / / // /_/_ \/_/ / / / \/____// / / \ \_\ \__ \/___/\ / / / \/____// / / \ \_\ / / / / / // /_/_ \/_/
/ / / / / // /____/\ / / / / / // / / / / / /\/____\/ / / / / / // / / / / // / / / / // /____/\
/ / / / / // /\____\/ / / / / / // / / / / / \ \_\ / / / / / // / / / / // / / / / // /\____\/
\ \ \__/ / // / /______ / / / / / // / /___/ / / \/_/ / / / / / // / /___/ / / \ \ \__/ / // / /______
\ \___\/ // / /_______\/ / / / / // / /____\/ / / / / / / // / /____\/ / \ \___\/ // / /_______\
\/_____/ \/__________/\/_/ \/_/ \/_________/ \/_/ \/_/ \/_________/ \/_____/ \/__________/
- Slides available at https://github.com/MarkBennett/deno-node-compat
Deno is a new project from Ryan Dhal, the original author of Node.
Node | Deno | |
---|---|---|
V8 engine | โ | โ |
ES Modules | ๐จ * | โ |
Common.js | โ | No |
Web APIs | ๐จ * | โ |
Sandbox / Permissions | No | โ |
TypeScript | No | โ |
Linter | No | โ |
Formatter | No | โ |
REPL | โ | โ |
npm / node_modules | โ | No |
Bundler | No | โ |
- Partial support with .mjs files
- Fetch, Web Crypto, and a growing list of other APIs
- Fast and secure
- Betting on Web APIs will pay off
- Single executable with TS, linting, formatting, and testing
Learn more at deno.land
- Most devs know Node
- Learning something new is hard
- The node/npm ecosystem is much bigger than Deno's
Deno is addressing all of these, and really focused on developer experience.
Today going to focus on how Deno is overcoming the third of these, by making Node and npm work seamlessly with Deno.
Using npm
packages is easy!
Just import packages using the npm:
url schema and you're good to go!
Never type npm install --save
again!
import ?? from "npm:<package-name>[@<version-requirement>]";
Packages are downloaded the first time you import them and cached across the system.
// express-main.ts
import express from "npm:express";
const app = express();
app.get("/", function (_req: Request, res) {
res.send("Hello World");
});
app.listen(3000);
console.log("listening on http://localhost:3000/");
Node has a large Standard Library which provides access to the file system, network, and more.
Though Deno uses Web APIs, since v1.15 a large portion of the Node Standard Library is available in Deno.
You can access them by importing from the node
module in the Deno standard
library.
// node-stdlib.ts
import { readFileSync } from "https://deno.land/[email protected]/node/fs.ts";
import { stdout } from "https://deno.land/[email protected]/node/process.ts";
const data = readFileSync("hello.txt", "utf8");
stdout.write(data);
When you import an npm
package, Deno automatically polyfills the Node API for
you.
In Deno you run scripts from a url:
deno run main.ts
deno run https://deno.land/std/examples/welcome.ts
Use deno run
with an
npm:<package-name>[@<version-requirement>][/<binary-name>]
url to run a Node
package binary.
deno run -A --unstable npm:create-vite-extra
deno run -A --unstable npm:cowsay "Hello!"
deno run -A --unstable npm:[email protected]/cowthink "What to eat?"
deno run -A --unstable npm:eslint your_file.js
This is basically the same as using npx
in Node since nothing needs to be
downloaded or installed first.
- NOTE: We need to add permissions
-A
and the--unstable
flag to run these scripts.
You can also use deno task
to run scripts defined in a deno.jsonc
file.
// deno.jsonc
{
"tasks": {
"fmt": "deno fmt",
"lint": "deno lint",
"test": "deno test -A",
"slides": "slides readme.md"
}
}
Start the slides with:
deno task slides
This works like the scripts defined in package.json
in Node.
When using imports with webpack and node, you can import packages using "bare" specifier (ie "react" or "lodash") and the bundler will resolve the package to the correct file.
// my-node-code.js
import React from "react";
import { map } from "lodash";
Deno doesn't have this feature, but you can use import maps to get the same behavior. They're a standard feature of the browser, which Deno now supports too.
// import-map.json
{
"imports": {
"react": "https://cdn.skypack.dev/react",
"react-dom": "https://cdn.skypack.dev/react-dom"
}
}
Then just tell Deno about your import map when you run your code:
deno run --import-map ./import_map.json my-node-code.js
Most packages on npm are missing TypeScript types. This isn't specific to Deno, and you've likely running into it whenever you've used TypeScript with Node.
You can use the @types
npm packages to install third-party type definitions.
// express-main.ts
import express from "npm:express";
import type { Request, Response } from "npm:@types/express";
These definitions are not always complete, and you may need to add your own. Pull requests are welcome!
https://github.com/DefinitelyTyped/DefinitelyTyped
Some popular packages like bcrypt
and sharp
use native Node modules. These
let them access C libraries and perform operations that are not possible or
optimized in JavaScript.
These aren't currently supported in Deno, but work is underway to add support and the first version was merged into the main branch on Oct 5, 2022.
I'm guessing this will be a headline feature in Deno v1.27.
Though Deno has a large portion of the Node Standard Library available, it's not complete and work is on-going to add more.
You can track progress on GitHub:
And there's a list of missing APIs in the Deno docs:
They're always open to receiving new issues and pull requests!
Some packages hard code node_modules
into their source (bad!) and won't work
without it.
Deno supports this using the --node-modules-dir
flag.
// chalk.ts
// this will break without node_modules
import chalk from "npm:chalk@5";
console.log(chalk.green("Hello"));
Can be run with:
deno run --unstable --node-modules-dir chalk.ts
Going forward to the team is already tracking the next Node LTS release. and working to get it's specs passing in Deno.
This is the tracking issue on GitHub:
To get there the Deno team knows they need to have a graceful on-ramp for existing Node developers, and have committed to making it as easy as possible.
Even if Deno doesn't become the next Node, simply pushing Node to better support standards and improve the developer experience is a win for everyone.
Before you begin, make sure you have Deno installed. You can install it on Mac and Linux with the following command:
curl -fsSL https://deno.land/install.sh | sh
Or with PowerShell on Windows:
irm https://deno.land/install.ps1 | iex
See https://deno.land/#installation for more detials.
Quickly initialize a new project:
deno init hello-node
This will setup linting, formatting, and testing for your project.
deno run --watch main.ts
deno lint
deno test
deno fmt
If you're using VS Code, it's also a good idea to install the official Deno extension.
https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno
- Deno v1.2.5 Relase Notes
- Deno v1.2.6 Release Notes
- Interoperating with Node and NPM in the Deno Manual
_ _ _ _ _ _ _ _ _ _
/\ \ /\_\ /\ \ / /\ /\ \ /\ \ /\ \ /\ \ _ / /\ / /\
/ \ \ / / / _ / \ \ / / \ \_\ \ \ \ \ / \ \ / \ \ /\_\ / / \ / / \
/ /\ \ \ \ \ \__ /\_\ / /\ \ \ / / /\ \__ /\__ \ /\ \_\ / /\ \ \ / /\ \ \_/ / // / /\ \__ / / /\ \___
/ / /\ \ \ \ \___\ / / // / /\ \_\ / / /\ \___\ / /_ \ \ / /\/_/ / / /\ \ \ / / /\ \___/ // / /\ \___\ / / /\ \__ /\
/ / / \ \_\ \__ / / / // /_/_ \/_/ \ \ \ \/___// / /\ \ \ / / / / / / \ \_\ / / / \/____/ \ \ \ \/___//_/ / \__/ / /
/ / / _ / / / / / / / / // /____/\ \ \ \ / / / \/_// / / / / / / / // / / / / / \ \ \ \ \ \ /_/ /
/ / / /\ \/ / / / / / / // /\____\/ _ \ \ \ / / / / / / / / / / / // / / / / /_ \ \ \ \_\/ \ \ \
/ / /__\ \ \/ / / /___/ / // / /______ /_/\__/ / / / / / ___/ / /__ / / /___/ / // / / / / //_/\__/ / / \_\/_
/ / /____\ \ \/ / /____\/ // / /_______\\ \/___/ / /_/ / /\__\/_/___\/ / /____\/ // / / / / / \ \/___/ / /_/\
\/________\_\/\/_________/ \/__________/ \_____\/ \_\/ \/_________/\/_________/ \/_/ \/_/ \_____\/ \_\/