You now know most of the JavaScript language. This chapter gives an overview of web development and describes next steps. It answers questions such as:
Web development has become a vast field: Between JavaScript, web browsers, server-side JavaScript, JavaScript libraries, and JavaScript tools, there is a lot to know. Additionally, everything is always changing: some things go out of style, new things are invented, etc.
How can you avoid feeling overwhelmed when faced with this constantly changing vastness of knowledge?
Trust in your ability to learn on demand
It is commendable to learn something out of pure curiosity. But I’m wary of trying to learn everything and spreading oneself too thin. That also induces an anxiety of not knowing enough (because you never will). Instead, trust in your ability to learn things on demand!
These are a few things worth learning for web development:
Browser APIs such as the Document Object Model (DOM), the browsers’ representation of HTML in memory. They are the foundations of any kind of frontend development.
JavaScript-adjacent technologies such as HTML and CSS.
Frontend frameworks: When you get started with web development, it can be instructive to write user interfaces without any libraries. Once you feel more confident, frontend frameworks make many things easier, especially for larger apps. Popular frameworks include: Alpine.js, Angular, Ember, Lit, Preact, Qwik, React, Solid, Stencil, Svelte, Vue.js.
JavaScript runtimes: Some JavaScript platform are for running code on servers. But they are also used for running command-line tools. The most popular runtime is Node.js. Most JavaScript-related tools (even compilers!) are implemented in Node.js-based JavaScript and installed via npm. A good way to get started with Node.js, is to use it for shell scripting.
JavaScript tooling: Modern web development involves many tools. Later in this chapter, there is an overview of the current tooling ecosystem.
Progressive web apps (PWAs): The driving idea behind progressive web apps is to give web apps features that, traditionally, only native apps had – for example: native installation on mobile and desktop operating systems; offline operation; showing notifications to users. Google has published a checklist detailing what makes a web app progressive. The minimum requirements are:
One good resource for learning web development – including JavaScript – is MDN web docs.
WebAssembly is a universal virtual machine that is built into most JavaScript engines. We often get the following distribution of work:
For static code, WebAssembly is quite fast: C/C++ code, compiled to WebAssembly, is about 50% as fast as the same code, compiled to native (source). Use cases include support for new video formats, machine learning, gaming, etc. It helps that it is relatively easy to compile existing code bases (e.g. ones written in C) to WebAssembly.
WebAssembly works well as a compilation target for various languages. Does this mean JavaScript will be compiled to WebAssembly or replaced by another language?
JavaScript engines perform many optimizations for JavaScript’s highly dynamic features. If we wanted to compile JavaScript to WebAssembly, we’d have to implement these optimizations on top of WebAssembly. The result would be slower than current engines and have a similar code base. Therefore, we wouldn’t gain anything.
Does WebAssembly mean that JavaScript is about to be replaced by another language? WebAssembly does make it easier to support languages other than JavaScript in web browsers. But those languages face several challenges on that platform:
For dynamic code, JavaScript is comparatively fast. Therefore, for the foreseeable future, it will probably remain the most popular choice for high-level code. For low-level code, compiling more static languages (such as Rust) to WebAssembly is an intriguing option.
Given that it is just a virtual machine, there are not that many practically relevant things to learn about WebAssembly. But it is worth keeping an eye on its evolving role in web development. It is also becoming popular as a stand-alone virtual machine:
Important standards group in this area: “The Bytecode Alliance is a nonprofit organization dedicated to creating secure new software foundations, building on standards such as WebAssembly and WebAssembly System Interface (WASI).”
WebAssembly System Interface (WASI): “group of standard API specifications for software compiled to the W3C WebAssembly (Wasm) standard. WASI is designed to provide a secure standard interface for applications that can be compiled to Wasm from any language, and that may run anywhere – from browsers to clouds to embedded devices.”
WebAssembly Component Model (WCM): “broad-reaching architecture for building interoperable Wasm libraries, applications, and environments.”
warg – secure registry protocol for Wasm packages: An important foundation for WebAssembly package managers.
In this section, we take a look at:
The former are much more important. The names change, as tools come into and out of style, but I wanted you to see at least some of them.
Building JavaScript means getting from the JavaScript we write to the JavaScript we deploy. The following tools are often involved in this process.
A transpiler is a compiler that compiles source code to source code. Two transpilers that are popular in the JavaScript community are:
TypeScript is a superset of JavaScript. Roughly, it is the latest version of JavaScript plus static typing. The TypeScript compiler tsc
performs two tasks:
One important trend is to use faster tools (such as bundlers, see below) for the relatively simply task of compiling TypeScript to JavaScript and to use the TypeScript compiler only for type-checking during development – which is a complicated task (so far no practical alternatives to tsc
have emerged).
Babel compiles upcoming and modern JavaScript features to older versions of the language. That means we can use new features in our code and still run it on older browsers.
Minification means compiling JavaScript to equivalent, smaller (as in fewer characters) JavaScript. It does so by renaming variables, removing comments, removing whitespace, etc.
For example, given the following input:
let numberOfOccurrences = 5;
if (Math.random()) {
// Math.random() is not zero
numberOfOccurrences++
}
A minifier might produce:
let a=5;Math.random()&&a++;
Bundlers (see below) usually support minification.
Bundlers compile and optimize the code of a JavaScript app. The input of a bundler is many files – all of the app’s code plus the libraries it uses. A bundler combines these input files to produce fewer output files (which tends to improve performance).
A bundler minimizes the size of its output via techniques such as tree-shaking. Tree-shaking is a form of dead code elimination: only those module exports are put in the output that are imported somewhere (across all code, while considering transitive imports).
It is also common to perform compilation steps such as transpiling and minification while bundling.
Popular bundlers include:
Sometimes there are build tasks that involve multiple tools or invoke tools with specific arguments. Task runners (in the tradition of Unix make
) let us define simpler names for such tasks and often also help with connecting tools and processing files. There are:
"scripts"
in package.json
.
Static checking means analyzing source code statically (without running it). It can be used to detect a variety of problems. Tools include:
JavaScript has many testing frameworks – for example:
The most popular package manager for JavaScript is npm. It started as a package manager for Node.js but has since also become dominant for client-side web development and tools of any kind.
The following alternatives to npm use npm’s package registry (think online database):
Additionally, there is JSR (JavaScript Registry):
Intl
and available in most modern browsers.
Given that JavaScript is just one of several kinds of artifacts involved in web development, more tools exist. These are but a few examples: