Tip: this article is pretty long, you can download it as PDF / ePub / Mobi to read it later
I explore new projects every week, and it’s rare that one hits my attention so much as Deno did.
What is Deno?
If you are familiar with Node.js, the popular server-side JavaScript ecosystem, then Deno is just like Node. Except deeply improved in many ways.
Let’s start from a quick list of the features I like the most about Deno:
- It is based on modern features of the JavaScript language
- It has an extensive standard library
- It has TypeScript at its core, which brings a huge advantage in many different ways, including a first-class TypeScript support (you don’t have to separately compile TypeScript, it’s automatically done by Deno)
- It embraces ES modules
- It has no package manager
- It has a first-class
await
- It as a built-in testing facility
- It aims to be browser-compatible as much as it can, for example by providing a built-in
fetch
and the globalwindow
object
We’ll explore all of those features in this guide.
After you use Deno and learn to appreciate its features, Node.js will look like something old.
Especially because the Node.js API is callback based, as it was written way before promises and async/await. There’s no change in place for that in Node, as such a change would be monumental, so we’re stuck to callbacks or to promisifying API calls.
Node.js is awesome and will continue to be the de facto standard in the JavaScript world. But I think we’ll gradually see Deno more adopted because of its first-class TypeScript support and modern standard library.
Deno can afford to have everything written with modern technologies, since there’s no backward compatibility to maintain. Of course there’s no guarantee that in a decade the same will happen to Deno and a new technology will emerge, but this is the reality at the moment.
Why Deno? Why now?
Deno was announced almost 2 years ago by the Node.js original creator Ryan Dahl at JSConf EU. Watch the YouTube video of the talk, it’s very interesting and it’s a mandatory watch if you are involved in Node.js and JavaScript in general.
Every project manager must take decisions. Ryan regretted some early decisions in Node. Also, technology evolves, and today JavaScript is a totally different language than what it was back in 2009 when Node started. Think about the modern ES6/2016/2017 features, and so on.
So he started a new project to create some sort of second wave of JavaScript-powered server side apps.
The reason I am writing this guide now and not back then is because technologies need a lot of time to mature. And we have finally reached Deno 1.0 (1.0 should be released on May 13, 2020), the first release of Deno officially declared stable.
That’s might seem just a number, but 1.0 means there will not be major breaking changes until Deno 2.0, which is a big deal when you dive into a new technology - you don’t want to learn something and then have it change too fast.
Should you learn Deno?
That’s a big question.
Learning something new such as Deno is a big effort. My suggestion is that if you are starting out now with server-side JS and you don’t know Node yet, and never wrote any TypeScript, I’d start with Node.
No one was ever fired for choosing Node.js (paraphrasing a common quote).
But if you love TypeScript, don’t depend on a gazillion npm packages in your projects and you want to use await
anywhere, hey Deno might be what you’re looking for.
Will it replace Node.js?
No. Node.js is a giant, well established, incredibly well supported technology that is going to stay for decades.
First-class TypeScript support
Deno is written in Rust and TypeScript, two of the languages that today are really growing fast.
In particular being written in TypeScript means we get a lot of the benefits of TypeScript even if we might choose to write our code in plain JavaScript.
And running TypeScript code with Deno does not require a compilation step - Deno does that automatically for you.
You are not forced to write in TypeScript, but the fact the core of Deno is written in TypeScript is huge.
First, an increasingly big percentage of JavaScript programmers love TypeScript.
Second, the tools you use can infer many information about software written in TypeScript, like Deno.
This means that while we code in VS Code for example, which obviously has a tight integration with TypeScript since both are developed at MicroSoft, we can get benefits like type checking as we write our code, and advanced IntelliSense features. In other words the editor can help us in a deeply useful way.
Similarities and differences with Node.js
Since Deno is basically a Node.js replacement, it’s useful to compare the two directly.
Similarities:
- Both are developed upon the V8 Chromium Engine
- Both are great for developing server-side with JavaScript
Differences:
- Node is written in C++ and JavaScript. Deno is written in Rust and TypeScript.
- Node has an official package manager called
npm
. Deno does not, and instead lets you import any ES Module from URLs. - Node uses the CommonJS syntax for importing pacakges. Deno uses ES Modules, the official way.
- Deno uses modern ECMAScript features in all its API and standard library, while Node.js uses a callbacks-based standard library and has no plans to upgrade it.
- Deno offers a sandbox security layer through permissions. A program can only access the permissions set to the executable as flags by the user. A Node.js program can access anything the user can access
- Deno has for a long time envisioned the possibility of compiling a program into an executable that you can run without external dependencies, like Go, but it’s still not a thing yet. That’d be a game changer.
No package manager
Having no package manager and having to rely on URLs to host and import packages has pros and cons. I really like the pros: it’s very flexible, we can create packages without publishing them on a repository like npm.
I think that some sort of package manager will emerge, but nothing official is out yet.
The Deno website provides code hosting (and thus distribution through URLs) to 3rd party packages: https://deno.land/x/
Install Deno
Enough talk! Let’s install Deno.
The easiest way is to use Homebrew:
brew install deno
Once this is done, you will have access to the deno
command. Here’s the help that you can get using deno --help
:
flavio@mbp~> deno --help
deno 0.42.0
A secure JavaScript and TypeScript runtime
Docs: https://deno.land/std/manual.md
Modules: https://deno.land/std/ https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues
To start the REPL, supply no arguments:
deno
To execute a script:
deno run https://deno.land/std/examples/welcome.ts
deno https://deno.land/std/examples/welcome.ts
To evaluate code in the shell:
deno eval "console.log(30933 + 404)"
Run 'deno help run' for 'run'-specific flags.
USAGE:
deno [OPTIONS] [SUBCOMMAND]
OPTIONS:
-h, --help
Prints help information
-L, --log-level <log-level>
Set log level [possible values: debug, info]
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-V, --version
Prints version information
SUBCOMMANDS:
bundle Bundle module and dependencies into single file
cache Cache the dependencies
completions Generate shell completions
doc Show documentation for a module
eval Eval script
fmt Format source files
help Prints this message or the help of the given subcommand(s)
info Show info about cache or info related to source file
install Install script as an executable
repl Read Eval Print Loop
run Run a program given a filename or url to the module
test Run tests
types Print runtime TypeScript declarations
upgrade Upgrade deno executable to newest version
ENVIRONMENT VARIABLES:
DENO_DIR Set deno's base directory (defaults to $HOME/.deno)
DENO_INSTALL_ROOT Set deno install's output directory
(defaults to $HOME/.deno/bin)
NO_COLOR Set to disable color
HTTP_PROXY Proxy address for HTTP requests
(module downloads, fetch)
HTTPS_PROXY Same but for HTTPS
The Deno commands
Note the SUBCOMMANDS
section in the help, that lists all the commands we can run. What subcommands do we have?
bundle
bundle module and dependencies of a project into single filecache
cache the dependenciescompletions
generate shell completionsdoc
show documentation for a moduleeval
to evaluate a piece of code, e.g.deno eval "console.log(1 + 2)"
fmt
a built-in code formatter (similar togofmt
in Go)help
prints this message or the help of the given subcommand(s)info
show info about cache or info related to source fileinstall
install script as an executablerepl
Read-Eval-Print-Loop (the default)run
run a program given a filename or url to the moduletest
run teststypes
print runtime TypeScript declarationsupgrade
upgradedeno
to the newest version
You can run deno <subcommand> help
to get specific additional documentation for the command, for example deno run --help
.
As the help says, we can use this command to start a REPL (Read-Execute-Print-Loop) using deno
without any other option.
This is the same as running deno repl
.
A more common way you’ll use this command is to execute a Deno app contained in a TypeScript file.
You can run both TypeScript (.ts
) files, or JavaScript (.js
) files.
If you are unfamiliar with TypeScript, don’t worry: Deno is written in TypeScript, buf you can write your “client” applications in JavaScript.
My TypeScript tutorial will help you get up and running quickly with TypeScript if you want.
Your first Deno app
Let’s run a Deno app for the first time.
What I find pretty amazing is that you don’t even have to write a single line - you can run a command from any URL.
Deno downloads the program, compiles it and then runs it:
Of course running arbitrary code from the Internet is not a practice generally recommendable. In this case we are running it from the Deno official site, plus Deno has a sandbox that prevents programs to do anything you don’t want to allow. More on this later.
This program is very simple, just a console.log()
call:
console.log('Welcome to Deno 🦕')
If you open the https://deno.land/std/examples/welcome.ts URL with the browser, you’ll see this page:
Weird, right? You’d probably expect a TypeScript file, instead we have a web page. The reason is the Web server of the Deno website knows you’re using a browser and serves you a more user friendly page.
Download the same UR using wget
for example, which requests the text/plain
version of it instead of text/html
:
If you want to run the program again, it’s now cached by Deno and it does not need to download it again:
You can force a reload of the original source with the --reload
flag:
deno run
has lots of different options that were not listed in the deno --help
. Instead, you need to run deno run --help
to reveal them:
flavio@mbp~> deno run --help
deno-run
Run a program given a filename or url to the module.
By default all programs are run in sandbox without access to disk, network or
ability to spawn subprocesses.
deno run https://deno.land/std/examples/welcome.ts
Grant all permissions:
deno run -A https://deno.land/std/http/file_server.ts
Grant permission to read from disk and listen to network:
deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts
Grant permission to read whitelisted files from disk:
deno run --allow-read=/etc https://deno.land/std/http/file_server.ts
USAGE:
deno run [OPTIONS] <SCRIPT_ARG>...
OPTIONS:
-A, --allow-all
Allow all permissions
--allow-env
Allow environment access
--allow-hrtime
Allow high resolution time measurement
--allow-net=<allow-net>
Allow network access
--allow-plugin
Allow loading plugins
--allow-read=<allow-read>
Allow file system read access
--allow-run
Allow running subprocesses
--allow-write=<allow-write>
Allow file system write access
--cached-only
Require that remote dependencies are already cached
--cert <FILE>
Load certificate authority from PEM encoded file
-c, --config <FILE>
Load tsconfig.json configuration file
-h, --help
Prints help information
--importmap <FILE>
UNSTABLE:
Load import map file
Docs: https://deno.land/std/manual.md#import-maps
Specification: https://wicg.github.io/import-maps/
Examples: https://github.com/WICG/import-maps#the-import-map
--inspect=<HOST:PORT>
activate inspector on host:port (default: 127.0.0.1:9229)
--inspect-brk=<HOST:PORT>
activate inspector on host:port and break at start of user script
--lock <FILE>
Check the specified lock file
--lock-write
Write lock file. Use with --lock.
-L, --log-level <log-level>
Set log level [possible values: debug, info]
--no-remote
Do not resolve remote modules
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-r, --reload=<CACHE_BLACKLIST>
Reload source code cache (recompile TypeScript)
--reload
Reload everything
--reload=https://deno.land/std
Reload only standard modules
--reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts
Reloads specific modules
--seed <NUMBER>
Seed Math.random()
--unstable
Enable unstable APIs
--v8-flags=<v8-flags>
Set V8 command line options. For help: --v8-flags=--help
ARGS:
<SCRIPT_ARG>...
script args
Deno code examples
In addition to the one we ran above, the Deno website provides some other examples you can check out: https://deno.land/std/examples/.
At the time of writing we can find:
cat.ts
prints the content a list of files provided as argumentscatj.ts
prints the content a list of files provided as argumentschat/
an implementation of a chatcolors.ts
an example ofcurl.ts
a simple implementation ofcurl
that prints the content of the URL specified as argumentecho_server.ts
a TCP echo servergist.ts
a program to post files to gist.github.comtest.ts
a sample test suitewelcome.ts
a simple console.log statement (the first program we ran above)xeval.ts
allows you to run any TypeScript code for any line of standard input received. Once known asdeno xeval
but since removed from the official command.
Your first Deno app (for real)
Let’s write some code.
Your first Deno app you ran using deno run https://deno.land/std/examples/welcome.ts
was an app that someone else wrote, so you didn’t see anything in regards to how Deno code looks like.
We’ll start from the default example app listed on the Deno official website:
import { serve } from 'https://deno.land/std/http/server.ts'
const s = serve({ port: 8000 })
console.log('http://localhost:8000/')
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
This code imports the serve
function from the http/server
module. See? We don’t have to install it first, and it’s also not stored on your local machine like it happens with Node modules. This is one reason why the Deno installation was so fast.
Importing from https://deno.land/std/http/server.ts
imports the latest version of the module. You can import a specific version using @VERSION
, like this:
import { serve } from 'https://deno.land/std@v0.42.0/http/server.ts'
The serve
function is defined like this in this file:
/**
* Create a HTTP server
*
* import { serve } from "https://deno.land/std/http/server.ts";
* const body = "Hello World\n";
* const s = serve({ port: 8000 });
* for await (const req of s) {
* req.respond({ body });
* }
*/
export function serve(addr: string | HTTPOptions): Server {
if (typeof addr === 'string') {
const [hostname, port] = addr.split(':')
addr = { hostname, port: Number(port) }
}
const listener = listen(addr)
return new Server(listener)
}
We proceed to instantiate a server calling the serve()
function passing an object with the port
property.
Then we run this loop to respond to every request coming from the server.
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
Note that we use the await
keyword without having to wrap it into an async
function because Deno implements top-level await.
Let’s run this program locally. I assume you use VS Code, but you can use any editor you like.
I recommend installing the Deno extension from justjavac
(there was another one with the same name when I tried, but deprecated - might disappear in the future)
The extension will provide several utilities and nice thing to VS Code to help you write your apps.
Now create an app.ts
file in a folder and paste the above code:
Now run it using deno run app.ts
:
Deno downloads all the dependencies it needs, by first downloading the one we imported.
The https://deno.land/std/http/server.ts file has several dependencies on its own:
import { encode } from '../encoding/utf8.ts'
import { BufReader, BufWriter } from '../io/bufio.ts'
import { assert } from '../testing/asserts.ts'
import { deferred, Deferred, MuxAsyncIterator } from '../async/mod.ts'
import {
bodyReader,
chunkedBodyReader,
emptyReader,
writeResponse,
readRequest,
} from './_io.ts'
import Listener = Deno.Listener
import Conn = Deno.Conn
import Reader = Deno.Reader
and those are imported automatically.
At the end though we have a problem:
What is happening? We have a permission denied problem.
Let’s talk about the sandbox.
The Deno sandbox
I mentioned previously that Deno has a sandbox that prevents programs to do anything you don’t want to allow.
What does this mean?
One of the things that Ryan mentions in the Deno introduction talk is that sometimes you want to run a JavaScript program outside of the Web Browser, and yet do not allow it to access anything it wants on your system. Or talk to the external world using a network.
There’s nothing stopping a Node.js app to get your SSH keys or any other thing on your system and send it to a server. This is why we usually only install Node packages from trusted sources, but how can we know if one of the projects we use gets hacked and in turn everyone else does?
Deno tries to replicate the same permission model that the browser implements. No JavaScript running in the browser can do shady things on your system unless you explicitly allow it.
Going back to Deno, if a program want to access the network like in the previous case, then we need to give it permission.
We can do so by passing a flag when we run the command, in this case --allow-net
:
deno run --allow-net app.ts
The app is now running an HTTP server on port 8000:
Other flags allow Deno to unlock other functionality:
--allow-env
allow environment access--allow-hrtime
allow high resolution time measurement--allow-net=<allow-net>
allow network access--allow-plugin
allow loading plugins--allow-read=<allow-read>
allow file system read access--allow-run
allow running subprocesses--allow-write=<allow-write>
allow file system write access--allow-all
allow all permissions (same as-A
)
Permissions for net
, read
and write
can be granular. For example, you can allow reading from a specific folder using --allow-read=/dev
Formatting code
One of the things I really liked from Go was the gofmt
command that came with the Go compiler. All Go code looks the same. Everyone uses gofmt
.
JavaScript programmers are used to running Prettier, and deno fmt
actually runs that under the hood.
Say you have a file formatted badly like this:
You run deno fmt app.ts
and it’s automatically formatted properly, also adding semicolons where missing:
The standard library
The Deno standard library is extensive despite the project being very young.
It includes:
archive
tar archive utilitiesasync
async utilitiesbytes
helpers to manipulate bytes slicesdatetime
date/time parsingencoding
encoding/decoding for various formatsflags
parse command-line flagsfmt
formatting and printingfs
file system APIhash
crypto libhttp
HTTP serverio
I/O liblog
logging utilitiesmime
support for multipart datanode
Node.js compatibility layerpath
path manipulationws
websockets
Another Deno example
Let’s see another example of a Deno app, from the Deno examples: cat
:
const filenames = Deno.args
for (const filename of filenames) {
const file = await Deno.open(filename)
await Deno.copy(file, Deno.stdout)
file.close()
}
This assigns to the filenames
variable the content of Deno.args
, which is a variable containing all the arguments sent to the command.
We iterate through them, and for each we use Deno.open()
to open the file and we use Deno.copy()
to print the content of the file to Deno.stdout
. Finally we close the file.
If you run this using
deno run https://deno.land/std/examples/cat.ts
The program is downloaded and compiled, and nothing happens because we didn’t specify any argument.
Try now
deno run https://deno.land/std/examples/cat.ts app.ts
assuming you have app.ts
from the previous project in the same folder.
You’ll get a permission error:
Because Deno disallows access to the filesystem by default. Grant access to the current folder using --allow-read=./
:
deno run --allow-read=./ https://deno.land/std/examples/cat.ts app.ts
Is there an Express/Hapi/Koa/* for Deno?
Yes, definitely. Check out projects like
Example: use Oak to build a REST API
I want to make a simple example of how to build a REST API using Oak. Oak is interesting because it’s inspired by Koa, the popular Node.js middleware, and due to this it’s very familiar if you’ve used that before.
The API we’re going to build is very simple.
Our server will store, in memory, a list of dogs with name and age.
We want to:
- add new dogs
- list dogs
- get details about a specific dog
- remove a dog from the list
- update a dog age
We’ll do this in TypeScript, but nothing stops you from writing the API in JavaScript - you simply remove the types.
Create a app.ts
file.
Let’s start by importing the Application
and Router
objects from Oak:
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
then we get the environment variables PORT and HOST:
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
By default our app will run on localhost:4000.
Now we create the Oak application and we start it:
const router = new Router()
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT}...`)
await app.listen(`${HOST}:${PORT}`)
Now the app should be compiling fine.
Run
deno run --allow-env --allow-net app.ts
and Deno will download the dependencies:
and then listen on port 4000.
The following times you’ll run the command, Deno will skip the installation part because those packages are already cached:
At the top of the file, let’s define an interface for a dog, then we declare an initial dogs
array of Dog objects:
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
Now let’s actually implement the API.
We have everything in place. After you create the router, let’s add some functions that will be invoked any time one of those endpoints is hit:
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
See? We define
GET /dogs
GET /dogs/:name
POST /dogs
PUT /dogs/:name
DELETE /dogs/:name
Let’s implement those one-by-one.
Starting from GET /dogs
, which returns the list of all the dogs:
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}
Next, here’s how we can retrieve a single dog by name:
export const getDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const dog = dogs.filter((dog) => dog.name === params.name)
if (dog.length) {
response.status = 200
response.body = dog[0]
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
Here is how we add a new dog:
export const addDog = async ({
request,
response,
}: {
request: any
response: any
}) => {
const body = await request.body()
const dog: Dog = body.value
dogs.push(dog)
response.body = { msg: 'OK' }
response.status = 200
}
Notice that I now used const body = await request.body()
to get the content of the body, since the name
and age
values are passed as JSON.
Here’s how we update a dog’s age:
export const updateDog = async ({
params,
request,
response,
}: {
params: {
name: string
}
request: any
response: any
}) => {
const temp = dogs.filter((existingDog) => existingDog.name === params.name)
const body = await request.body()
const { age }: { age: number } = body.value
if (temp.length) {
temp[0].age = age
response.status = 200
response.body = { msg: 'OK' }
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
and here is how we can remove a dog from our list:
export const removeDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const lengthBefore = dogs.length
dogs = dogs.filter((dog) => dog.name !== params.name)
if (dogs.length === lengthBefore) {
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
return
}
response.body = { msg: 'OK' }
response.status = 200
}
Here’s the complete example code:
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}
export const getDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const dog = dogs.filter((dog) => dog.name === params.name)
if (dog.length) {
response.status = 200
response.body = dog[0]
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
export const addDog = async ({
request,
response,
}: {
request: any
response: any
}) => {
const body = await request.body()
const { name, age }: { name: string; age: number } = body.value
dogs.push({
name: name,
age: age,
})
response.body = { msg: 'OK' }
response.status = 200
}
export const updateDog = async ({
params,
request,
response,
}: {
params: {
name: string
}
request: any
response: any
}) => {
const temp = dogs.filter((existingDog) => existingDog.name === params.name)
const body = await request.body()
const { age }: { age: number } = body.value
if (temp.length) {
temp[0].age = age
response.status = 200
response.body = { msg: 'OK' }
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
export const removeDog = ({
params,
response,
}: {
params: {
name: string
}
response: any
}) => {
const lengthBefore = dogs.length
dogs = dogs.filter((dog) => dog.name !== params.name)
if (dogs.length === lengthBefore) {
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
return
}
response.body = { msg: 'OK' }
response.status = 200
}
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT}...`)
await app.listen(`${HOST}:${PORT}`)
Find out more
The Deno official website is https://deno.land
The API documentation is available at https://doc.deno.land and https://deno.land/typedoc/index.html
awesome-deno https://github.com/denolib/awesome-deno
A few more random tidbits
- Deno provides a built-in
fetch
implementation that matches the one available in the browser - Deno has a compatibility layer with the Node.js stdlib in progress
Download my free JavaScript Beginner's Handbook
More js tutorials:
- Things to avoid in JavaScript (the bad parts)
- Deferreds and Promises in JavaScript (+ Ember.js example)
- How to upload files to the server using JavaScript
- JavaScript Coding Style
- An introduction to JavaScript Arrays
- Introduction to the JavaScript Programming Language
- The Complete ECMAScript 2015-2019 Guide
- Understanding JavaScript Promises
- The Lexical Structure of JavaScript
- JavaScript Types
- JavaScript Variables
- A list of sample Web App Ideas
- An introduction to Functional Programming with JavaScript
- Modern Asynchronous JavaScript with Async and Await
- JavaScript Loops and Scope
- The Map JavaScript Data Structure
- The Set JavaScript Data Structure
- A guide to JavaScript Template Literals
- Roadmap to Learn JavaScript
- JavaScript Expressions
- Discover JavaScript Timers
- JavaScript Events Explained
- JavaScript Loops
- Write JavaScript loops using map, filter, reduce and find
- The JavaScript Event Loop
- JavaScript Functions
- The JavaScript Glossary
- JavaScript Closures explained
- A tutorial to JavaScript Arrow Functions
- A guide to JavaScript Regular Expressions
- How to check if a string contains a substring in JavaScript
- How to remove an item from an Array in JavaScript
- How to deep clone a JavaScript object
- Introduction to Unicode and UTF-8
- Unicode in JavaScript
- How to uppercase the first letter of a string in JavaScript
- How to format a number as a currency value in JavaScript
- How to convert a string to a number in JavaScript
- this in JavaScript
- How to get the current timestamp in JavaScript
- JavaScript Strict Mode
- JavaScript Immediately-invoked Function Expressions (IIFE)
- How to redirect to another web page using JavaScript
- How to remove a property from a JavaScript object
- How to append an item to an array in JavaScript
- How to check if a JavaScript object property is undefined
- Introduction to ES Modules
- Introduction to CommonJS
- JavaScript Asynchronous Programming and Callbacks
- How to replace all occurrences of a string in JavaScript
- A quick reference guide to Modern JavaScript Syntax
- How to trim the leading zero in a number in JavaScript
- How to inspect a JavaScript object
- The definitive guide to JavaScript Dates
- A Moment.js tutorial
- Semicolons in JavaScript
- The JavaScript Arithmetic operators
- The JavaScript Math object
- Generate random and unique strings in JavaScript
- How to make your JavaScript functions sleep
- JavaScript Prototypal Inheritance
- JavaScript Exceptions
- How to use JavaScript Classes
- The JavaScript Cookbook
- Quotes in JavaScript
- How to validate an email address in JavaScript
- How to get the unique properties of a set of objects in a JavaScript array
- How to check if a string starts with another in JavaScript
- How to create a multiline string in JavaScript
- The ES6 Guide
- How to get the current URL in JavaScript
- The ES2016 Guide
- How to initialize a new array with values in JavaScript
- The ES2017 Guide
- The ES2018 Guide
- How to use Async and Await with Array.prototype.map()
- Async vs sync code
- How to generate a random number between two numbers in JavaScript
- HTML Canvas API Tutorial
- How to get the index of an iteration in a for-of loop in JavaScript
- What is a Single Page Application?
- An introduction to WebAssembly
- Introduction to JSON
- The JSONP Guide
- Should you use or learn jQuery in 2020?
- How to hide a DOM element using plain JavaScript
- How to merge two objects in JavaScript
- How to empty a JavaScript array
- How to encode a URL with JavaScript
- How to set default parameter values in JavaScript
- How to sort an array of objects by a property value in JavaScript
- How to count the number of properties in a JavaScript object
- call() and apply() in JavaScript
- Introduction to PeerJS, the WebRTC library
- Work with objects and arrays using Rest and Spread
- Destructuring Objects and Arrays in JavaScript
- The definitive guide to debugging JavaScript
- The TypeScript Guide
- Dynamically select a method of an object in JavaScript
- Passing undefined to JavaScript Immediately-invoked Function Expressions
- Loosely typed vs strongly typed languages
- How to style DOM elements using JavaScript
- Casting in JavaScript
- JavaScript Generators Tutorial
- The node_modules folder size is not a problem. It's a privilege
- How to solve the unexpected identifier error when importing modules in JavaScript
- How to list all methods of an object in JavaScript
- The String replace() method
- The String search() method
- How I run little JavaScript snippets
- The ES2019 Guide
- The String charAt() method
- The String charCodeAt() method
- The String codePointAt() method
- The String concat() method
- The String endsWith() method
- The String includes() method
- The String indexOf() method
- The String lastIndexOf() method
- The String localeCompare() method
- The String match() method
- The String normalize() method
- The String padEnd() method
- The String padStart() method
- The String repeat() method
- The String slice() method
- The String split() method
- The String startsWith() method
- The String substring() method
- The String toLocaleLowerCase() method
- The String toLocaleUpperCase() method
- The String toLowerCase() method
- The String toString() method
- The String toUpperCase() method
- The String trim() method
- The String trimEnd() method
- The String trimStart() method
- Memoization in JavaScript
- The String valueOf() method
- JavaScript Reference: String
- The Number isInteger() method
- The Number isNaN() method
- The Number isSafeInteger() method
- The Number parseFloat() method
- The Number parseInt() method
- The Number toString() method
- The Number valueOf() method
- The Number toPrecision() method
- The Number toExponential() method
- The Number toLocaleString() method
- The Number toFixed() method
- The Number isFinite() method
- JavaScript Reference: Number
- JavaScript Property Descriptors
- The Object assign() method
- The Object create() method
- The Object defineProperties() method
- The Object defineProperty() method
- The Object entries() method
- The Object freeze() method
- The Object getOwnPropertyDescriptor() method
- The Object getOwnPropertyDescriptors() method
- The Object getOwnPropertyNames() method
- The Object getOwnPropertySymbols() method
- The Object getPrototypeOf() method
- The Object is() method
- The Object isExtensible() method
- The Object isFrozen() method
- The Object isSealed() method
- The Object keys() method
- The Object preventExtensions() method
- The Object seal() method
- The Object setPrototypeOf() method
- The Object values() method
- The Object hasOwnProperty() method
- The Object isPrototypeOf() method
- The Object propertyIsEnumerable() method
- The Object toLocaleString() method
- The Object toString() method
- The Object valueOf() method
- JavaScript Reference: Object
- JavaScript Assignment Operator
- JavaScript Internationalization
- JavaScript typeof Operator
- JavaScript new Operator
- JavaScript Comparison Operators
- JavaScript Operators Precedence Rules
- JavaScript instanceof Operator
- JavaScript Statements
- JavaScript Scope
- JavaScript Type Conversions (casting)
- JavaScript Equality Operators
- The JavaScript if/else conditional
- The JavaScript Switch Conditional
- The JavaScript delete Operator
- JavaScript Function Parameters
- The JavaScript Spread Operator
- JavaScript Return Values
- JavaScript Logical Operators
- JavaScript Ternary Operator
- JavaScript Recursion
- JavaScript Object Properties
- JavaScript Error Objects
- The JavaScript Global Object
- The JavaScript filter() Function
- The JavaScript map() Function
- The JavaScript reduce() Function
- The JavaScript `in` operator
- JavaScript Operators
- How to get the value of a CSS property in JavaScript
- How to add an event listener to multiple elements in JavaScript
- JavaScript Private Class Fields
- How to sort an array by date value in JavaScript
- JavaScript Public Class Fields
- JavaScript Symbols
- How to use the JavaScript bcrypt library
- How to rename fields when using object destructuring
- How to check types in JavaScript without using TypeScript
- How to check if a JavaScript array contains a specific value
- What does the double negation operator !! do in JavaScript?
- Which equal operator should be used in JavaScript comparisons? == vs ===
- Is JavaScript still worth learning?
- How to return the result of an asynchronous function in JavaScript
- How to check if an object is empty in JavaScript
- How to break out of a for loop in JavaScript
- How to add item to an array at a specific index in JavaScript
- Why you should not modify a JavaScript object prototype
- What's the difference between using let and var in JavaScript?
- Links used to activate JavaScript functions
- How to join two strings in JavaScript
- How to join two arrays in JavaScript
- How to check if a JavaScript value is an array?
- How to get last element of an array in JavaScript?
- How to send urlencoded data using Axios
- How to get tomorrow's date using JavaScript
- How to get yesterday's date using JavaScript
- How to get the month name from a JavaScript date
- How to check if two dates are the same day in JavaScript
- How to check if a date refers to a day in the past in JavaScript
- JavaScript labeled statements
- How to wait for 2 or more promises to resolve in JavaScript
- How to get the days between 2 dates in JavaScript
- How to upload a file using Fetch
- How to format a date in JavaScript
- How to iterate over object properties in JavaScript
- How to calculate the number of days between 2 dates in JavaScript
- How to use top-level await in ES Modules
- JavaScript Dynamic Imports
- JavaScript Optional Chaining
- How to replace white space inside a string in JavaScript
- JavaScript Nullish Coalescing
- How to flatten an array in JavaScript
- This decade in JavaScript
- How to send the authorization header using Axios
- List of keywords and reserved words in JavaScript
- How to convert an Array to a String in JavaScript
- How to remove all the node_modules folders content
- How to remove duplicates from a JavaScript array
- Let vs Const in JavaScript
- The same POST API call in various JavaScript libraries
- How to get the first n items in an array in JS
- How to divide an array in multiple equal parts in JS
- How to slow down a loop in JavaScript
- How to load an image in an HTML canvas
- How to cut a string into words in JavaScript
- How to divide an array in half in JavaScript
- How to write text into to an HTML canvas
- How to remove the last character of a string in JavaScript
- How to remove the first character of a string in JavaScript
- How to fix the TypeError: Cannot assign to read only property 'exports' of object '#<Object>' error
- How to create an exit intent popup
- How to check if an element is a descendant of another
- How to force credentials to every Axios request
- How to solve the "is not a function" error in JavaScript
- Gatsby, how to change the favicon
- Loading an external JS file using Gatsby
- How to detect dark mode using JavaScript
- Parcel, how to fix the `regeneratorRuntime is not defined` error
- How to detect if an Adblocker is being used with JavaScript
- Object destructuring with types in TypeScript
- The Deno Handbook: a concise introduction to Deno 🦕
- How to get the last segment of a path or URL using JavaScript
- How to shuffle elements in a JavaScript array
- How to check if a key exists in a JavaScript object
- Event bubbling and event capturing
- event.stopPropagation vs event.preventDefault() vs. return false in DOM events
- Primitive types vs objects in JavaScript
- How can you tell what type a value is, in JavaScript?
- How to return multiple values from a function in JavaScript
- Arrow functions vs regular functions in JavaScript
- In which ways can we access the value of a property of an object?
- What is the difference between null and undefined in JavaScript?
- What's the difference between a method and a function?
- What are the ways we can break out of a loop in JavaScript?
- The JavaScript for..of loop
- What is object destructuring in JavaScript?
- What is hoisting in JavaScript?
- How to change commas into dots with JavaScript
- The importance of timing when working with the DOM
- How to reverse a JavaScript array
- How to check if a value is a number in JavaScript
- How to accept unlimited parameters in a JavaScript function
- JavaScript Proxy Objects
- Event delegation in the browser using vanilla JavaScript
- The JavaScript super keyword
- Introduction to XState
- Are values passed by reference or by value in JavaScript?
- Custom events in JavaScript
- Custom errors in JavaScript
- Namespaces in JavaScript
- A curious usage of commas in JavaScript
- Chaining method calls in JavaScript
- How to handle promise rejections
- How to swap two array elements in JavaScript
- How I fixed a "cb.apply is not a function" error while using Gitbook
- How to add an item at the beginning of an array in JavaScript
- Gatsby, fix the "cannot find module gatsby-cli/lib/reporter" error
- How to get the index of an item in a JavaScript array
- How to test for an empty object in JavaScript
- How to destructure an object to existing variables in JavaScript
- The Array JavaScript Data Structure
- The Stack JavaScript Data Structure
- JavaScript Data Structures: Queue
- JavaScript Data Structures: Set
- JavaScript Data Structures: Dictionaries
- JavaScript Data Structures: Linked lists
- JavaScript, how to export a function
- JavaScript, how to export multiple functions
- JavaScript, how to exit a function
- JavaScript, how to find a character in a string
- JavaScript, how to filter an array
- JavaScript, how to extend a class
- JavaScript, how to find duplicates in an array
- JavaScript, how to replace an item of an array
- JavaScript Algorithms: Linear Search
- JavaScript Algorithms: Binary Search
- JavaScript Algorithms: Selection Sort
- JavaScript Algorithms: Quicksort
- JavaScript Algorithms: Merge Sort
- JavaScript Algorithms: Bubble Sort