Deno Runtime
Learn about the available functions in Deno and how to work with APIs in it.
We'll cover the following
Functions
Deno provides a set of functions included in the runtime as globals in the Deno
namespace. The runtime APIs can be used to do the most elementary, low-level things.
Types of functions
Two types of functions are available on Deno without any imports:
- Web APIs
- The
Deno
namespace
Whenever there’s a behavior in Deno that also exists on the browser, Deno mimics the browser APIs. Those are Web APIs. If you’re coming from the JavaScript world, you’ll probably be familiar with most of them. We’re speaking about functions such as fetch
, addEventListener
, and setTimeout
, and objects such as window
, Event
, and console
, among others.
Code written using Web APIs can be bundled and run in the browser without transformations.
The other big part of the APIs exposed by the runtime lives inside a global namespace named Deno
. We can use the REPL and the documentation, two of the things we explored earlier in this course, to explore it and get a quick grasp of what functions it includes.
Note: To access the documentation of all the symbols included in Deno, run the
doc
command with the--builtin
flag:deno doc --builtin
.
Stability
The functions inside the Deno
namespace are considered stable from version 1.0.0 onward. This means the Deno team will try to support them across newer versions and will do its best to keep them compatible with future changes.
Features still not considered stable for production live under the --unstable
flag, as we’ve used them in previous examples.
The documentation of unstable modules can be accessed using the --unstable
flag with the doc
command or by accessing this page of Deno’s documentation.
The standard library is not yet considered stable by the Deno team, so they have a different version from the CLI (currently, we are using version 0.83.0).
In contrast with the Deno
namespace functions, the standard library doesn’t normally need the --unstable
flag to run. The exception is if any module from the standard library uses unstable functions from the Deno
namespace.
Program lifecycle
Deno supports the browser compatible load
and unload
events that can be used to run setup and cleanup code.
Handlers can be written in two different ways:
- With
addEventListener
- By overriding the
window.onload
andwindow.onunload
functions.
The load
events can be asynchronous, but the same is not true for unload
events because they can’t be canceled.
Using addEventListener
enables us to register unlimited handles, for instance, create a file called add-event-listener
:
addEventListener("load", () => {console.log("loaded 1");});addEventListener("unload", () => {console.log("unloaded 1");});addEventListener("load", () => {console.log("loaded 2");});addEventListener("unload", () => {console.log("unloaded 2");});console.log("Exiting...");
If we run the preceding code, we get the following output:
deno run program-lifecycle/add-event-listener.js
Exiting...loaded 1loaded 2unloaded 1unloaded 2
Another way to schedule code to run on setup and teardown phases is by overriding the onload
and onunload
functions from the window
object. These functions have the particularity that only the last to be assigned runs. This happens because they override one another; see the following code, for instance:
window.onload = () => {console.log("onload 1");};window.onunload = () => {console.log("onunload 1");};window.onload = () => {console.log("onload 2");};window.onunload = () => {console.log("onunload 2");};console.log("Exiting");
By running the preceding program, we got the following output:
deno run program-lifecycle/window-on-load.js
Exitingonload 2onunload 2
If we then look at the initial code we wrote, we can understand that the first two declarations were overridden by the two declarations following them. That’s what happens when we override the onunload
and onload
functions.
window.onload = () => { console.log("onload 1"); }; window.onunload = () => { console.log("onunload 1"); }; window.onload = () => { console.log("onload 2"); }; window.onunload = () => { console.log("onunload 2"); }; console.log("Exiting");
Web APIs
To demonstrate that we can use the Web APIs the same way we can use on the browser, we’ll write a rudimentary program that fetches the Deno website logo, converts it to base64, and prints to the console an HTML page with the base64 of the image there. Let’s do this by following these steps:
- Create a file called
fetch-Deno-logo.js
, and fetch the request to"https://deno.land/logo.svg"
:
fetch("https://deno.land/logo.svg")
2. Convert it into blob:
fetch("https://deno.land/logo.svg").then(r =>r.blob())
Get the text out of the
blob
object, and convert it intobase64
usingbtoa
:
fetch("https://deno.land/logo.svg ").then(r =>r.blob()).then(async (img) => {const base64 = btoa(await img.text())});
Print to the console an HTML page with an image tag using the base64 image:
fetch("https://deno.land/logo.svg ").then(r =>r.blob()).then(async (img) => {const base64 = btoa(await img.text())console.log(`<html><img src="data:image/svg+xml;base64,${base64}" /></html>`)})
When we run this, we get the expected output:
deno run --allow-net web-apis/fetch-deno-logo.js
<html><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyMCA1MTIwIj48dGl0bGU+RGVubyBsb2dvPC90aXRsZT48cGF0aCBkPSJNMjU2MCAwYTI1NjAgMjU2MCAwIDEgMSAwIDUxMjAgMjU2MCAyNTYwIDAgMCAxIDAtNTEyMHoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjQ2MCAxNDQ5Yy03NDQgMC0xMzI0IDQ2OS0xMzI0IDEwNTIgMCA1NTAgNTMzIDkwMSAxMzU5IDg4NGwyNS0xIDkxLTMtMjMgNjAgMyA2YTY2OCA2NjggMCAwIDEgMTggNDdsMiA2IDMgMTAgNCAxNCAzIDkgNCAxMCAzIDExIDQgMTYgNSAxNyAzIDExIDUgMTggNSAxOSA0IDE5IDUgMjAgNCAxNCA1IDIyIDUgMjIgNyAzMCAzIDE2IDUgMjQgNSAyNSA2IDI2IDcgMzcgNiAzMCA4IDQyIDQgMjEgNyAzMyA2IDM0IDggNDYgOSA0OCA4IDUwIDkgNTEgOSA1MiA5IDU0IDkgNTYgNyA0MyAxMSA3MyA1IDMwIDEyIDc3IDkgNjMgOCA0OCA5IDY2IDUgMzNjNTQ5LTczIDEwMzctMzM5IDEzOTMtNzI4bDExLTEyLTUxLTE5MC0xMzUtNTA1LTg0LTMxNC03NC0yNzYtNDYtMTY4LTI5LTEwNi0xNy02NC0xNi01Ni02LTI0LTQtMTMtMi03LTItNmMtNzgtMjUxLTIyOS00NzMtNDM1LTYzNC0yNDItMTg5LTU0OS0yODgtOTA3LTI4OHptLTY1NCAyNjY5Yy02NS0xOC0xMzMgMjAtMTUyIDg1bC0xIDMtMTEyIDQxNmEyMjg3IDIyODcgMCAwIDAgMjE1IDkzbDE3IDcgMTIxLTQ1MSAxLTNjMTYtNjYtMjMtMTMzLTg5LTE1MHptNjk3LTMwNWMtNjYtMTgtMTM0IDIwLTE1MyA4NWwtMSAzLTE3MCA2MzB2M2ExMjUgMTI1IDAgMCAwIDI0MSA2NWwxLTMgMTcwLTYzMHYtM2wzLTE0IDEtNS00LTIxLTYtMjktNC0xOGExMjUgMTI1IDAgMCAwLTc4LTYzem0tMTE4NS02NDktOCAxOS0xIDQtMTcwIDYzMC0xIDNhMTI1IDEyNSAwIDAgMCAyNDEgNjZsMS0zIDE1NC01NzJjLTgwLTQyLTE1My05Mi0yMTYtMTQ3em0tNDA1LTcyNWMtNjYtMTctMTM0IDIxLTE1MyA4NWwtMSAzLTE3MCA2MzB2M2ExMjUgMTI1IDAgMCAwIDI0MSA2NmwxLTMgMTcwLTYzMHYtM2MxNi02Ni0yMy0xMzMtODgtMTUxem0zODExLTE0M2MtNjUtMTctMTMzIDIxLTE1MiA4NWwtMSAzLTE3MCA2MzAtMSAzYTEyNSAxMjUgMCAwIDAgMjQyIDY2di0zbDE3MS02MzB2LTRjMTYtNjUtMjMtMTMyLTg5LTE1MHpNNTQyIDE0NTVhMjI4NCAyMjg0IDAgMCAwLTI2NyA4MzggMTI0IDEyNCAwIDAgMCA2MiAzOGM2NSAxNyAxMzMtMjEgMTUyLTg1bDEtMyAxNzAtNjMwIDEtM2MxNi02Ni0yMy0xMzMtODktMTUxYTEyNyAxMjcgMCAwIDAtMzAtNHptMzc1MiA0Yy02Ni0xNy0xMzMgMjEtMTUzIDg1djNsLTE3MCA2MzAtMSAzYTEyNSAxMjUgMCAwIDAgMjQxIDY2bDEtMyAxNzAtNjMwIDEtM2MxNi02Ni0yNC0xMzMtODktMTUxeiIvPjxwYXRoIGQ9Ik0yNjIwIDE4NzBhMTYwIDE2MCAwIDEgMSAwIDMyMCAxNjAgMTYwIDAgMCAxIDAtMzIweiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMjgyIDg2MGMtNjUtMTctMTMzIDIxLTE1MiA4NWwtMSAzLTE3MCA2MzAtMSAzYTEyNSAxMjUgMCAwIDAgMjQxIDY2bDEtMyAxNzAtNjMwIDEtNGMxNi02NS0yMy0xMzItODktMTUwem0yMTg1IDExOWMtNjYtMTctMTM0IDIxLTE1MyA4NWwtMSAzLTExNCA0MjRhMTM5OSAxMzk5IDAgMCAxIDIxMSAxMjhsMTEgOSAxMzQtNDk1di0zYzE2LTY2LTIzLTEzMy04OC0xNTF6TTIzNTUgMjY5YTIyOTkgMjI5OSAwIDAgMC0yMzggMzRsLTE3IDMtMTU4IDU4Ny0xIDNhMTI1IDEyNSAwIDAgMCAyNDEgNjVsMS0zIDE3MC02MzAgMS0zYTEyNCAxMjQgMCAwIDAgMS01NnptMTU2NCA0MzUtMzMgMTI0LTEgM2ExMjUgMTI1IDAgMCAwIDI0MSA2NWwxLTMgNC0xM2EyMzEyIDIzMTIgMCAwIDAtMTk3LTE2NWwtMTUtMTF6bS05ODktNDE0LTYwIDIyMy0xIDNhMTI1IDEyNSAwIDAgMCAyNDEgNjVsMS0zIDYzLTIzNWEyMjg2IDIyODYgMCAwIDAtMjI2LTUwbC0xOC0zeiIvPjwvc3ZnPg==" /></html>
Now, with the help of *nix output redirection features, we can create an HTML file with the output of our script:
deno run --allow-net web-apis/fetch-deno-logo.js > web-apis/deno-logo.html
We can now inspect the file.
Note: Use the
ls
command to see theweb-apis
folder in the directory. Use thecd
command to move to theweb-apis
folder. There we can find thedeno-logo.html
file.
It's also possible to directly run a script from the Deno standard library to serve the current folder:
deno run --allow-net --allow-read https://deno.land/std@0.83.0/http/file_server.ts web-apis
The command above will show the output as follows:
Check https://deno.land/std@0.65.0/http/file_server.tsHTTP server listening on http://0.0.0.0:4507
Practice the commands in the widget provided below by clicking “Run” and typing the commands in the terminal.
Please execute the commands above in the same order they are written. By navigating to the link provided under the “Run” button of the widget and navigating to /deno-logo.html
, we can check that the image is there and working.
fetch("https://deno.land/logo.svg") .then((r) => r.blob()) .then(async (img) => { const base64 = btoa(await img.text()); console.log(`<html> <img src="data:image/svg+xml;base64,${base64}" /> </html> `); });
Clicking the deno-logo.html
file will show the following output:
These are just examples of Web APIs that are supported in Deno. In this specific example, we’ve used fetch
and btoa
, but more will be used throughout the chapter.
Feel free to experiment with these already familiar APIs, either by writing simple scripts or by using the REPL. In the rest of the course, we’ll use known functions from the Web APIs.