Quick Links

Deno 1.19 was released in February 2022 as the latest incremental update for the secure-by-design JavaScript runtime. Among the changes are a streamlined permissions management experience, first-class support for vendored dependencies, and new native web streams for files, network sockets, and standard input and output.

In this article we'll look at the major additions and improvements that will alter how you use Deno. You can get the full low-down on the release from the changelog on the Deno blog.

Permission Prompts

One of Deno's primary aims is offering a more secure JavaScript environment than alternatives like Node.js provide. Its strict permissions model prevents programs from accessing capabilities such as the network, filesystem, and host environment unless the user explicitly grants access.

In previous Deno versions you needed to supply command-line flags such as

        --allow-net
    

(permit networking) and

        --allow-read
    

(allow filesystem reads) to grant these permissions. The

        --prompt
    

flag was offered as an alternative, enumerating each permission as an interactive CLI prompt for you to answer

        y
    

or

        n
    

to.

In Deno v1.19 the

        --prompt
    

flag is automatically included when you omit specific

        --allow-
    

options. This makes it quicker to start applications that need several permissions. You don't need to remember them individually or specify

        --prompt
    

each time.

You can use the

        --no-prompt
    

flag to disable interactive permission prompts altogether. This remains the default mode when Deno's running without a TTY.

Native Web Streams

Deno now uses native

        ReadableStream
    

and

        WritableStream
    

instances for its file, networking, and stdio streams. The adoption of web streams for these functions improves interoperability between APIs and other runtimes such as web browsers. As an example, you can now stream network data straight to a file or standard output:

const file = await Deno.create("./data.txt");
    

const networkResponse = await fetch("https://example.com/data.txt");

await networkResponse.body.pipeTo(file.writable);

Each stream's

        readable
    

and

        writable
    

properties refer to web stream instances. These can be freely passed between the supporting APIs, making complex asynchronous code clear and readable. The use of web streams extends to Deno's server component, letting you pipe streamed data into your HTTP responses.

Simple Stream Compression

Streams have also gained two new transformers,

        CompressionStream
    

and

        DecompressionStream
    

. These simplify the compression and decompression of data passing through streams. Deno's implemented the standardized APIs that already work in Chrome and Opera. Other browsers are expected to add support in the future.

const decompressed = await Deno.open("./file.txt");
    

const compressed = await Deno.open("./file.txt.gz");

await decompressed.readable

.pipeThrough(new CompressionStream("gz"))

.pipeTo(compressed.writable);

The transformers currently support

        gzip
    

and

        deflate
    

-formatted data. There's an open community proposal to extend the API with

        brotli
    

compression too.

Vendored Dependencies

A big new feature of the release is vendored dependencies. Deno now provides a mechanism for vendoring dependencies as part of your own source code. It removes the messy workaround of committing

        DENO_DIR
    

to your repository just so you can make changes to files provided by external modules.

Vendored dependencies give Deno something similar to Node.js'

        node_modules
    

directory. Vendoring a module converts the opaque files in

        DENO_DIR
    

into an on-disk dependency tree where filenames resemble original module names.

The new

        deno vendor
    

command downloads the remote dependencies of specified modules into a local vendor directory:

deno vendor main.ts

The directory will include an import_map.json that you can pass to Deno's --import-map flag when you execute your source. This will instruct Deno to resolve dependencies using the downloaded modules. Adding the --no-remote flag disables remote module loading altogether, guaranteeing the vendored dependencies will be used without exception.

deno run --no-remote --import-map=vendor/import_map.json main.ts

A good use case for this feature is when you want to distribute vendored code alongside your own source. It's also handy for debugging when you need to inject some logging statements into a dependency. You can vendor the target module to conveniently browse and edit its source files. Once you're done, remove the vendor directory to revert to the regular module loading system.

Improved Development Experience

Other new improvements enhance the developer experience and Deno's debugging tools. Here are some of the changes you can benefit from:

  • More reliable compilation - The deno compile command serializes your dependency graph directly into the final binary. This removes the bundling step used in older Deno versions, ensuring code execution order remains correct. Compiled binaries should behave more predictably and be consistent with deno run.
  • Circular references in console.log - Objects containing circular references are now clearly displayed in console.log output. Each reference includes an indicator of the target object and the circle count of the current iteration.
  • Easily save coverage reports - The deno coverage report has gained an --output flag that can be used to send output straight to a file (deno coverage --lcov --output=coverage.lcov coverage/). Previously you needed to use shell redirection to manually pipe the command's standard output into files.
  • Disable file watcher console clears - Deno's --watch flag used to clear the console each time it restarted the running process. This behavior can now be disabled with the --no-clear-screen flag. It lets you retain console output after files are changed.
  • Reduced ambiguity in the Deno.File API - Deno.File is now Deno.FsFile to avoid confusion with the standardized File web API. You should update Deno.File references to the new variant to make it explicit that you're accessing local filesystem resources. Deno.File remains usable with deprecation warnings until Deno v2.

There are also new unstable APIs to get the system user ID of the running process and discover available network interfaces. The existing unstable Unix sockets API can now be used to serve HTTP content. Finally, the signal listeners API for subscribing to system signals like SIGINT and SIGTERM has been promoted to stable status.

Upgrading

You can upgrade to the new release by running the deno upgrade command. This will automatically download the latest version, unzip it, and overwrite your current Deno installation. You can rollback to v1.18 if you need to using deno upgrade --version 1.18.2.

Summary

Deno v1.19 is another healthy release for the JavaScript and TypeScript runtime. It streamlines several aspects of the development experience ranging from stream handling to the deno command-line utilities.

The release also bumps the V8 runtime up to 9.9. This adds new internalization features including more properties on the Intl.Locale object and an Intel.supportedValuesOf() function to check whether specific components are available. You can now use these capabilities in your Deno programs.