Deno World
Published in

Deno World

Node.js compatibility in Deno

Introduction

Since a long time, Deno’s standard library had a module called node that mimicked some Node.js’s core modules (like http, fs, etc.) in Deno. The purpose of compatibility is to provide an ability to run Node.js programs in Deno. The primary advantage is running a Node.js app as is, i.e. without rewriting it. Only a subset of the Node core APIs were supported, while a good number of them were still in To-Do. This ES module stayed in standard library for a long time, with occasional enhancements here and there.

Since v1.15, Deno is getting more serious about Node.js compatibility. Recently, there have been numerous enhancements to the standard library’s node module. A lot of work has been put in to reach feature parity with Node.js.

The biggest enhancement is to bring in the std’s node module in the core runtime through a flag ( — compat). This way, there is no need to include/import anything. All the Node core modules are loaded at startup. In other words, all the Node’s core modules are available as a standard import, rather than importing from the standard library.

In this introductory article, we’ll evaluate Deno’s current level of Node.js compatibility through some simple examples.

Startup

There is a new flag called — compat that can be used to load the Node modules into Deno’s core runtime. This happens at startup. The loading of core modules happens from the same standard library’s node module.

For Deno v1.16.2, the core modules are loaded from https://deno.land/std@0.115.0/.

It is expected that the std version would get updated for every Deno release.

Here is the list of core modules that are loaded in the compatibility mode:

assert, assert/strict, async_hooks, buffer, child_process, cluster, console, constants, crypto, dgram, dns, domain, events, fs, fs/promises, http, https, module, net, os, path, path/posix, path/win32, perf_hooks, process, querystring, readline, stream, stream/promises, stream/web, string_decoder, sys, timers, timers/promises, tls, tty, url, util, util/types, v8, vm, zlib

The compatibility mode is currently under unstable umbrella, therefore needs — unstable flag to load Node’s core modules.

$ deno run --compat --unstable nodeApp.js

The compatibility mode allows CJS (common JS) modules to get loaded through require() API. Unlike standard imports that don’t require a read permission, CJS imports (i.e. require) requires explicit read permission.

$ deno run --compat --unstable --allow-read nodeApp.js

That’s all about the background! Once compat mode is specified, all the core modules get loaded in the background. This helps in running a Node.js program as is.

Let’s go through some simple examples and evaluate how much of Node.js compatibility is there.

Examples

Example 1

Check if command line args can be referred through process.argv.

//nodeApp.js
console.log(process.argv);
//--$ deno run --compat --unstable --allow-read nodeApp.js
[ "/usr/local/bin/deno", "/Users/mayankc/Work/source/denoExamples/nodeApp.js" ]

Verdict: Compatible

Example 2

Check if environment variables can be accessed with process.env.

//nodeApp.js
console.log(process.env);
const l=process.env.LANG;
//--
{
SSH_AUTH_SOCK: "/private/tmp/com.apple.launchd.r6GGfQ0uSK/Listeners",
OLDPWD: "/Users/mayankc/Work/source",
__CFBundleIdentifier: "com.apple.Terminal",
TERM: "xterm-256color",
....
LANG: "en_US.UTF-8",
NVM_IOJS_ORG_MIRROR: "https://iojs.org/dist"
}
l: en_US.UTF-8

Verdict: compatible

Example 3

Check if files can be written using core fs module with callbacks.

//nodeApp.js
const fs = require('fs');
const data ='Trying FS module in compat mode';

fs.writeFile('/var/tmp/fsCompatTest.txt', data, (err) => {
if (err) throw err;
console.log('File is created successfully.');
});
//--$ deno run --compat --unstable --allow-read --allow-write nodeApp.js
File is created successfully.
$ cat /var/tmp/fsCompatTest.txt
Trying FS module in compat mode

Verdict: Compatible

Example 4

Check if data can be read from file using core fs module with callbacks.

//nodeApp.js 
const fs = require('fs');

fs.readFile('/var/tmp/fsCompatTest.txt', (err, data) => {
if (err) throw err;
console.log('Read from file:', data.toString('utf-8'));
});
//--$ deno run --compat --unstable --allow-read --allow-write nodeApp.js
Read from file: Trying FS module in compat mode

Verdict: compatible

Example 5

Check if a standard ‘hello world’ kind of HTTP server can be used with Node.js APIs like createServer() and listen().

//nodeApp.js
const http = require('http');
const respData='HTTP server in Node.js compat mode';
http.createServer((req, res) => {
res.writeHead(200, {
'content-type': 'text/plain',
'content-length': `${respData.length}`
});
res.end(respData);
}).listen(8080, () => console.log('Listening...'));
//--$ curl http://localhost:8080 -v
< HTTP/1.1 200 OK
< content-length: 34
< content-type: text/plain
HTTP server in Node.js compat mode

Verdict: compatible

Example 5

Check if buffers can be created and converted to different formats.

//nodeApp.js
const {Buffer} = require('buffer');
const buf = Buffer.from('hello world', 'utf8');
const h=buf.toString('hex');
const b=buf.toString('base64');
const u=new Uint8Array(buf);
//--
h: 68656c6c6f20776f726c64
b: aGVsbG8gd29ybGQ=
u: Uint8Array(11) [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

Verdict: compatible

Overall impression: It works for simple programs!

It’s important to note that the feature parity is still getting built. Modules like https, vm, etc. are not yet available in compatibility mode.

We’ll go through more examples in a subsequent article.

This story is a part of the exclusive medium publication on Deno: Deno World.

--

--

--

The one and only exclusive medium magazine with 200+ articles on Deno

Recommended from Medium

Gatsby.js — Conditional Queries and Create Pages

How to simply test macros and transformations in Kentico

Add Popups and Menus Easily with V-Click-Outside

JavaScript Problems— IFrames and Arrays

Material UI — Popovers

Run Async Code on Update of a State with React Hooks

Best of Modern JavaScript — Destructuring and Defaults

How to Build Spotify Audio Controls in JavaScript

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mayank Choubey

Mayank Choubey

Deno, Node.js, etc.

More from Medium

Four sources to import modules in Deno

A comprehensive guide to HTTP clients in Deno

Run and debug Deno applications in VSCode

Deno nuggets: Write raw data on console