<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Josh Carvel</title>
    <description>The latest articles on Forem by Josh Carvel (@joshcarvel).</description>
    <link>https://forem.com/joshcarvel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F501446%2Fe4916cfc-8949-4a34-8ebf-db0260a3b0a4.jpg</url>
      <title>Forem: Josh Carvel</title>
      <link>https://forem.com/joshcarvel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joshcarvel"/>
    <language>en</language>
    <item>
      <title>Understanding JS Build Tools (Part 2: Bundling and Transforming)</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Mon, 31 Jul 2023 11:38:15 +0000</pubDate>
      <link>https://forem.com/joshcarvel/understanding-js-build-tools-part-2-bundling-and-transforming-2p39</link>
      <guid>https://forem.com/joshcarvel/understanding-js-build-tools-part-2-bundling-and-transforming-2p39</guid>
      <description>&lt;h2&gt;
  
  
  Intro 🔨
&lt;/h2&gt;

&lt;p&gt;In Part 1, we talked about the benefits of modular JavaScript and package managers, and how this led to the widespread practice of bundling JS before it hits the browser. &lt;/p&gt;

&lt;p&gt;In Part 2, we’re exploring the process of bundling and transforming JavaScript. These days, we tend to use a single tool to do all this work, known as a &lt;strong&gt;build tool.&lt;/strong&gt; We’ll discuss a variety of build tools and the core features they provide, so you can understand how your projects are built and be able to choose and configure a build tool if you need to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Part 1, or good understanding of JavaScript modules and npm&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing your tool 🛒
&lt;/h2&gt;

&lt;p&gt;There are many build tools in the JavaScript community, and they come in many forms. Some are simpler but more ‘opinionated’ in how they are configured, and others are more complicated to set up, but have a lot of flexibility. There’s no perfect tool for your project, unless you make a new one yourself (and now you know why there are so many JavaScript tools!).&lt;/p&gt;

&lt;p&gt;You can see usage statistics and ratings of these tools in the annual &lt;a href="https://2022.stateofjs.com/en-US/libraries/build-tools/"&gt;State of JavaScript survey&lt;/a&gt;. As of now, &lt;em&gt;webpack&lt;/em&gt; is still by far the most used build tool. It falls into the category of being very flexible and potentially very complicated, which has earned it a divisive reputation. It’s also been around for 11 years now, which is a &lt;em&gt;long&lt;/em&gt; time in the JavaScript world.&lt;/p&gt;

&lt;p&gt;A few years after webpack debuted, a couple of other build tools also became quite popular. &lt;em&gt;Rollup,&lt;/em&gt; from the author of Svelte, was designed as a minimal tool which focuses only on bundling JS and allows you to specify plugins for everything else. Meanwhile, a tool called &lt;em&gt;Parcel&lt;/em&gt; sold itself on a zero-config approach, to make it even easier to get started.&lt;/p&gt;

&lt;p&gt;But the biggest change in recent years has been the move away from the idea that JS build tools must be written in JavaScript. Though they’re available to install via npm, the new generation of build tools uses low-level languages to perform build tasks more efficiently. This can streamline the deployment process, but perhaps the biggest advantage is speed of build during development, which can make a huge difference to productivity in big projects.&lt;/p&gt;

&lt;p&gt;One of the pioneers of this approach is &lt;em&gt;esbuild.&lt;/em&gt; It’s still a fairly new and quite minimal project, but it has a major focus on bundling JS &lt;em&gt;very&lt;/em&gt; fast, using the Go language and various performance techniques. The benchmark on the esbuild homepage shows it bundling &lt;em&gt;100x&lt;/em&gt; faster than webpack.&lt;/p&gt;

&lt;p&gt;Other tools are trying to cater for needs that esbuild can’t meet. The author of Vue.js has written &lt;em&gt;Vite.&lt;/em&gt; Its main selling point is around reloading the page during development, which we’ll talk about later. Parcel, meanwhile, was rewritten in Rust for its version 2 - specifically, it makes use of a Rust framework called &lt;em&gt;SWC (Speedy Web Compiler)&lt;/em&gt;, which we’ll also mention later. And the author of webpack has been busy working with the creators of Next.js to produce &lt;em&gt;Turbopack&lt;/em&gt;, which they bill as “The Rust-powered successor to Webpack”. It aims to provide an even better, faster development experience than Vite.&lt;/p&gt;

&lt;p&gt;Finally, a couple of very new tools are trying to revolutionise front-end tooling with an all-in-one approach, for a more convenient development experience. &lt;em&gt;Bun&lt;/em&gt; is designed as a faster replacement for Node.js and npm, but also comes with a transpiler (I’ll explain that later), a test runner, and a bundler which they have measured as &lt;em&gt;even faster&lt;/em&gt; than esbuild. A project called ‘Rome’ had similar ideas - unfortunately the startup behind it closed in August 2023, but it has been forked as &lt;em&gt;Biome&lt;/em&gt;. It doesn’t replace Node or npm, but plans to do all of the rest, along with formatting and linting (only the formatter and linter are released at the time of writing). It will be interesting to see if this approach takes off in the JS community once the tools mature.&lt;/p&gt;

&lt;p&gt;Ultimately, what build tool you end up using very much depends on the needs of your project, such as its size and complexity, and what front-end library/framework (React, Vue, etc.) and rendering framework (Next.js, Astro etc.) you use, if any. There are initialisers for these frameworks that are built on top of a specific build tool - for example, the &lt;code&gt;create-vue&lt;/code&gt; initialiser is built on Vite, since they have the same author.&lt;/p&gt;

&lt;p&gt;In this article I’ll demonstrate Parcel, but only because it lends itself well to simple examples, so don’t be unduly influenced by this choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Command line JS 👨‍💻
&lt;/h2&gt;

&lt;p&gt;Before we get to discussing their features, it’s worth taking a minute to understand how build tools run with npm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executable JS files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most of the modules we install from npm are imported into our code to eventually be executed (run) in the browser. However, authors of Node.js files can also write their code to be executed on the command line. These are often referred to as &lt;em&gt;executables&lt;/em&gt; (though strictly speaking, only code the computer can run directly without an interpreter meets this definition). By tradition in Unix-like systems (e.g. Linux, mac), executable files are held in a folder called &lt;code&gt;bin&lt;/code&gt; (for &lt;em&gt;binaries&lt;/em&gt;, not ‘bin’!).&lt;/p&gt;

&lt;p&gt;It is possible to run Node.js executables using the command &lt;code&gt;node&lt;/code&gt; in the terminal followed by the file name. This tells whatever shell program you use such as Bash, Zsh (mac) or PowerShell (Windows), to run the code via Node.js rather than trying to interpret it. However, in any Unix-like system the file author can give the file executable permission, then add an &lt;em&gt;interpreter directive&lt;/em&gt; to make the shell run it in the program specified (Node.js in this case): &lt;code&gt;#!/usr/bin/env node&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So let’s say I have installed Parcel and I want to run their command line code. In the ‘parcel’ folder in node_modules I can see they’ve added it in &lt;code&gt;lib/bin.js&lt;/code&gt; with an interpreter directive. This means I can actually run this code with &lt;code&gt;node_modules/parcel/lib/bin.js&lt;/code&gt; in my project’s directory in a Bash terminal. However, JS devs are lazy folks and we don’t like writing things like paths to files.&lt;/p&gt;

&lt;p&gt;npm makes this easier. Firstly, it creates a single folder at the top of node_modules called &lt;code&gt;.bin&lt;/code&gt; where it stores &lt;em&gt;symbolic links&lt;/em&gt; (sort of like a shortcut) to the actual files. The author must list their executable JS files with names in the “bin” property of their &lt;code&gt;package.json&lt;/code&gt;, or if it’s a single file the name is taken by default from the &lt;code&gt;package.json&lt;/code&gt; “name” property - ‘parcel’ in this case. This means our command can just be &lt;code&gt;node_modules/.bin/parcel&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course this is still too much for JS devs! npm actually provides even more of a shortcut with &lt;em&gt;npx&lt;/em&gt; (mentioned in the previous article). npx already knows the &lt;code&gt;node_modules/.bin&lt;/code&gt; path, so we can just write &lt;code&gt;npx parcel&lt;/code&gt;. I’ve taken you the scenic route to get here, but I think it’s nice to understand what’s really going on under the hood. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executing non-JS files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One more thing. I mentioned that some bundlers contain code written in languages like Rust or Go, yet they’re available via npm to run in Node.js. What’s the deal? &lt;/p&gt;

&lt;p&gt;Well, we are not actually running the Rust or Go code directly. That has already been &lt;em&gt;compiled&lt;/em&gt; into various different binaries suitable for execution in particular operating systems. Often these are published to npm separately as &lt;em&gt;scoped packages&lt;/em&gt; (each npm user or organisation has a scope starting with &lt;code&gt;@&lt;/code&gt; and can publish related packages under it, e.g. &lt;code&gt;@esbuild/linux-x64&lt;/code&gt;), and then added as &lt;code&gt;optionalDependencies&lt;/code&gt; in the &lt;code&gt;package.json&lt;/code&gt; of the main project, to be installed if possible in the user’s OS.&lt;/p&gt;

&lt;p&gt;These binaries can then be imported and used directly in Node.js code because Node.js exposes an API for running natively executable files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bundling code 🧺
&lt;/h2&gt;

&lt;p&gt;Ok, now let’s look at how we use a build tool for bundling. &lt;/p&gt;

&lt;p&gt;Bundling is essentially performing an action on multiple source files in order to output one (or more, if specified) file(s). The source files are left intact for you to continue working on, and the output can be run in the target environment (the browser, in our case).&lt;/p&gt;

&lt;p&gt;To bundle your code, you need to specify an input file that is not imported by other files, from which the bundler will start tracing the chain of imported files. You may also need to give the name of the output file to be created, and the path to the folder where you want it to live.&lt;/p&gt;

&lt;p&gt;Your input file may be called something like &lt;code&gt;index.js&lt;/code&gt;. The output folder is often called &lt;code&gt;dist&lt;/code&gt; (for ‘distribution’), and we typically create a separate folder named &lt;code&gt;src&lt;/code&gt; to house the source files. How you set up the HTML file(s) depends on the build tool and configuration, but it could for example live in &lt;code&gt;src&lt;/code&gt; and contain a script tag pointing to &lt;code&gt;index.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can then ask the bundler to bundle the files. With Parcel, a basic example looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx parcel src/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We passed the input file as an &lt;em&gt;argument&lt;/em&gt; to the parcel command. The output folder was assumed to be &lt;code&gt;dist&lt;/code&gt;, which Parcel creates for us and adds the bundled files into, including a copy of my HTML file with a &lt;code&gt;script&lt;/code&gt; tag pointing to the outputted JS file. If we want to change the name or location of the output folder, in Parcel we can use the command line flag &lt;code&gt;--dist-dir&lt;/code&gt;, or “targets” in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we have an HTML file which is ready to be served to the browser. All the build tools I’ve mentioned have a simple command like this to bundle JS files. But we can use something called &lt;em&gt;npm scripts&lt;/em&gt; to make this even simpler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm scripts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;npm scripts allow us to specify a shorthand for running commands in the terminal, similar to aliases. These shorthands can be anything you like, but some of them are considered standard, which is nice because you can run the same command for basic tasks no matter what project you’re working on.&lt;/p&gt;

&lt;p&gt;The scripts are specified in the “scripts” property of the package.json file, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parcel src/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like with &lt;code&gt;npx&lt;/code&gt;, we don’t need to specify the path to the &lt;code&gt;.bin&lt;/code&gt; folder here. To execute the command, you call &lt;code&gt;npm run&lt;/code&gt; (an alias for &lt;code&gt;npm run-script&lt;/code&gt;) followed by the name you assigned the script. However, the “start” script is so commonly used that npm have aliased it to just &lt;code&gt;npm start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes it is inconvenient or not possible to specify all options to the build tool on the command line, for example when using plugins. In this case we can use a configuration file, written with a name and format the build tool is expecting. Because these files will be run in Node.js, they are often written using CommonJS syntax. However, since 2020 Node.js has had built-in support for ESM syntax - one way to enable it is adding the &lt;code&gt;.mjs&lt;/code&gt; extension to your files rather than &lt;code&gt;.js&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We won’t use a config file in this article because our examples are quite simple, but if you need one the build tool docs should explain everything you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bundling CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ever since webpack came along, build tools (or their plugins) have been able to bundle CSS files too. Since every linked CSS file requires a network request, bundling them in advance helps the page load quicker. It also makes it easier to locate your styles next to the JS module that uses them, if you prefer this approach. Rather than having to add a &lt;code&gt;link&lt;/code&gt; tag with a path to the file, you can specify an import from the same directory in the JS file, using ESM import syntax. For example, in &lt;code&gt;index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bundling CSS requires a specific loader, which may be a plugin, or built into the bundler. Typically a bundled CSS file is produced and linked in the outputted HTML via a &lt;code&gt;link&lt;/code&gt; tag. In Parcel this works without any extra config. A different approach is to add all the CSS rules to the document’s internal stylesheet (the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag in the HTML file’s &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, which has the same specificity as an external stylesheet), meaning no network requests are needed to load the CSS. webpack’s style loader uses this approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading assets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Other assets such as images can also be loaded by build tools from JavaScript. There are a few ways to import these assets, but the simplest syntax looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./image.jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The import which I’ve called ‘image’ here is a URL which can be assigned to an &lt;code&gt;img&lt;/code&gt; element’s &lt;code&gt;src&lt;/code&gt; attribute. The build tool’s relevant loader will handle getting the asset linked correctly in your output folder. Parcel, esbuild and webpack have loaders built in, though you need a little configuration in webpack and esbuild, and there is a plugin for Rolllup. &lt;/p&gt;

&lt;h3&gt;
  
  
  Bundling for development
&lt;/h3&gt;

&lt;p&gt;So now we know how to make a basic bundle, but we still need to see our work in the browser before this is useful. We could just open our HTML file in the browser, but that’s not very convenient. npm projects typically use a &lt;em&gt;server&lt;/em&gt;, even for local development. Some build tools have this built in, and for others you need a plugin package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using a development server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you serve files, you serve to a particular &lt;em&gt;host&lt;/em&gt; (computer), which has a &lt;em&gt;hostname,&lt;/em&gt; such as the name of a website. When you tell your browser to get a file from that host, it translates that into the IP address of the computer where that file can be found.&lt;/p&gt;

&lt;p&gt;But it is also possible to serve files to the same computer you are serving from. In that case, the hostname is always &lt;em&gt;localhost.&lt;/em&gt; The computer reserves at least one specific IP address to do this, which in the IPv4 system is the address 127.0.0.1. (The 127 may seem a bit random, but it’s just half the maximum of an 8-bit block in binary). &lt;/p&gt;

&lt;p&gt;When we ask to go to localhost or 127.0.0.1, the computer knows it can skip the actual networking and instead use something called the loopback interface, so we don’t need to specify the HTTP protocol. But we do need to specify a &lt;em&gt;port&lt;/em&gt; so the browser knows which program to ask for the file.&lt;/p&gt;

&lt;p&gt;There are 16 bits free for port numbers, which is over 65,000 numbers, though some are reserved for particular things. A running instance of a program on the host machine that wants to access the network can use any port which is not reserved or currently being used. Port 3000 is the default port for Node.js apps, so you will often see this used by JS build tools. Other round numbers in the thousands are often used too. Another standard is 8080, based on the fact that the standard HTTP port is 80. The port number is added after a colon, e.g. localhost:3000.&lt;/p&gt;

&lt;p&gt;In Parcel, there is a built-in server which by default serves the code on localhost:1234 when you run the parcel command. You can also add the &lt;code&gt;--open&lt;/code&gt; flag at the end to get the server to open up that page in your browser. Then you will see the contents of your HTML file on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebuilding and reloading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Having the project served is one thing, but during development, we also want to make lots of changes to our source files and see the results reflected in the browser. A typical dev server can &lt;em&gt;watch&lt;/em&gt; development files and detect when a file is changed. When this happens, it can trigger a rebuild, so that if you refresh your browser page, the new code is served.&lt;/p&gt;

&lt;p&gt;This is all well and good, but JS devs are impatient as well as lazy. We scoff at having to &lt;em&gt;refresh&lt;/em&gt; the browser page when we make a code change! &lt;/p&gt;

&lt;p&gt;One solution is to get the build tool to reload the page for you, often called &lt;em&gt;live reloading.&lt;/em&gt; In esbuild, if you’ve enabled file watching you can add some JS that listens to server events using the browser’s EventSource API and calls the browser’s reload function when a change event occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/esbuild&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“Still not good enough!”, the JS devs cry. &lt;/p&gt;

&lt;p&gt;In fairness though, if your project contains a lot of JS and other assets that need loaded up-front, a page reload can be quite slow, which hurts productivity. So modern JS build tools (or their plugins) often have functionality to reload only part of the page content during development without a page refresh, which is referred to as &lt;em&gt;hot reloading&lt;/em&gt; or &lt;em&gt;Hot Module Replacement (HMR)&lt;/em&gt;. This basically involves the build tool sending updated chunks of content to the browser to replace the outdated parts only.&lt;/p&gt;

&lt;p&gt;The new tools on the block focus heavily on the HMR experience. Vite figured out it would be faster in development mode to actually serve native ES Modules to the browser (whereas in production it uses Rollup to bundle the files). When there is a code change it serves new modules, but lets the browser handle caching everything that hasn’t changed. Turbopack, in contrast, does not use ESM but claims to have achieved a faster refresh speed than Vite by leveraging WebSockets (a fast connection between browser and server).&lt;/p&gt;

&lt;p&gt;esbuild, however, has gone in the opposite direction and doesn’t support HMR for JavaScript. In their words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;… JavaScript is stateful so you cannot transparently implement hot-reloading for JavaScript like you can for CSS. Some other development servers implement hot-reloading for JavaScript anyway, but it requires additional APIs, sometimes requires framework-specific hacks, and sometimes introduces transient state-related bugs during an editing session.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Bundling for production
&lt;/h3&gt;

&lt;p&gt;When we bundle for production, we will need a slightly different process. In Parcel, we can use the &lt;code&gt;parcel build&lt;/code&gt; command. We can add this command to an npm script called build, so my npm scripts now looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"parcel src/index.html --open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"parcel build src/index.html"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then to create my production bundle, I would run &lt;code&gt;npm run build&lt;/code&gt;. How and where this is run depends on your deployment process, which is outside the scope of this article. But it is important to have a separate production build so that the development-only features we’ve talked about are turned off.&lt;/p&gt;

&lt;p&gt;The packages you use also sometimes want to know if they are running in production mode, so they can remove development-friendly code like log messages. By convention this is done via an &lt;em&gt;environment variable&lt;/em&gt;, which is just a variable that is stored outside of the process (running instance of the program) and can be set by the user. In Node.js, environment variables are accessed via the global &lt;code&gt;process&lt;/code&gt; object, on an object called &lt;code&gt;env&lt;/code&gt;. The variable &lt;code&gt;NODE_ENV&lt;/code&gt; is used for toggling production mode.&lt;/p&gt;

&lt;p&gt;Handily, most build tools set this variable for you based on your configuration, so you don’t need to worry about it. For example, Parcel sets &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; to ‘production’ when the &lt;code&gt;parcel build&lt;/code&gt; command is used, and ‘development’ otherwise. You can always override the variable by setting it via the command line, or alternatively, any Node.js environment variables can be listed in a file called &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As well as turning off features, in production mode build tools can also apply optimisations to the bundling process for better performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tree shaking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tree shaking is a term popularised by Rollup which means removing unused imports from the outputted bundle. As described in the webpack docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can imagine your application as a tree. The source code and libraries you actually use represent the green, living leaves of the tree. Dead code represents the brown, dead leaves of the tree that are consumed by autumn. In order to get rid of the dead leaves, you have to shake the tree, causing them to fall.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tree shaking works best with ESM import statements, which as we mentioned last article are &lt;em&gt;static&lt;/em&gt; in nature, meaning you can know for sure what code will be imported without running it. So build tools usually tree shake unused imports so long as they are not CommonJS imports or being converted to that format (though Parcel can tree shake CommonJS).&lt;/p&gt;

&lt;p&gt;Note that we are referring only to unused &lt;em&gt;imports&lt;/em&gt;, not unused code in general. For example, if you import a package that exports a single class and you only use some of the methods, the whole package will still end up in your bundle. But many popular libraries split up their exports, so you can just import the parts you need. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code splitting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code splitting refers to any means of splitting up your code into smaller parts, known as chunks, in the interests of better performance.&lt;/p&gt;

&lt;p&gt;One natural way your code might be split is in a multi-page application with separate HTML and associated JS files. Build tools allow you to specify these files as separate &lt;em&gt;entry points,&lt;/em&gt; which results in separate bundles for each page, so the browser only loads the content it needs for each page. However, these pages may use some of the same code, e.g. third-party packages. There is no need for the browser to re-download that code if it already has it cached, which is why build tools enable splitting up a bundle further into chunks (separately loaded files) so parts of it can be shared between pages.&lt;/p&gt;

&lt;p&gt;Chunks can also be used in single-page applications, via ESM &lt;em&gt;dynamic imports&lt;/em&gt; in the form &lt;code&gt;import(moduleName)&lt;/code&gt;. Dynamic imports return a Promise that resolves when the module and its dependencies have loaded. These can be used inside conditions or callbacks to implement &lt;em&gt;lazy loading&lt;/em&gt; for modules, so they are only loaded if and when they are needed (e.g. see &lt;code&gt;React.lazy&lt;/code&gt; in React 18). The build tool then handles creating separate chunks for dynamically imported modules and any shared dependencies. As the name suggests, dynamic imports are &lt;em&gt;dynamic&lt;/em&gt; expressions, so they are not as easily compatible with tree-shaking (though again, Parcel supports it).&lt;/p&gt;

&lt;p&gt;Note that code splitting support differs across build tools. Parcel and Rollup do a lot automatically, but esbuild support is still in progress. webpack requires you to specify dependencies when splitting chunks for multiple entry points, but has automatic support for dynamic imports via its SplitChunksPlugin. SplitChunksPlugin also by default splits out any node modules code into a separate chunk (known as the ‘vendor chunk’). This is handy for example if you ship new application code but your dependencies haven’t changed, because the vendor chunk does not need re-downloaded if the user’s browser already has it cached. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content hashing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We just mentioned how the browser can cache our JS files so it doesn’t need to re-download them. This works great unless we &lt;em&gt;do&lt;/em&gt; actually need them re-downloaded because the content has changed. For this reason, build tools support &lt;em&gt;content hashing&lt;/em&gt;, either via configuration or by default. Hashing is the process of applying a function to some content that outputs a unique string, and if the content has not changed, the string will always be the same. In this case the outputted ‘hash’ string is added to the filename so the browser knows when the file has changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transforming code 🤖
&lt;/h2&gt;

&lt;p&gt;Now that we know how to create a basic bundle for development and production, let’s move on to understanding transformations. The high-level source code that we write can be transformed in a number of ways before it is run by the browser. This process is known as &lt;strong&gt;transpilation&lt;/strong&gt;, i.e. converting code to a different high-level form, as opposed to &lt;em&gt;compilation&lt;/em&gt;, which is converting high-level to very low-level code. &lt;/p&gt;

&lt;p&gt;We already know that bundling usually involves some conversion of ESM or CommonJS syntax. For example when we bundle for the browser, module syntax is stripped away and often replaced with plain functions that wrap each module.&lt;/p&gt;

&lt;p&gt;But there are additional transformations we can do for various reasons. Previously, task runners such as Gulp or Grunt were used for many of these operations, but using the bundler to do them keeps things simpler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transforming code for development
&lt;/h3&gt;

&lt;p&gt;Certain tools are used by developers to write code more productively, but need transpiled for the browser to run them. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS transforms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tools known as &lt;em&gt;CSS preprocessors&lt;/em&gt; allow you to write custom CSS syntax, then transpile it to regular CSS. The most popular one (as per the 2022 State of CSS survey) is called &lt;em&gt;Sass&lt;/em&gt;. Its syntax provides for CSS rule nesting and some programming concepts like variables and functions. How you transform the syntax into CSS depends on what bundler you use. Parcel automatically installs its own transformer for you - other bundlers require adding plugins and in some cases also installing the sass package from npm.&lt;/p&gt;

&lt;p&gt;Another tool you should know about is &lt;em&gt;PostCSS&lt;/em&gt;. PostCSS is not a preprocessor or even a tool you use directly. It provides some core logic that parses non-standard CSS and can run a chain of plugins to do the transformations. There are hundreds of these plugins such as autoprefixer, which automatically adds vendor prefixes to CSS selectors where necessary, and preset-env, which can transpile modern CSS for older browsers. There are also plugins for pretty much all Sass functionality, so it’s a viable and more flexible alternative. You can use PostCSS plugins by configuring them for your bundler as required. &lt;/p&gt;

&lt;p&gt;Finally, it’s worth mentioning &lt;em&gt;Lightning CSS&lt;/em&gt;, a fast CSS transform tool written in Rust by the author of Parcel. It’s built into Parcel and also available as a standalone tool. It implements the functionality of some of the most popular PostCSS plugins and can also support the draft CSS specification on nesting if you add the config for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Templating languages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most devs writing for the browser use some kind of library or framework to make the job of writing JS for a system devised in the 90’s a bit more manageable. These provide some form of templating to make it easier to display different bits of UI conditionally with JS. However, this special syntax needs transformed to plain JavaScript for the browser.&lt;/p&gt;

&lt;p&gt;The most popular of these languages is probably &lt;em&gt;JSX&lt;/em&gt;, the lovechild of JavaScript and HTML which was created for React and can be optionally used in Vue. This is traditionally transpiled by a tool called &lt;em&gt;Babel,&lt;/em&gt; which can translate the JSX markup into JavaScript functions to create UI elements. &lt;/p&gt;

&lt;p&gt;However, there are now alternatives to Babel. SWC is a tool written in Rust to achieve tens of times faster performance than Babel, and is built into Parcel and Turbopack. esbuild comes with its own JSX transpilation, which is also used by Vite. And the Typescript compiler, which we’ll cover in a second, can also transform JSX to React code. With webpack and Rollup, you can specify your transpiling plugin. All these build tools also support many other templating languages.&lt;/p&gt;

&lt;p&gt;Some frameworks come with their own compiler, which just needs configured with the build tool. For example, Svelte uses its own templating language which it compiles to JavaScript, and Solid.js also uses this approach, but with JSX syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TypeScript is an extension to JavaScript with types. VSCode comes with Typescript, so if you write Typescript in a &lt;code&gt;.ts&lt;/code&gt; file in VSCode, it understands the syntax, shows type information and errors on hover in the file, and lists errors and warnings from all files in the ‘Problems’ tab. This is a fairly convenient way to use Typescript in your project. However, because the browser doesn’t understand Typescript, it needs to be transpiled to JavaScript.&lt;/p&gt;

&lt;p&gt;Many bundlers now come with Typescript transpilation built in, either using SWC (Parcel, Turbopack) or esbuild (esbuild, Vite), so you should be able to get started straight away. There is also an official Typescript compiler called &lt;code&gt;tsc&lt;/code&gt;. This is handy when you want the type errors to stop your build from completing, rather than causing an error in the browser console. This is most important for production builds, but can be handy in development too. You can run it from the command line any time you like, or add it to a npm script, e.g. run tsc and then (&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator) run parcel. We use the &lt;code&gt;--noEmit&lt;/code&gt; flag so that tsc only does type checking, not emitting the transpiled JS files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc --noEmit &amp;amp;&amp;amp; parcel index.html"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Getting type errors to block the build on an ongoing basis as you edit files is more complicated because &lt;code&gt;tsc&lt;/code&gt; has to run in the background, though Parcel has an experimental plugin for this which you can try. It can also be achieved by bundlers that run &lt;code&gt;tsc&lt;/code&gt; via plugins such as webpack.&lt;/p&gt;

&lt;p&gt;Bear in mind that &lt;code&gt;tsc&lt;/code&gt; uses configuration defined in a &lt;code&gt;tsconfig.json&lt;/code&gt; file, which is documented on the Typescript website. Explaining this config is outside the scope of this article, but you will need to configure at least a few properties here if you want to use &lt;code&gt;tsc&lt;/code&gt; directly. &lt;/p&gt;

&lt;h3&gt;
  
  
  Transforming code for production
&lt;/h3&gt;

&lt;p&gt;Serving code in a production environment brings its own challenges which further code transformations can help with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During development you probably use the latest version of your preferred browser, but your users may be using an older browser in which newer JavaScript syntax doesn’t work. To tackle this problem, build tools can transform the newer code into the equivalent older syntax, via any of the transpilers mentioned above - Babel, SWC, esbuild or tsc.&lt;/p&gt;

&lt;p&gt;To do this, you need to specify what level of compatibility you need. Many transpilers allow you to specify a range of browsers, from which they figure out which syntax needs transformed. This is done via a popular npm package called &lt;em&gt;browserslist,&lt;/em&gt; which accepts a plain English syntax for specifying a range of browser versions and returns the full list. This configuration can be added in a “browserslist” property in package.json, or a &lt;code&gt;.browserslistrc&lt;/code&gt; file (a filename ending in ‘rc’ is standard for a config file in any Unix-like system, and can contain whatever format the parser expects). You can see the configuration details on their &lt;a href="https://browsersl.ist/"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that tsc uses a different approach - you specify the lowest JS version you need to support in the “target” property of &lt;code&gt;tsconfig.json&lt;/code&gt;. esbuild’s transpiler (also used by Vite) also uses a “target” property which takes JS versions, but it does accept a list of browser versions as well, which can be generated by running browserslist separately if necessary.&lt;/p&gt;

&lt;p&gt;All of this is great for transforming newer syntax, such as the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing"&gt;nullish coalescing operator&lt;/a&gt;, for example, which can be fairly easily written in older JS. However, there is a separate problem of newer APIs, e.g. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"&gt;Promises&lt;/a&gt;, which have more complicated implementations inside the browser (typically in C++). Writing another implementation of an API to fill a gap in browser support is known as a &lt;em&gt;polyfill&lt;/em&gt; (a term coined back in 2009). Transpilers don’t take on the task of writing polyfills, but luckily there is an incredibly popular npm library called &lt;em&gt;core-js&lt;/em&gt; that does, though it’s mostly maintained, with much frustration, by just one guy in Russia (yup, welcome to the JS ecosystem!). &lt;/p&gt;

&lt;p&gt;core-js polyfills can be configured with Babel and SWC. They are not included as part of esbuild or Typescript, but you can import the polyfills you need directly from core-js as described in the core-js docs.&lt;/p&gt;

&lt;p&gt;Finally, it’s worth noting that adding extra syntax and polyfills makes your bundles larger, especially when supporting ES5, which is a bit of a waste in up-to-date browsers. One approach to tackle this is known as &lt;em&gt;differential serving/bundling&lt;/em&gt;. Two scripts are output - one with ES6 code, linked with &lt;code&gt;type=module&lt;/code&gt; in the &lt;code&gt;script&lt;/code&gt; tag, the other with ES5 code, with a &lt;code&gt;nomodule&lt;/code&gt; attribute in the script tag, which tells the browser to ignore it if it supports modules (an ES6 feature). This is built into Parcel and can be configured in some other bundlers such as webpack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Production is all about getting the code to the user as fast as possible, so the less code there is, the better. This also means as few characters as possible, why is why developers use &lt;em&gt;minification&lt;/em&gt; to remove any characters that are not necessary for the code to run. Whitespace and comments are removed, variable names are shortened to one character, and syntax may be rewritten in a more concise way (you can usually configure these operations). This can be used on CSS, HTML, SVG and other files as well as JS.&lt;/p&gt;

&lt;p&gt;The standard tool for minification is called &lt;em&gt;terser&lt;/em&gt;. This became the most popular tool over the older projects uglify-js and babel-minify which are no longer maintained. It’s used by webpack when you specify ‘production mode’, and there is a plugin for Rollup. However, by now you will probably not be surprised to hear that SWC and esbuild use their own, speedier minification process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope hoisting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There's one more little optimisation you might hear about. As mentioned earlier, bundlers need to maintain each module's scope to avoid naming conflicts once the code is all bundled together. In development mode, they create plain wrapping functions to achieve this, but for production, there is a newer approach called &lt;em&gt;scope hoisting&lt;/em&gt;. Any top-level variables are given unique names, which avoids the need for wrapper functions, so the code runs quicker. This is built in with Parcel and Rollup, and available for webpack via a plugin. &lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging code 🔧
&lt;/h2&gt;

&lt;p&gt;Bundling and transforming code has lots of benefits, but it does lead to an issue with debugging. You are probably familiar with debugging a JavaScript error in devtools by clicking on the link to the source file in the top-right of the error. However, when we bundle JS, the source is now one giant file which has probably been transformed in a number of ways from the original code, making debugging much more difficult.&lt;/p&gt;

&lt;p&gt;Luckily, there is a solution to this, called &lt;strong&gt;source maps&lt;/strong&gt;. These are files ending in &lt;code&gt;.map&lt;/code&gt; that are generated by the build tool, and they enable devtools to point you back to your original source file instead of the bundle. Unless you are writing your own library, you don’t need to worry about these maps too much aside from making sure they are generated, which is sometimes done by default (e.g. by Parcel), and sometimes requires a small amount of configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully these explanations have given you a much better understanding of various build tools and what they do. Let’s recap some key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modern build tools can handle both bundling and running various transformations on our code, and the needs of the development environment are very different from production.&lt;/li&gt;
&lt;li&gt;There are many tools to choose from, with different pros and cons, including speed of development experience, ease of use and flexibility. Always keep in mind the needs of your particular project rather than getting carried away with the latest trend.&lt;/li&gt;
&lt;li&gt;Build tools are complicated, but we are in an exciting era where they are also faster, more all-encompassing and perhaps easier to get started with than ever before.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I definitely haven’t covered all the ins and outs of build tools here, so if you want to know more about any of the tools I’ve mentioned, their documentation (listed below) is a good place to start. There are also plenty of discussions in blogs and social media about all these tools and users’ experiences and frustrations when it comes to the fine details.&lt;/p&gt;

&lt;p&gt;Read these if you wish, though your main focus should always just be achieving reasonable productivity for your work. After all, tools are just tools - it’s what we build with them that matters!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Footnote: yet more build tools?!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you looked at the State of JS 2022 survey, you’ll notice a couple of build tools I didn’t mention: Snowpack and WMR. As explained on &lt;a href="https://vitejs.dev/guide/comparisons.html"&gt;Vite’s comparisons page&lt;/a&gt;, Snowpack is no longer maintained, and WMR is geared towards Preact, so it’s a more niche solution. You may also be aware of &lt;em&gt;Deno&lt;/em&gt;, which is the follow-up runtime from the author of Node.js. It used to have a bundle option built in, but this was &lt;a href="https://github.com/denoland/deno/issues/11073"&gt;deprecated&lt;/a&gt; in favour of letting other tools handle bundling instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;p&gt;* = particularly recommended for further study&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;* &lt;a href="https://2022.stateofjs.com/en-US/libraries/build-tools/"&gt;State of JS 2022: Build Tools&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;* &lt;a href="https://parceljs.org/docs"&gt;Parcel docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webpack.js.org/concepts/"&gt;webpack docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rollupjs.org/"&gt;Rollup docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://esbuild.github.io/"&gt;esbuild docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://v2.vitejs.dev/guide/why.html"&gt;Vite docs - Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://turbo.build/pack/docs/why-turbopack"&gt;Turbopack docs - Why Turbopack?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bun.sh/docs"&gt;Bun docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://biomejs.dev/blog/annoucing-biome/"&gt;Announcing Biome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Executable"&gt;Executable - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.dev/en/learn/run-nodejs-scripts-from-the-command-line/"&gt;Run Node.js scripts from the command line - Node.js website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Interpreter_directive"&gt;Interpreter directive - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v9/configuring-npm/package-json"&gt;package.json - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v9/using-npm/scope"&gt;scope - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v9/commands/npm-run-script"&gt;run-script - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/dist/latest-v20.x/docs/api/esm.html#enabling"&gt;Enabling modules - Node.js docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Localhost"&gt;localhost - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"&gt;import() - MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/lazy"&gt;React.lazy - React docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://2022.stateofcss.com/en-US/other-tools/"&gt;State of CSS 2022: Other Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sass-lang.com/guide/"&gt;Sass Basics - Sass website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://postcss.org/docs/postcss-architecture"&gt;PostCSS Architecture - PostCSS website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lightningcss.dev/"&gt;LightningCSS website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://babeljs.io/docs/"&gt;Babel docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://swc.rs/"&gt;SWC docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.solidjs.com/guides/rendering"&gt;Rendering - SolidJS docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://svelte.dev/docs/svelte-compiler"&gt;Svelte compiler - Svelte docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/tsconfig"&gt;TsConfig Reference - TypeScript docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/browserslist"&gt;browserslist - npm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Configuration_file"&gt;Configuration file - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zloirock/core-js/blob/master/README.md#usage"&gt;core-js docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/terser/terser"&gt;terser - github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Understanding JS Build Tools (Part 1: Modules and Packages)</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Mon, 31 Jul 2023 11:37:58 +0000</pubDate>
      <link>https://forem.com/joshcarvel/understanding-js-build-tools-part-1-modules-and-packages-3i5o</link>
      <guid>https://forem.com/joshcarvel/understanding-js-build-tools-part-1-modules-and-packages-3i5o</guid>
      <description>&lt;h2&gt;
  
  
  Intro 🏗️
&lt;/h2&gt;

&lt;p&gt;When you learn front-end development for the first time, you learn a simple fact: to run JavaScript in the browser, you add a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in an HTML file. You can set the &lt;code&gt;src&lt;/code&gt; attribute to link to a JS file, or just write the JS inside the tag, and if you’re not using much JavaScript, you may not need to know much more than this to run it.&lt;/p&gt;

&lt;p&gt;But these days, web applications and sites tend to use a &lt;em&gt;lot&lt;/em&gt; of JavaScript. JS is gaining more and more responsibility in the browser, and on the server too. For this reason, we also have a &lt;em&gt;lot&lt;/em&gt; of techniques and tools to help us construct our JS projects. And that can mean a lot of wrestling with build tools you don’t fully understand, even if you’re an experienced dev.&lt;/p&gt;

&lt;p&gt;Of course, every layer of complexity or configuration is meant to improve either the developer or end user’s experience. But over time, it adds up to quite a heap of technical knowledge. And while we have tools and frameworks that can abstract away these details for you, it always pays to know what’s really going on, so you can take greater control of your projects.&lt;/p&gt;

&lt;p&gt;In this two-part article, I’ll help you do that. We will demystify the key methods and tools commonly used to set up modern JS projects, examining what they do, why they exist, and their pros and cons. By the end, you should be able to make intelligent decisions about build tools and feel confident in tackling their configuration.&lt;/p&gt;

&lt;p&gt;In Part 1, we’ll ground ourselves with a solid understanding of JavaScript modules and packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic understanding of HTML, JavaScript and JSON&lt;/li&gt;
&lt;li&gt;Basic understanding of Git&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Modules 🗃️
&lt;/h2&gt;

&lt;p&gt;Modules are at the heart of modern front-end development. This is because the JavaScript for our project is likely to be spread across different files. Even if we wrote all the JS ourselves, a single large file is not very nice to manage. And we definitely need other files if we’re using code other people wrote.&lt;/p&gt;

&lt;p&gt;As a starting point, we could split up our JS files into separate scripts. Perhaps one for each page of the website or application, for example. But when you add multiple &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in HTML, by default the JavaScript runs as if it was still all in a single file. If I declare a function or a variable &lt;em&gt;globally&lt;/em&gt; (not inside a function), I can use it later on, even in a different file. &lt;/p&gt;

&lt;p&gt;So if I have two scripts like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./script1.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./script2.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a function like this in script1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can use the function in script2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// the "hi" alert shows in the browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This behaviour probably seemed OK back when JS was a novelty that could add a sprinkling of interactivity to mostly ‘static’ websites. But for today’s complex sites and applications, it’s far from ideal.&lt;/p&gt;

&lt;p&gt;Firstly, we have to manage dependency order. Because script2 depends on a function from script1, the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag for script2 must come &lt;em&gt;after&lt;/em&gt; script1 in the HTML. The scripts are run in order, and you can't use a function or variable before it is defined. This may not seem like a big deal here, but the problem grows with the amount of scripts you have. Keeping track of what script needs to go where is manual work that we don’t want to do.&lt;/p&gt;

&lt;p&gt;Secondly, the relationships between parts of our code are implicit, which can break our code in unexpected ways. If there is another &lt;code&gt;sayHi&lt;/code&gt; function somewhere after script1, and I call it later expecting to get the script1 version, actually it will have been overwritten by the other implementation. This happens for function declarations and variables defined with &lt;code&gt;var&lt;/code&gt;. It’s even worse for any variables (including function expressions) defined with &lt;code&gt;const&lt;/code&gt; or &lt;code&gt;let&lt;/code&gt; - these cause an error if another already exists with the same name. For code that uses a lot of libraries and frameworks, this is simply unworkable.&lt;/p&gt;

&lt;p&gt;Finally, global variables and functions create a security issue. Anyone running your code could run a script to access your code’s inner workings and even change what it does.&lt;/p&gt;

&lt;p&gt;So how do we deal with this? The answer is modules. But before proper module systems were used in JavaScript, there was a way to reduce the issues of global scope a little, sometimes referred to as the ‘module pattern’.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 'module pattern'
&lt;/h3&gt;

&lt;p&gt;Before modules, library authors would wrap their code in a single function, so the inner workings were not in global scope and couldn't conflict with anything. Inside that function, they would add all of their library’s public API to a single object (e.g. the &lt;code&gt;$&lt;/code&gt; object in the famous example of jQuery), and add it to the window object in order to make it globally accessible. Then finally they would call the wrapping function to make it work.&lt;/p&gt;

&lt;p&gt;The catch here is that the name of your wrapping function would still end up on the global scope. This problem was sidestepped with an obscure technique. We can define functions without names in JavaScript if they are part of an &lt;em&gt;expression&lt;/em&gt; (a line of code that resolves to a value). Usually expressions are assigned to a variable, but they don’t have to be - just writing a value such as &lt;code&gt;3&lt;/code&gt; is a perfectly valid line of JavaScript. &lt;/p&gt;

&lt;p&gt;However, a function not assigned to a variable is treated as a function declaration by the JavaScript compiler, so it will expect a function name. Putting the expression inside parentheses convinces the compiler it’s not a function declaration. We then need to call the function, and since we can't do it later (there’s no name to reference), we have to do it immediately. Hence we get this weird looking construction called an &lt;em&gt;immediately invoked function expression&lt;/em&gt; (IIFE):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;library&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="c1"&gt;// my library code...&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;library&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;library&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern was very widely used in JavaScript code, but definitely wasn’t ideal. Each ‘module’ still exposes a public object to &lt;em&gt;all&lt;/em&gt; other scripts, and we still have to manage the dependency order of scripts.&lt;/p&gt;

&lt;p&gt;So let’s look at how a module system can solve these problems for us. &lt;/p&gt;

&lt;h3&gt;
  
  
  ECMAScript Modules (ESM)
&lt;/h3&gt;

&lt;p&gt;There is a module syntax described in the ECMAScript specification (which defines JavaScript). It uses the keywords &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt; to link dependencies.&lt;/p&gt;

&lt;p&gt;For example, in script1 I could have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in script2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./script1.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// the "hi" alert shows in the browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can immediately see how much nicer this is - the relationships between different files are now explicitly defined. And the code inside each module is scoped to the module, &lt;em&gt;not&lt;/em&gt; globally scoped. So &lt;code&gt;sayHi&lt;/code&gt; can only be used where it is imported. If I don't import it, I get an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught ReferenceError: sayHi is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though I could have a different definition of &lt;code&gt;sayHi&lt;/code&gt; if I wanted, and both would work fine in their respective files. If I both import &lt;code&gt;sayHi&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; define a new version with the same name, I will get a (different) error when running the program, but at least the conflict of names is obvious in the file, not implicit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./script1.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught SyntaxError: Identifier 'sayHi' has already been declared&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One way to avoid naming conflicts is using the &lt;em&gt;module object&lt;/em&gt; syntax, which adds any exports from the imported file to an object with whatever name you assign it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Script1&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./script1.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Script1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// the "hi" alert shows in the browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Modules in the Browser
&lt;/h3&gt;

&lt;p&gt;Now comes the complicated bit. ESM has become the standard for modern web applications, &lt;em&gt;but&lt;/em&gt; there is a bit of history.&lt;/p&gt;

&lt;p&gt;Firstly, this system was only added to the ECMAScript specification in the 2015 release commonly referred to as ES6 (the 6th release). Before this, browsers simply did not understand ESM syntax or have the functionality to wrap up scripts into isolated modules.&lt;/p&gt;

&lt;p&gt;The first JS module system was actually created for running JavaScript &lt;em&gt;outside&lt;/em&gt; the browser, by the CommonJS project in 2009. It was then implemented in Node.js, the popular JS runtime environment.&lt;/p&gt;

&lt;p&gt;CommonJS modules use a different syntax to ESM. For example, here is a named export in script1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sayHi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here’s the import in script2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sayHi&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./script1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// "hi" is logged to the console&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This system made it easy for authors of server-side and command-line JS projects to split up their code and use other people’s modules. But there was an obstacle to implementing it in the browser.&lt;/p&gt;

&lt;p&gt;In Node.js, a JS file can be located on the machine and loaded immediately, so the code can run &lt;em&gt;synchronously&lt;/em&gt; - line by line. The browser environment is different. HTML was not designed with modules in mind. You can’t just hand the browser a bunch of modules and get it to run them in the right order. You have to specify individual script tags, and each one is a network request that takes time to complete. So unless we want to block the rendering of the page while we wait for each script, that makes the process &lt;em&gt;asynchronous.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Thus began the tradition of using tools to transform JavaScript modules into code the browser can run correctly. Early approaches to this transformed the code at the time of execution. There was a popular specification called &lt;em&gt;Asynchronous Module Definition (AMD),&lt;/em&gt; where your scripts defined a function which wrapped the code to be executed and listed the dependencies required, but did not call that function. At runtime, a third-party library known as a &lt;em&gt;script loader&lt;/em&gt; retrieved the script elements from the DOM, sorted out the required order and added the module code into the DOM dynamically.&lt;/p&gt;

&lt;p&gt;Other libraries were available as command-line build tools. These compiled the CommonJS code &lt;em&gt;before&lt;/em&gt; it was delivered to the browser. A popular tool called Browserify was created to handled the dependencies between modules and &lt;em&gt;bundle&lt;/em&gt; all the code inside a single script tag. It was later overtaken by webpack and other bundlers that could handle ESM syntax and provide other features we’ll talk about in the next article.&lt;/p&gt;

&lt;p&gt;Unfortunately, before ESM there was no consensus on the best module approach, so library authors needed their code to work for users using &lt;em&gt;either&lt;/em&gt; CommonJS or AMD. This led to &lt;em&gt;Universal Module Definition (UMD),&lt;/em&gt; which basically took authors back to using an IIFE, then adding code to export the module in whatever way was being used at runtime.&lt;/p&gt;

&lt;p&gt;You won’t need to use these approaches in your projects, but you will hear them mentioned in bundler documentation. The bundler needs to handle different types of exports and imports, because many popular libraries are still not exported using ESM (for example, React still exports CommonJS modules). And when we bundle for the browser, we usually output our code in an IIFE so it can run in older browsers, while still being isolated from any other JS that may be running on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Default exports&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another legacy of previous module systems is that exporting a single object containing all the library’s functionality was very common. ESM has a syntax that allows for this called &lt;em&gt;default exports&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;For example, let’s say I have a file called MyLibrary.js, and all I want to export from it is a class called &lt;code&gt;MyLibrary&lt;/code&gt;. If I export it with &lt;code&gt;export default&lt;/code&gt;, it can then be imported without curly brackets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MyLibrary&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./MyLibrary.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To bundle or not to bundle?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ok, we’re done with the history lesson and we want to use ESM syntax. But we still have a shoot-out between bundling the modules before they hit the browser, and just using the browser implementation. If you want to use &lt;code&gt;import&lt;/code&gt; statements without bundling, the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag for each module must have its &lt;code&gt;type&lt;/code&gt; attribute set to “module”. With our example scripts that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./script1.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./script2.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the browser reads these files, it figures out the dependencies before any of the code is executed, so we don’t have to worry about the order. If script1 imports something from script2, that tells the browser to execute script2 first, even though it comes later in the HTML.&lt;/p&gt;

&lt;p&gt;Note that this makes the imports &lt;em&gt;static -&lt;/em&gt; they’re not allowed to change during execution. So you can't use an &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;export&lt;/code&gt; statement inside a function or condition - it must be at the 'top level'. (There is an alternative called ‘dynamic imports’ however, which we’ll cover in Part 2).&lt;/p&gt;

&lt;p&gt;So now this exists in the browser, why bother using build tools instead? Well, there are a number of reasons why bundling JavaScript has become so popular. One is that it cuts down on network requests - why make the browser request multiple files when we can send just one? Another is that build tools can handle other useful operations before outputting our code, which we’ll cover in Part 2.&lt;/p&gt;

&lt;p&gt;But perhaps the biggest reason relates to how we use other people’s code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharing code 🎁
&lt;/h2&gt;

&lt;p&gt;We often want to use other people's libraries and frameworks, known as &lt;em&gt;dependencies&lt;/em&gt;, in our JS. What's the best way to do this?&lt;/p&gt;

&lt;p&gt;You &lt;em&gt;could&lt;/em&gt; go to the website or GitHub repository of the library you want to use and download the code, then add it to your project. But that’s slow, and you would have to also download all of the libraries that it depends on. Since JS projects these days have so many dependencies, that’s not really feasible. And this is just for one &lt;em&gt;version&lt;/em&gt; of the library, never mind dealing with updates.&lt;/p&gt;

&lt;p&gt;A slightly more common approach is linking in a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag to the URL of a server that the library code (and its dependencies) is stored on. To do this, the author must have first publicised this link and the server must allow &lt;em&gt;cross-origin requests&lt;/em&gt; (requests coming from other URLs). Additionally, in order for the code to get to the browser quickly, they will most likely use a &lt;strong&gt;content delivery network (CDN).&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CDN Links
&lt;/h3&gt;

&lt;p&gt;A CDN is a network of servers across the world. Companies such as Cloudflare, Akamai, Amazon, Google, Microsoft and many others provide these networks, which code authors pay to handle serving their resource, e.g. a website, application or library. &lt;/p&gt;

&lt;p&gt;The author usually puts their code on their own server (known as the &lt;em&gt;origin server&lt;/em&gt;), but either sets up a redirect or alters their urls to point to the CDN instead. The CDN servers pull that resource from the origin and cache it so wherever the user is, there should be a copy nearby which can reach them quickly. Periodically, the CDN servers request the resource from the origin server to ensure it is up-to-date, or the author can manually invalidate the cache.&lt;/p&gt;

&lt;p&gt;The advantage of using a library via a CDN is that you don't have to download the code or its dependencies yourself, and it's generally fast and reliable. Plus it can be better for the user, because since multiple sites can access a library from the same CDN, the user’s browser might already have cached the resource you’re linking to, in which case it doesn’t need to fetch it again over the network. So why not use CDN links for everything? &lt;/p&gt;

&lt;p&gt;Firstly, there are some small drawbacks that might be an issue, such as not being able to work offline or not having control of serving the resources needed for your project. Another simple one is that there might not be a CDN link available for the library you want to use.&lt;/p&gt;

&lt;p&gt;But there are bigger reasons too:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Admin.&lt;/em&gt; During development, you need to add all the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in the right place. Then as time goes on, you need to manually manage what version of the library you need when third party packages are updated.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Performance.&lt;/em&gt; This is the same problem we mentioned earlier - the browser has to make a separate request for each &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag (unless the resource is in the browser cache), which will slow down load times in production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a very small project, these downsides might be no problem. But for everything else, this is why &lt;em&gt;package managers&lt;/em&gt; are so popular. Package managers provide a system for managing dependencies. All the code is stored on the developer's computer, so the application can be developed offline if necessary. And you can use a bundler to output only one &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag (or however many you prefer).&lt;/p&gt;

&lt;p&gt;The downside of packages? They come from the Node.js world. You have to run Node.js on your computer, and a bundler to join all the modules together. This can be a hurdle for junior developers, and adds some complexity to getting started with JS projects. But for most JS devs this isn’t a big deal - we’ve accepted the inconvenience of setting up Node and a bundler config every once in a while, in return for the benefits it provides.&lt;/p&gt;

&lt;p&gt;It does mean, however, that native ESM in the browser was somewhat dead on arrival in 2015. It has its use cases, but people were already used to using packages and a bundler, and they had lots of reasons to stick with that.&lt;/p&gt;

&lt;p&gt;So let’s dive into how packages work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Packages
&lt;/h3&gt;

&lt;p&gt;A package is a library of code together with information about the code, such as the version number. A package manager is the tool that lets you download, manage, and if necessary create those packages. It has a command-line interface which communicates with the &lt;em&gt;registry&lt;/em&gt;, which is the database of all the packages that have been published by users. These aren't all public (access can be scoped to a particular organisation, for example), but many are.&lt;/p&gt;

&lt;p&gt;We’ll be looking at the most popular package manager for JS, &lt;em&gt;npm&lt;/em&gt;. In the early years of npm, there were some issues that led some developers at Facebook and elsewhere to create &lt;em&gt;yarn&lt;/em&gt;, a similar alternative. However, npm is generally considered to have caught up with the main yarn improvements. There is also &lt;em&gt;pnpm&lt;/em&gt;, which offers some speed and disk space improvements, but is less widely used. As a beginner, you should get used to npm for the foreseeable, since the others are similar to use anyway.&lt;/p&gt;

&lt;p&gt;To use npm, you just need to download Node.js from the Node.js website - npm is included with it because it’s so central to JS development these days. You can find the list of npm packages on the &lt;a href="https://www.npmjs.com/"&gt;npm website&lt;/a&gt;. To install a package, navigate to your project’s directory and run &lt;code&gt;npm install&lt;/code&gt; followed by the package name, e.g. &lt;code&gt;npm install react&lt;/code&gt;. There are built-in aliases (names for the same command) such as &lt;code&gt;npm i&lt;/code&gt;, which you can use if your prefer. If you need to uninstall a package, you can use &lt;code&gt;npm uninstall&lt;/code&gt;, which also has aliases such as &lt;code&gt;npm remove&lt;/code&gt; or &lt;code&gt;npm r&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The install command downloads a package from the registry. The installation is &lt;em&gt;local&lt;/em&gt; by default - you can only use the package in the directory you installed it in. This is the standard approach nowadays and is useful when you need to use different versions of a package for different projects. However, you can install a package globally if you need to, using the global &lt;em&gt;flag&lt;/em&gt; (option) &lt;code&gt;-g&lt;/code&gt;, e.g. &lt;code&gt;npm install -g react&lt;/code&gt;. Then it will be installed somewhere accessible everywhere (the exact location depends on the operating system).&lt;/p&gt;

&lt;p&gt;Packages are downloaded to a folder npm creates in your project called &lt;em&gt;node_modules,&lt;/em&gt; with a subfolder for each package. Most packages in turn have their own dependencies (&lt;em&gt;sub-dependencies&lt;/em&gt;), which are &lt;em&gt;also&lt;/em&gt; installed to your machine in the node_modules folder. This means the node_modules folder gets &lt;em&gt;very&lt;/em&gt; big very quickly! You &lt;em&gt;definitely&lt;/em&gt; don't want to commit this large folder into version control, so add the node_modules folder to your &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security and npm&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Please note that anyone can upload code to npm, and it relies on user reports to take down malicious code. In particular there is a practice called &lt;em&gt;typosquatting&lt;/em&gt;, where malicious code is uploaded with a slightly different name from a popular npm package so users might install it by accident. So be careful what you install, and check the package information on the npm website, including the ‘weekly downloads’ figure, to determine if a package seems legitimate and reliable. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using a package&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you have installed a package, you can import it in any JS file. You might expect you need to specify the path to the folder in node_modules, but luckily bundlers allow &lt;em&gt;bare specifiers,&lt;/em&gt; for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we do this, the bundler (or a plugin) knows to look for the dependency in node_modules and import it from there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;package.json&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you install a package, an entry is added to a file called &lt;code&gt;package.json&lt;/code&gt;, which npm creates for you if you haven’t created it already. This lists your dependencies in the &lt;code&gt;dependencies&lt;/code&gt; property, and the file &lt;em&gt;should&lt;/em&gt; be committed to version control. That way, when someone else clones your project to work on it, they can just run &lt;code&gt;npm install&lt;/code&gt; and all the dependencies listed in &lt;code&gt;package.json&lt;/code&gt; will be installed for them.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;package.json&lt;/code&gt; is also used by package authors to specify information about their package. This includes the package name, description, version number, and &lt;code&gt;devDependencies&lt;/code&gt;, which is dependencies they used to create the package, but the package users don’t need installed. There is also &lt;code&gt;peerDependencies&lt;/code&gt;, which should be specified by plugin authors who are adding functionality to another package without using that package directly.&lt;/p&gt;

&lt;p&gt;You will often see package users installing packages that aren’t used in the application code, such as testing libraries, with the &lt;code&gt;--save-dev&lt;/code&gt; flag, so they are listed in &lt;code&gt;devDependencies&lt;/code&gt;. This is not strictly necessary, since bundlers usually eliminate code that is not imported by your application (covered in the next article). However, it has become something of a standard practice, which you can follow if you like.&lt;/p&gt;

&lt;p&gt;Peer dependencies are also worth understanding because since npm 7, npm automatically installs peer dependencies by default, meaning you may see an error relating to conflicting versions of a package being installed in your project. This error can be ignored with &lt;code&gt;npm install --legacy-peer-deps&lt;/code&gt;, though it’s better in the long run to resolve the conflict.&lt;/p&gt;

&lt;p&gt;Finally, you might see some custom properties in &lt;code&gt;package.json&lt;/code&gt; that are not documented by npm. These can be used to specify configuration to build tools, which we’ll cover in Part 2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Package versions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we can get to one of the main advantages and complications of package managers - managing package &lt;em&gt;versions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When packages are published, they are classified by a version number. The traditional approach in software is that any release has three aspects to it, represented by three numbers separated by dots: the 'major' release version for major feature additions (1.x.x), the ‘minor’ release version for minor feature additions (x.1.x), and the 'patch' release version for small bug fixes (x.x.1). These numbers are incremented whenever necessary, so a package could skip straight from version 1.1.0 to version 1.2.0 for example, if the change made was a minor feature.&lt;/p&gt;

&lt;p&gt;npm packages are recommended to follow a strict, systemised interpretation of this approach called &lt;em&gt;semantic versioning&lt;/em&gt; (often abbreviated to 'semver'). This aims to make working with dependencies more reliable. The main rule is that minor and patch releases cannot contain &lt;em&gt;breaking changes&lt;/em&gt;, i.e. changes that would break code currently using the package.&lt;/p&gt;

&lt;p&gt;When you install a npm package, you can specify a version using &lt;code&gt;@&lt;/code&gt; if that version is available, e.g. &lt;code&gt;npm install react@16.14.0&lt;/code&gt;. But if no version is specified, and we don’t already have the package installed, npm will always install the latest version. In the example of &lt;code&gt;npm install react&lt;/code&gt;, that may look like this in the &lt;code&gt;dependencies&lt;/code&gt; property of &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"react": "^18.2.0"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;OK, so version 18.2.0 was installed. But what's that funny thing before the number? Well that's called a caret, and it complicates things a little.&lt;/p&gt;

&lt;p&gt;In theory, every package user and author could always specify exact versions of packages. This can be configured for all installations by running &lt;code&gt;npm config set save-exact=true&lt;/code&gt;, or for a particular package with &lt;code&gt;npm install --save-exact&lt;/code&gt;. You then need to update packages individually when you are sure it's safe to do so (minor and patch releases aren’t &lt;em&gt;supposed&lt;/em&gt; to break stuff - that doesn't mean they can't!). With this approach, package versions are specified in &lt;code&gt;package.json&lt;/code&gt; with no caret.&lt;/p&gt;

&lt;p&gt;There are couple of downsides to this: firstly, you have to track and manage all the versions of your dependencies yourself. Secondly, consider you install package A and package B in your project, but those packages depend on package C, and have specified slightly different versions of it. npm will have to install both versions of package C in your node_modules folder, which could be a waste of space - the packages probably would have worked fine with the same version of package C.&lt;/p&gt;

&lt;p&gt;So npm allows some flexibility - we can specify acceptable ranges of package versions. The default is that new patch or minor versions of the package will be tolerated (since they should not break existing code). This is what the caret in &lt;code&gt;package.json&lt;/code&gt; indicates. I can therefore run &lt;code&gt;npm update&lt;/code&gt; (or &lt;code&gt;npm install&lt;/code&gt;) with a particular package name, and the package will be updated to the latest non-major version. Or I can run &lt;code&gt;npm update&lt;/code&gt; without arguments to update all my packages at once. &lt;/p&gt;

&lt;p&gt;You may also see a tilde before the package version, e.g.  &lt;code&gt;"react": "~17.0.0"&lt;/code&gt;. This means that only updated patch versions are allowed, so React 16.3.1 could be installed but not React 16.4.0. This can be configured with &lt;code&gt;npm config set save-prefix='~'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Locking package versions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately there is a side-effect of allowing version ranges. Say someone else clones my repository and runs &lt;code&gt;npm install&lt;/code&gt;, and in the time since I installed the packages myself, there have been some minor or patch releases. The &lt;code&gt;package.json&lt;/code&gt; file stays exactly the same, but the other user gets slightly different versions of the packages, which could lead to different behaviour.&lt;/p&gt;

&lt;p&gt;To get around this, npm introduced another file called &lt;code&gt;package-lock.json&lt;/code&gt;, which is also created when you install packages. This file is sort of like a historical record: it shows the exact version of all the dependencies and sub-dependencies that were installed using &lt;code&gt;npm install&lt;/code&gt;, and it &lt;em&gt;should&lt;/em&gt; be committed to version control along with &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When another user runs &lt;code&gt;npm install&lt;/code&gt; in your project, npm will usually install the exact versions specified in &lt;code&gt;package.lock-json&lt;/code&gt; rather than the more recent minor or patch versions that &lt;em&gt;could&lt;/em&gt; be installed according to &lt;code&gt;package.json&lt;/code&gt;. This ensures consistency of package installations while still maintaining the benefits of specifying dependency ranges.&lt;/p&gt;

&lt;p&gt;For example, your &lt;code&gt;package.json&lt;/code&gt; might list &lt;code&gt;"react": "^18.1.0"&lt;/code&gt;. &lt;em&gt;Without&lt;/em&gt; a &lt;code&gt;package-lock.json&lt;/code&gt;, the other user could get React 18.2.0 installed instead. But if the &lt;code&gt;package-lock.json&lt;/code&gt; file says 18.1.0, that is what the other user will get.&lt;/p&gt;

&lt;p&gt;There is one exception, in the scenario that &lt;code&gt;package.json&lt;/code&gt; has been edited manually to specify a different version. If it was edited to say 18.2.0, for example, the other user will get that when running &lt;code&gt;npm install&lt;/code&gt;, even though &lt;code&gt;package-lock.json&lt;/code&gt; said 18.1.0. The installation causes &lt;code&gt;package-lock.json&lt;/code&gt; to be &lt;em&gt;updated&lt;/em&gt; to list 18.2.0.&lt;/p&gt;

&lt;p&gt;Note: &lt;code&gt;package-lock.json&lt;/code&gt; used to always win out in this case, but since users tended to see &lt;code&gt;package.json&lt;/code&gt; as the 'source of truth' of their package versions, npm altered the behaviour in 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialisers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So now you understand packages and the purpose of module bundling, but you still might be unsure how to get started building a JS application. One way to do this is by using a type of npm package known as an &lt;em&gt;initialiser.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Initialisers are designed to configure your local environment for building a certain type of app, including setting up the bundler. The name of these packages begins with ‘create’, and they contain code that can be run on the command line to install certain packages and set up config files for you.&lt;/p&gt;

&lt;p&gt;You can run these packages with the npm command &lt;code&gt;npx&lt;/code&gt;, which temporarily installs and runs the package specified in your local directory, then removes the installation once its work is done. This makes it ideal for initialisers, since they are only needed once in a project. So an example would be &lt;code&gt;npx create-react-app&lt;/code&gt;. You could also run &lt;code&gt;npm init react-app&lt;/code&gt; (no ‘create’ in the package name), which is a slightly newer equivalent (init is also aliased to create).&lt;/p&gt;

&lt;p&gt;Initialisers like this make it quicker to get up and running with a project. You can then to refer to their documentation to get an idea of what they are doing for you and how to continue. Usually you can also customise the setup to some degree to suit your needs.&lt;/p&gt;

&lt;p&gt;One downside is that you need a fairly clear idea of your app’s requirements before you start, unless you want to spend some additional time untangling the config later. Another is that outsourcing configuration means you don’t really need to understand it. Usually in development this works fine until something doesn’t work as you want it to, at which point it causes you a headache. In this series we’re diving into the details that some people ignore, so you can make a properly informed decision of how to set up your project, whether you choose to use an initialiser or not. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We’ve covered lots of information about modules and npm here, but we didn’t get to how build tools work. I’ll cover that in the next article because it’s a big topic. First, let’s recap the key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modules are key to modern JS, but the systems we use today are heavily influenced by the under-powered original design of HTML and the ‘historical’ developments since then. This is why we ended up using ESM, but not necessarily the browser implementation.&lt;/li&gt;
&lt;li&gt;Using packages via Node.js is so popular partly because it allows us to bundle our code to be fetched with a single network request, as well as managing different versions of our dependencies more easily. However, it is not without its own complications and drawbacks.&lt;/li&gt;
&lt;li&gt;Even though certain approaches have become very popular in the JavaScript community, you should always look to use the right tool for the job. That requires a solid understanding of the tools, which is what this series is all about.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Footnote: CDNs and npm&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You may have heard of an open-source project called &lt;a href="http://unpkg.com"&gt;unpkg.com&lt;/a&gt; which uses Cloudflare to provide a CDN link for every package available on npm. This is a free service relying on sponsors, and it doesn’t provide any uptime or support guarantees. So the project author doesn’t recommend relying on it for anything critical to a business. However, it can be very useful for demos, personal projects and trying out packages without a local environment set up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;p&gt;* = particularly recommended for further study&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lihautan.com/javascript-modules/"&gt;History of Web Development: JavaScript Modules - Tan Li Hau&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;* &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"&gt;JavaScript modules - MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://requirejs.org/docs/why.html"&gt;Why Web Modules? - RequireJS docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/issues/11503"&gt;Formalize top-level ES exports - React issue (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/adding-a-cdn-to-your-website/#aa-hold-up-you-lost-me-at-cdn"&gt;Adding and Leveraging a CDN on Your Website - CSS Tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sitepoint.com/7-reasons-not-to-use-a-cdn/"&gt;7 Reasons NOT to use a Content Delivery Network - sitepoint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/javascript-package-managers-compared/"&gt;JavaScript package managers compared: npm, Yarn, or pnpm? - Sebastian Weber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/about-npm"&gt;About npm - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v9/commands"&gt;CLI Commands - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v9/configuring-npm/package-json"&gt;package.json - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/2020-10-13-presenting-v7-0-0-of-the-npm-cli/"&gt;Presenting v7.0.0 of the npm CLI - GitHub blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.npmjs.org/post/162134793605/why-use-semver"&gt;Why use SemVer? - npm blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/cli/v6/configuring-npm/package-lock-json"&gt;package-lock.json - npm docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.quigley.codes/everything-you-wanted-to-know-about-package-lock-json/"&gt;Everything You Wanted To Know About package-lock.json But Were Too Afraid To Ask - James Quigley&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kentcdodds.com/blog/unpkg-an-open-source-cdn-for-npm"&gt;unpkg: An open source CDN for npm - Kent C Dodds&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>How to Get Your First Dev Job: A Complete Guide</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Sun, 20 Dec 2020 16:47:07 +0000</pubDate>
      <link>https://forem.com/joshcarvel/how-to-get-your-first-dev-job-a-complete-guide-n1d</link>
      <guid>https://forem.com/joshcarvel/how-to-get-your-first-dev-job-a-complete-guide-n1d</guid>
      <description>&lt;h2&gt;
  
  
  Intro 🚪
&lt;/h2&gt;

&lt;p&gt;If you are reading this article, you've probably heard of a strange phenomenon. &lt;/p&gt;

&lt;p&gt;I'm here to tell you that yes, it's true: the vast and mysterious realm of developers &lt;em&gt;is&lt;/em&gt; accessible to you, the humble sales assistant, accountant, fast-food worker or philosophy graduate, and the price of admission is not (necessarily) four or more years of gruelling and expensive education. In fact, you need only to &lt;em&gt;ask&lt;/em&gt; for entry. &lt;/p&gt;

&lt;p&gt;I know, because I did it. I taught myself to code online and landed a good job at a software company.&lt;/p&gt;

&lt;p&gt;But you may also know that the road to the door can be long, winding, and full of confusing words. You're probably wondering how best to avoid the trapdoors, navigate the mazes and tangled forests, and appear wise and knowing to the keepers of the gate.&lt;/p&gt;

&lt;p&gt;Well, I'm going to tell you that no matter how long and hard the journey, you just need to focus on &lt;em&gt;three&lt;/em&gt; factors. I'll tell you exactly how to do that, and also give you three secret weapons to help you along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The factors 📊
&lt;/h2&gt;

&lt;p&gt;The three factors you need to work on to get your first developer job are (in no particular order):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Your technical ability and knowledge, in the context of the job you are applying for&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your general employability, i.e. non-technical skills, traits and experience&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The number of positions you are considered for&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course there are other factors that affect whether someone is hired, such as luck, systemic issues or any number of prejudices or irrelevant considerations on the part of the employer. However, this article is about what &lt;em&gt;you can do&lt;/em&gt; to get a job, right now. In that context (and I mean &lt;em&gt;only&lt;/em&gt; in that context), every moment spent dwelling on these other factors is a wasted one.&lt;/p&gt;

&lt;h3&gt;
  
  
  A game of percentages
&lt;/h3&gt;

&lt;p&gt;You need to understand the three factors above for what they are: things that increase your &lt;em&gt;chances&lt;/em&gt; of getting a job as a developer. Being employable is not a binary state. You are not 'unemployable' as a developer, and then at some point emerge from your cocoon into an 'employable' developer butterfly.&lt;/p&gt;

&lt;p&gt;The choice to hire you is an individual one, made by an individual company. You could be hired with next to no technical skills, or you could do everything right to get a particular job, but still not get it.&lt;/p&gt;

&lt;p&gt;In these circumstances, the only thing you can do is &lt;em&gt;anything that will positively affect one of the three factors.&lt;/em&gt; All other things being equal, if there is a chance to increase your technical ability, you'll take it. If there is a chance to make yourself more 'employable', you'll take it, no matter how hard it is to judge yourself, or how much you hate promoting yourself. If there is another application to be made, you'll make it, no matter how afraid of rejection you are.&lt;/p&gt;

&lt;p&gt;The above may sound a little obvious, but if your journey to getting a developer job is like most people's (and mine), there will be plenty of opportunities for you to bemoan something outside of your control rather than taking a targeted, positive action. This is natural and only human, but you are going to need to keep picking yourself up and refocusing, time and time again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Priorities
&lt;/h3&gt;

&lt;p&gt;The caveat to the above is that you only have so much &lt;em&gt;time.&lt;/em&gt; In this article we'll look at how to prioritise in each of the three areas so you can maximise your efficiency.&lt;/p&gt;

&lt;p&gt;You may also be wondering, how important is each factor? There is no exact answer to this, but neglecting any one of these factors is damaging to your chances of getting a job, and it's far better to have a good level in all the factors than to have disproportionate focus on one.&lt;/p&gt;

&lt;p&gt;Many people focus far too much on factor 1, usually because they are most comfortable with working on technical skills. But virtually no company hires someone that did not present themselves in a good light through their communication with the company, and who doesn't seem like someone who can be worked with. And no company hires someone who they haven't heard of because they never applied, or who sent one email that got lost in a packed inbox.&lt;/p&gt;

&lt;p&gt;Some people go all in on factor 3, neglecting the other two, most commonly factor 2. But the fact is that if there is something fundamental holding you back, like poor communication skills, it's not going to matter how many companies you apply to - they are all going to react the same way. You need to be very aware of whether you have the fundamental qualities required for the positions you are applying for. This can be difficult because the companies you apply for will usually not tell you this, and mostly just ignore you. But we'll look at some ways you can improve these skills later.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long will it take?
&lt;/h3&gt;

&lt;p&gt;You may have seen articles in the form of 'how I became a developer in [x] months', with the only constraint on x seemingly being that it is greater than 0. One such article may have even inspired you to become a developer, and they often have lots of useful information in them.&lt;/p&gt;

&lt;p&gt;However, aside from the fact that they usually focus mainly on factor 1 and neglect the other two, they also tend to obscure the fact that transitioning into a coding job is a personal journey that depends very much on your own circumstances, traits, and the amount of time you have available to dedicate to it. &lt;/p&gt;

&lt;p&gt;The truth is that you should try to get your job as fast as possible, but no faster. Which sounds obvious, but when comparing yourself to others, you'll often feel pressure to go faster than you can. You will find it difficult, and chalk up your failings to personal deficiencies rather than seeing them as an inevitable part of the journey. You may face financial and personal pressures that make it seem like you needed to get your new job yesterday. But all you can do is keep plugging away at the three factors.&lt;/p&gt;

&lt;p&gt;To give &lt;em&gt;some&lt;/em&gt; kind of indication, yes, it is possible to get a developer job in a matter of months, given full-time study and efficient, focused learning. Less than 3 months is incredible, less than 6 is still remarkable and usually requires the help of a bootcamp. A more normal timescale for full-time study is 6-12 months. For anything less than full-time study, 1-2 years would be a more common timescale. All of this also depends on the requirements of the job you get at the end of it as well - there are many kinds of developer roles.&lt;/p&gt;

&lt;h3&gt;
  
  
  A wake-up call?
&lt;/h3&gt;

&lt;p&gt;If you are already some way on the journey to your first dev job, just understanding and acting on the advice in this section will take you a long way. If you already know the best way to gain technical skills, become employable or get your foot in the door with a company, but have been neglecting one of these factors, your main take-away from this should be to just &lt;em&gt;get on with working on it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But I'll now go into a lot more detail on how to work on the 3 factors. First, I'm going to tell you your secret weapons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your secret weapons ⚔️
&lt;/h2&gt;

&lt;p&gt;Many people know some of the things I'll tell you in the next few sections, such as where to find coding materials, what to put on your CV, and so on. What they struggle with is some more fundamental problems.&lt;/p&gt;

&lt;p&gt;They lack confidence, they don't see themselves as good enough to be a developer. They struggle with keeping discipline and good habits. They give up too early.&lt;/p&gt;

&lt;p&gt;But you are going to overcome those challenges. You have some secret weapons.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Vision
&lt;/h3&gt;

&lt;p&gt;The first step to achieving anything should always be honing your vision of where you are going and how you see yourself. Below, we'll talk about getting clarity on the job you want. But ideally, you should be looking even further beyond that. &lt;/p&gt;

&lt;p&gt;Where do you want to be, ultimately? What would you be doing if money was no object, really? It doesn't even matter if the answer is not 'being a developer', if becoming a good, well-paid developer is how you get there. It also doesn't matter if the answer is just a guess (you're not a soothsayer), so long as it helps to focus and motivate you.&lt;/p&gt;

&lt;h4&gt;
  
  
  Supercharged motivation
&lt;/h4&gt;

&lt;p&gt;Once you have a long-term vision, you should already be even more excited about your journey. Work backwards from there to the short-term. Roughly plot out some points on the journey - where will you be in ten years, five years, one year. Just guesses that don't seem totally unreasonable. This should lead you to a better idea of the first developer job you want to get.&lt;/p&gt;

&lt;p&gt;Once you've done this, everything you do from now on should have a clear &lt;em&gt;why&lt;/em&gt; behind it. When you have to do hard things like sit down to code, make another job application or attend a networking event, and you wonder &lt;em&gt;why bother?&lt;/em&gt;, your answer is right there staring at you: because it will directly lead you to the thing you most want to do in the world. Then you have a simple choice: do something a bit hard now for limitless gain in the future, or give up on what you really want.&lt;/p&gt;

&lt;h4&gt;
  
  
  You 2.0
&lt;/h4&gt;

&lt;p&gt;Having a clear vision also goes to the core of how you see yourself. If you can see and &lt;em&gt;believe&lt;/em&gt; (even just a little bit) a vision of yourself achieving something you would be really proud of, you can start to see how you could change and become the &lt;em&gt;sort of person&lt;/em&gt; that can achieve that result. Then simply start trying to be that person a little more every day - the more you practise, the better you get.&lt;/p&gt;

&lt;p&gt;Start thinking of yourself as whatever you want to be - an entrepreneur or freelancer, a problem-solver, a leader - and let your actions slowly start to fit the role a little better. And, of course, start thinking of yourself as a developer. As soon as you write some code that does something, you're not an &lt;em&gt;aspiring&lt;/em&gt; developer, you are a developer, by definition. Just not a professional one. So embrace it. Put it on your CV. This is the new you!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Habit
&lt;/h3&gt;

&lt;p&gt;Habit is the key to achieving any goal. Once you have a big, long-term vision, you need to link it to a small, focused, consistent habit.&lt;/p&gt;

&lt;p&gt;Scientifically speaking, a habit is more of an automatic reaction. It doesn't cover a conscious and deliberate action like coding for an hour. But the secret is to master the automatic behaviours that put you in the &lt;em&gt;right place, with the right environment, at the right time&lt;/em&gt;, to do the activity you want to do. Once you practise this for a while, nine or more times out of ten, you will do the activity you intend.&lt;/p&gt;

&lt;p&gt;Let's say you want to practise sitting down to code at a certain time. Here are some factors you need to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to be in the right frame of mind for focusing. Carving out some time at the beginning of the day rather than leaving it to the end will probably be better for most people. There is evidence that your willpower and ability to focus is sapped as the day goes on (see sources at the end of this article).&lt;/li&gt;
&lt;li&gt;Your environment needs to be as comfortable as possible, e.g. a proper desk with good ergonomics, preferably clean and tidy - a place that makes you &lt;em&gt;want&lt;/em&gt; to spend time there.&lt;/li&gt;
&lt;li&gt;Minimise distractions. Just leave your phone in another room, seriously. It's the biggest productivity killer imaginable. If there are other people around, they need to know not to disturb you if possible.&lt;/li&gt;
&lt;li&gt;Have a clear time period with breaks. E.g. study in 20 minute bursts with breaks, or 45 minutes, whatever works for you. Use a timer for best results.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Slow and steady
&lt;/h4&gt;

&lt;p&gt;When you start a new habit, you have to start small. You need small wins. If you say you're going to fit in 4 hours a day of coding that you barely have time for, you're setting yourself up to miss your target, and the negative self-talk most of us are very familiar with will happily step in.&lt;/p&gt;

&lt;p&gt;Instead, focus on that small behaviour. It could be as simple as just sitting down at the computer at the right time. Every day, for a month. Or studying without getting distracted for an hour (breaks not included). Simple, quantifiable actions. It doesn't really matter if the study session went great, or it was really hard and confusing, and you didn't feel like you made progress. What matters is that you did what you intended, and that's all you can do. It will all add up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Other tips
&lt;/h4&gt;

&lt;p&gt;There's lots more I could say about habits, but here's just a few more tips to follow if you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accountability is a great tool. Tell &lt;em&gt;one or two people you respect&lt;/em&gt; what you are going to do (don't only announce it on social media - no one there will chase you up if you don't follow through). For best results, write it down in the form of a promise.&lt;/li&gt;
&lt;li&gt;Be flexible. If something's not working, tweak it. You don't want to change your habit all the time, but you don't want to stick with something that's not achievable. Find what works for &lt;em&gt;your&lt;/em&gt; schedule, your life, your personality, so you can do it consistently.&lt;/li&gt;
&lt;li&gt;Keep a chart on your wall of your progress. Set mini-goals and celebrate when you achieve these landmarks. It doesn't matter how much of the mountain is still ahead of you - always remind yourself of how far you've come and be proud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Persistence
&lt;/h3&gt;

&lt;p&gt;Most of us are guilty of a poor understanding of results. We expect results to happen steadily as a direct proportion of effort - a perfectly diagonal line on a graph. In most cases, it's actually a curve that starts off very gentle for a long time and then starts to curve sharply upwards.&lt;/p&gt;

&lt;p&gt;Once we accept this (and it is &lt;em&gt;very&lt;/em&gt; hard to accept), we have to commit to simply doing the &lt;em&gt;actions&lt;/em&gt;, and have faith that the &lt;em&gt;results&lt;/em&gt; will come later. If you've ever learnt a musical instrument, you know that in the beginning, after the initial rush of your first few little achievements, you start to feel like you've plateaued at a really low level, and that you're not making any progress despite your practise. Then, one day, like magic, you suddenly realise you can play something that you've been struggling with for ages.&lt;/p&gt;

&lt;p&gt;Learning to code is no different. Getting a job is no different. These things are hard for a long time, until suddenly, they're not. You finally understand a concept. You finally get to grips with a language. You finally get the knack of job applications. You finally get the job.&lt;/p&gt;

&lt;p&gt;It's easy to get discouraged in the thick of it. But if you have your clear vision, you have your simple, well-defined habit, and you have the &lt;em&gt;commitment&lt;/em&gt; to just seeing it through &lt;em&gt;until&lt;/em&gt; you are successful, then there will be no stopping you. &lt;/p&gt;

&lt;p&gt;With all that said, let's finally look more closely at the three factors I mentioned at the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factor 1: Technical ability 👨🏽‍💻
&lt;/h2&gt;

&lt;p&gt;Factor 1 is: &lt;strong&gt;"Your technical ability and knowledge, in the context of the job you are applying for."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note the second part - &lt;em&gt;in the context of the job you are applying for&lt;/em&gt;. If your goal is to get hired, and time is of the essence, then &lt;em&gt;everything you learn&lt;/em&gt; needs to be relevant to getting hired. &lt;/p&gt;

&lt;p&gt;Naturally, if you don't know what sort of job you are looking for, you will struggle with knowing what to learn. So step 1 is to target a specific kind of job - the more specific, the better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Targeting a job
&lt;/h3&gt;

&lt;p&gt;How do you know what job you want? First you need to do a little research on what is out there. Google and YouTube are your friends here. Also try to speak directly to developers if possible, for example at the company where you work, or through social media like Twitter.&lt;/p&gt;

&lt;p&gt;You don't want to drag out this stage too long - get some understanding of web dev vs. software dev, front end vs. back end and so on, just enough to start to feel &lt;em&gt;some kind of&lt;/em&gt; preference, then &lt;em&gt;choose.&lt;/em&gt; The important thing is just to make a decision. It's not for life. After you've gotten your first dev job, you can branch out or switch tracks - it happens all the time.&lt;/p&gt;

&lt;p&gt;If you are really struggling with the decision, you may want to go further into a few different paths, for example by trying out a few different programming languages and seeing what you prefer. It certainly is never going to hurt to be learning something about coding. However, the longer you put off deciding what to focus on, the less efficient your journey will be.&lt;/p&gt;

&lt;h4&gt;
  
  
  Narrowing it down further
&lt;/h4&gt;

&lt;p&gt;Once you've chosen your path, you will need to do some further research to understand the technologies involved, the type of jobs available, and to &lt;em&gt;narrow your focus down even further&lt;/em&gt;. For example, you may have decided to become a front-end web developer. Even within this path, there is a lot of variety. &lt;/p&gt;

&lt;p&gt;Do you want to build &lt;em&gt;websites&lt;/em&gt;, for example as a freelancer or at a web design agency, focusing mostly on HTML and CSS, maybe doing some design work, and probably working with a content management system? Or do you want to work on web &lt;em&gt;applications&lt;/em&gt;, focusing more on JavaScript and using a JavaScript framework? (for related discussion see: &lt;a href="https://css-tricks.com/the-great-divide/"&gt;https://css-tricks.com/the-great-divide/&lt;/a&gt;). And which framework - React, Vue, Angular?&lt;/p&gt;

&lt;p&gt;Look at job listings in your area to get a better idea of this. You should narrow it down to the point where there is a just a handful of job titles you are looking for (although some companies will use titles inaccurately) and you can instantly recognise the sort of job description that suits you.&lt;/p&gt;

&lt;p&gt;When we talk about narrowing down the jobs you are eligible for, you may be concerned that you are reducing your chances of getting a job. The opposite is true. You are applying for fewer jobs, but have a &lt;em&gt;much better chance&lt;/em&gt; of getting them, because everything you have been learning is relevant to those jobs. If you cast your net wider, you will be overlooked in favour of people with more relevant skills.&lt;/p&gt;

&lt;h4&gt;
  
  
  A note about job adverts
&lt;/h4&gt;

&lt;p&gt;It's well known that many developer job adverts are not very realistic or helpful. They may list skills that are not really required, overemphasise certain aspects or ask for a computer science degree regardless of whether the role requires it. &lt;/p&gt;

&lt;p&gt;Companies often advertise for their &lt;em&gt;ideal&lt;/em&gt; candidate, and there can be quite a gap between the job description and the skills of the person they will actually hire. In other cases, the advert may be written by someone that doesn't fully understand the role.&lt;/p&gt;

&lt;p&gt;It's very important to bear this in mind to avoid being discouraged. Focus on whether the main &lt;em&gt;gist&lt;/em&gt; of the role suits you. Then apply. &lt;/p&gt;

&lt;h3&gt;
  
  
  Learning
&lt;/h3&gt;

&lt;p&gt;This is the best part of the journey. If you don't enjoy learning, you probably shouldn't become a developer.&lt;/p&gt;

&lt;p&gt;But how should you do it? First, keep in mind two main principles, which we'll come back to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Learn from a &lt;strong&gt;reputable source&lt;/strong&gt; of information&lt;/li&gt;
&lt;li&gt;Make sure you are getting &lt;strong&gt;value for money&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Two options
&lt;/h4&gt;

&lt;p&gt;Let's assume you are not going to do a computer science degree, since the main topics of study are not immediately relevant to the typical new developer.&lt;/p&gt;

&lt;p&gt;You then have the choice between some other paid course, most commonly at a coding 'bootcamp', or 'teaching yourself' with online resources. As someone who did the latter, I'm a bit biased towards it, but you have to choose the option that's right for you.&lt;/p&gt;

&lt;p&gt;Teaching yourself is very difficult - you have fewer people to go to for help, it can be hard to learn the right topic at the right time, and you have to be very driven and self-motivated. You are alone with the mountain of information on the internet. On the other hand, you'll save a hefty amount of money, and if you get through it, you'll also come out of it with bucket-loads of resilience, research skills and problem-solving ability to brag to employers about.&lt;/p&gt;

&lt;p&gt;If you feel like you probably need a bit more of a push and a guiding hand, a bootcamp could be for you. Your learning will be efficiently packaged up for you, you will have a cohort to get through it with, teachers to ask questions of, and probably be given the opportunity to network with some local companies. It's not uncommon for people to go straight from a bootcamp into a job, though it depends on the individual.&lt;/p&gt;

&lt;p&gt;Just bear in mind that bootcamps are not currently regulated, and they usually ask for a lot of money for a relatively short period of education, so you should do thorough research and make your own judgement, keeping in mind the two principles mentioned above.&lt;/p&gt;

&lt;h4&gt;
  
  
  Teaching yourself
&lt;/h4&gt;

&lt;p&gt;We'll now talk about how to go about teaching yourself, but this is not just for the non-bootcamp route. As a developer you will always be teaching yourself to some extent. Technology is always changing and the web is your instruction manual. &lt;/p&gt;

&lt;p&gt;Here's three points to consider.&lt;/p&gt;

&lt;h5&gt;
  
  
  1. What you learn
&lt;/h5&gt;

&lt;p&gt;This part should be fairly straightforward for getting your first dev job - you should know from your research where you need to start, and you can add some things to the list as you go. &lt;/p&gt;

&lt;p&gt;However, the aim is to keep the list &lt;em&gt;as short as possible&lt;/em&gt; to get your first developer job. As you start learning you will come across many, many different technologies and aspects of development. There will be a lot of temptations to stray off course. You need to build the habit of sticking with what is on your list.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Where you learn
&lt;/h5&gt;

&lt;p&gt;There is no shortage of resources online to learn development, but they do vary in quality and price. You need to again bear in mind the two principles above.&lt;/p&gt;

&lt;p&gt;I won't list them all here, because there is plenty of info out there if you google what resources are best in your chosen area of development. But I'll explain the types of content you will see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Interactive tutorial websites&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Websites such as &lt;a href="https://www.freecodecamp.org/"&gt;freeCodeCamp&lt;/a&gt; (free!) and &lt;a href="https://www.codecademy.com/"&gt;codecademy&lt;/a&gt; (free/paid) offer tutorials where you can code in your browser, along with other kinds of content. You will probably want to make use of one of these kinds of courses at least once in your journey.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Video tutorials&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Video tutorials are great resources which I personally like a lot, and they're especially useful for beginners because you can see how professional developers write code and learn a lot from them. As well as teaching particular topics, there are lots of videos teaching you to build a particular project which you can code along with.&lt;/p&gt;

&lt;p&gt;There are lots of great programming video creators, and I really strongly advise that you do some googling to find out who they are first, to avoid missing out on content you might miss if you just search for content on a particular topic. Many of them have free videos on YouTube, either on a single topic or a free sample of a paid-for course, so make use of these.&lt;/p&gt;

&lt;p&gt;You can also buy courses on sites like &lt;a href="https://www.udemy.com/"&gt;Udemy&lt;/a&gt; (just be aware of Udemy's marketing tactics of hiking up prices then having an almost constant 'sale'). Don't shy away from buying a course from a reputable creator, because you will usually get what you pay for and get a lot more value than free resources. However, this shouldn't be your default option and you shouldn't need more than a handful of paid courses. Personally, I got a job after spending a grand total of £45 on Udemy courses (I bought three).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Plain text information&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will find a lot of good content in the form of technical documentation, books and online references. For example, if you are learning JavaScript there is the &lt;a href="https://developer.mozilla.org/en-US/"&gt;MDN documentation and tutorials&lt;/a&gt;, sites like &lt;a href="https://javascript.info/"&gt;javascript.info&lt;/a&gt; and books like &lt;a href="https://github.com/getify/You-Dont-Know-JS"&gt;You Don't Know JS&lt;/a&gt;. Personally, I didn't use any physical books to learn to code - there was enough info available free online. But if you prefer textbooks, there are plenty, such as O'Reilly books.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;u&gt;The stuff you find when you google a question...&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is where you really need to pay special attention to the &lt;em&gt;reputable source of information point&lt;/em&gt;. When you google a programming question you will usually find lots of articles on it, and lots of answers on the programming Q&amp;amp;A site StackOverflow. Usually the cream rises to the top. Just be careful. Make a habit of cross-checking information with documentation where possible and don't just believe someone because they used some big words.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Audio&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are quite a lot of podcasts related to development which you may find useful when you are away from your computer. Because of the nature of the medium, they often aren't focused on strictly technical information but on related discussions. &lt;/p&gt;

&lt;p&gt;My experience was that early on, I found it useful and encouraging to listen to podcasts such as CodeNewbie podcast and hear stories of people who transitioned into tech. But afterwards, I wanted technical information and found it hard to find. I also found that a lot of podcasts were aimed at more experienced developers and I found the discussions alienating and discouraging because I didn't understand them.&lt;/p&gt;

&lt;p&gt;I did find a couple of podcasts that were right for me, and I encourage you to do some digging to find the ones that are relevant to you. But I don't subscribe to the theory that you should be trying to absorb as much development information as possible, regardless of whether you understand it - I think this can often do more harm than good.&lt;/p&gt;

&lt;h5&gt;
  
  
  3. How you learn
&lt;/h5&gt;

&lt;p&gt;Most people don't think about this factor, but it's &lt;em&gt;vitally important&lt;/em&gt;. It's a huge topic in itself, on which there is decades of scientific research, but I will mention just a few key principles that will drastically improve your learning efficiency. (Sources to back up these points are listed at the end of this article).&lt;/p&gt;

&lt;p&gt;1. The holy grail: &lt;strong&gt;Active learning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a very simple idea, but it takes effort, so it's often ignored. The truth is, if you sit and passively watch a video or scroll through some information, you are not going to remember most of it. We are exposed to a cacophony of stimulus every second of our lives - if we remembered everything, we just wouldn't be able to function. Our brain is designed to discard most information.&lt;/p&gt;

&lt;p&gt;So if you want to remember something, you need to &lt;em&gt;make your brain know it's important.&lt;/em&gt; Anything you can do to get your brain working will help you learn, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Testing yourself. For example, make something by following a coding tutorial, then try to make it &lt;em&gt;without&lt;/em&gt; the tutorial. It doesn't really matter how often you have to check the tutorial for answers - just &lt;em&gt;trying&lt;/em&gt; to think for yourself will still be beneficial to your retention of the information.&lt;/li&gt;
&lt;li&gt;Asking questions ('what does that mean?', 'is that what I expected?', 'what do I think is going to be the answer here?', etc.)&lt;/li&gt;
&lt;li&gt;Coding along with a video (but trying to fully understand the information rather than just copying it out)&lt;/li&gt;
&lt;li&gt;Being creative - applying your knowledge in a new context by making something new or customising something that exists&lt;/li&gt;
&lt;li&gt;Cross-checking information&lt;/li&gt;
&lt;li&gt;Trying to &lt;em&gt;explain&lt;/em&gt; the information to someone else, e.g. in a blog post (one of my personal favourites!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't have to wait until halfway through learning to do these things, you can do them from the beginning. For example, it has been shown that testing yourself on a topic you know &lt;em&gt;nothing about&lt;/em&gt; improves your subsequent retention of information on that topic.&lt;/p&gt;

&lt;p&gt;Bear in mind that active learning is &lt;em&gt;harder.&lt;/em&gt; It will feel &lt;em&gt;uncomfortable&lt;/em&gt;. In learning science this is often called 'desirable difficulty'. You will come to recognise the right level of discomfort, which is somewhere between comfort and feeling completely clueless. If you are feeling completely clueless you need to break the task down into smaller pieces or try something a bit simpler first.&lt;/p&gt;

&lt;p&gt;Because it's harder, you need to take regular breaks. Breaks have been shown to reduce stress and improve productivity anyway, so it's all good. And active learning with breaks will still be more efficient in the long-term than passive learning without breaks.&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Rehearsal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even taking all the advice above, your retention of the information will still degrade naturally over time, for the reason mentioned above (we can't remember everything). You need to &lt;em&gt;rehearse&lt;/em&gt; information to make it stick.&lt;/p&gt;

&lt;p&gt;The maximally efficient method is to rehearse information &lt;em&gt;just before&lt;/em&gt; you are about to forget it, but this is very difficult, as the timing of that point has been shown to depend on a lot of factors. So don't worry too much about this. When you are learning to code on a need-to-know basis, there are natural points for rehearsal: when you need to use something you learned and you realise you've forgotten it. In my experience, I usually learn the info quicker the second time, so the time I originally spent wasn't wasted, and that's good enough.&lt;/p&gt;

&lt;p&gt;Just be aware that if you are taking the time to study certain concepts, it could be worth also going over some that you learned a week or a month ago. The main thing is, &lt;em&gt;don't feel bad about forgetting things&lt;/em&gt;. It's not a personal failing - it's just how the brain works.&lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;Variety&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Variety is good for a few reasons. First, doing relatively short bursts of varied activities (called &lt;em&gt;interleaving&lt;/em&gt; in cognitive science) has been shown across many fields of study to be more effective than studying one concept for a longer period. So if you were planning for example to learn about loops in JavaScript for an hour, you will probably be better splitting the time between loops, if statements and scope etc. instead, &lt;em&gt;even if&lt;/em&gt; it doesn't feel as helpful at the time.&lt;/p&gt;

&lt;p&gt;Second, you want to get a diversity of perspectives. In an age of free-flowing but not necessarily correct information, you need to make sure the info you hear is actually &lt;em&gt;correct.&lt;/em&gt; And when it comes to matters of opinion, the world of development is rife with these, so all you can do is hear a variety of perspectives and make up your own mind. So vary your learning materials as well as your activities. If you always stick with the same teacher or resource, you are missing the opportunity to become a better developer.&lt;/p&gt;

&lt;p&gt;Finally, varying the &lt;em&gt;context&lt;/em&gt; of learning has been shown to improve learning. Learn in different places, in different ways, with different music, and so on, and you have a better chance of it sticking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Troubleshooting
&lt;/h3&gt;

&lt;p&gt;Almost as important as your ability to learn is your ability to find solutions when things go wrong. &lt;/p&gt;

&lt;p&gt;Writing code for computers is hard, because they do exactly what we &lt;em&gt;wrote&lt;/em&gt;, not just what we &lt;em&gt;meant&lt;/em&gt;. An unintended effect of your code is called a &lt;em&gt;bug&lt;/em&gt;. Debugging is a huge time sap and a crucial skill for developers, which is often neglected. Many developers don't think too much about their approach and just try lots of things until it works. Here's a quick summary of some steps I usually take.&lt;/p&gt;

&lt;h4&gt;
  
  
  Googling
&lt;/h4&gt;

&lt;p&gt;The web is full of answers to development problems. People have written about them in countless blog articles or discussed them in forums. All developers, from junior to senior, google stuff all the time. There is simply far, far too much to know and no point reinventing the wheel when so many have been there before you.&lt;/p&gt;

&lt;p&gt;For example, if you have a problem with a specific library, you may find answers or at least better explanation of the problem on the Issues page of the library's repository on GitHub. But your most common source for answers will probably be StackOverflow, an invaluable Q&amp;amp;A site for development questions.&lt;/p&gt;

&lt;p&gt;When googling, you need to bear a few things in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Phrasing is crucial. Don't ask the question one way then give up. Try a number of different possible keywords. Sometimes you will not know the word for the issue, but it will pop up in one of the search results. Then use that word in your search, and voilà! You find what you were looking for.&lt;/li&gt;
&lt;li&gt;Don't expect to find the &lt;em&gt;exact&lt;/em&gt; answer you need for your use case. Often you can get what you need from the answer to a somewhat &lt;em&gt;similar&lt;/em&gt; problem, which will inspire you to try something that solves your problem, or you come across some code that can be adapted a bit to suit your use case.&lt;/li&gt;
&lt;li&gt;As mentioned already, think critically about the answer you find. For example, don't just find one answer on StackOverflow and immediately copy some code. Look at the other answers and reaction. Cross-check what the person is saying and see if it is reliable, or if there are problems with the solution. If you don't, you will probably just cause yourself more headaches in the future.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While Google is often your first port of call, it isn't always. Some problems simply require basic programming knowledge to fix, or are very specific to your use case, and Google will be of less help here. I've found that when my code doesn't work and I find nothing via Google, it's either because I've just made some basic error somewhere, or my case is so niche that no-one has written about it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Check the obvious things
&lt;/h4&gt;

&lt;p&gt;Checking you haven't done something really stupid before you proceed will save you a lot of time as a developer. Check for typos. Check little things like whether your greater-than/less-than signs and true and false conditions are the wrong way around. Always assume there could be something really simple going wrong because this is quite often the case!&lt;/p&gt;

&lt;p&gt;The next thing to check is the few things you think are most likely to be causing the problem. Just jump straight in investigating what is going on in those areas and you might get lucky.&lt;/p&gt;

&lt;h4&gt;
  
  
  In-depth debugging
&lt;/h4&gt;

&lt;p&gt;If you've exhausted your other options, I find the best approach is a very methodical one. This is time-consuming but usually gets to the root of the problem. Problems usually arise in complicated, niche use cases. So first, create a more simplified version of the scenario where everything &lt;em&gt;does&lt;/em&gt; work as expected. Then add things one by one, to get it closer to your real-life use case. Sooner or later you'll identify the thing that causes the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factor 2: Employability 👩‍💼
&lt;/h2&gt;

&lt;p&gt;'Soft' skills are not really any less important for a developer than any other job, despite the stereotype of the unsociable programmer. True, you will probably escape being &lt;em&gt;tested&lt;/em&gt; on these aspects, but you may be asked questions about them, and it will also greatly affect your application and how you come across at interview.&lt;/p&gt;

&lt;p&gt;Let's look at how to develop and use these skills before and during interviews.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting an interview
&lt;/h3&gt;

&lt;p&gt;Before you get an interview, you have one, simple goal: to get an interview. Forget about whether you'll get the job, forget about how the interview might go, forget about technical questions. Just do everything you can to make yourself stand out in a positive light - that means your CV, portfolio site and customised cover letter.&lt;/p&gt;

&lt;p&gt;Of course, you don't technically &lt;em&gt;have&lt;/em&gt; to do any of this (though you'll probably always need a CV). For example, you could get lucky and land an interview through someone you know. But if you don't, then you have no excuse not to do everything you can to sell yourself.&lt;/p&gt;

&lt;h4&gt;
  
  
  CV
&lt;/h4&gt;

&lt;p&gt;CVs are still very relevant for developer jobs, and you should assume the employer will look carefully at it even if you have an online portfolio. You want your CV to be a simple, at-a-glance reflection of your best qualities and technical skills. Keep it to &lt;em&gt;one page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are a design-focused developer you can design something nice, but otherwise, don't fret about details like layout - it's window dressing. Use a nice, clean template that displays the information clearly and has a bit of colour.&lt;/p&gt;

&lt;p&gt;Assuming you don't have much or any work experience that is relevant to development, I suggest you do a skills-based CV that has the following sections:&lt;/p&gt;

&lt;h5&gt;
  
  
  Title
&lt;/h5&gt;

&lt;p&gt;The title can just be your name, and the subtitle is the job title you are after, or the specific one you are applying to. For example, my subtitle was usually Front-End Developer.&lt;/p&gt;

&lt;p&gt;Don't say 'junior' developer. The company may or may not end up labelling you that way, but there's no point lowering your status yourself. Just calling yourself a 'developer' shows more confidence and is by no means inaccurate.&lt;/p&gt;

&lt;h5&gt;
  
  
  Profile
&lt;/h5&gt;

&lt;p&gt;This is a bullet-point style tagline reflecting the key selling points - a couple of sentences at most. Here is the one I used: "Highly motivated, self-disciplined, self-taught developer. I create modern, responsive and accessible websites and applications."&lt;/p&gt;

&lt;h5&gt;
  
  
  Skills
&lt;/h5&gt;

&lt;p&gt;List the technologies you are familiar with and other desirable skills e.g. test-driven development, responsive design etc.&lt;/p&gt;

&lt;h5&gt;
  
  
  Experience
&lt;/h5&gt;

&lt;p&gt;Employers want to see experience that &lt;em&gt;is relevant to a developer job.&lt;/em&gt; That means writing about the app you taught yourself to make is more relevant than some unrelated paid job. There's no rule that says you have to list all your paid work in your experience section - it's your CV, you can do what you want.&lt;/p&gt;

&lt;p&gt;So create a sub-section for your self-teaching or bootcamp and summarise the key things you did. Any extra things you did like making something at a hackathon or contributing to open-source are good here too. Then you can add a brief sub-section on your most recent job, and put the rest of your work history on your LinkedIn so you aren't hiding anything.&lt;/p&gt;

&lt;h5&gt;
  
  
  Education
&lt;/h5&gt;

&lt;p&gt;This can go last - just your most recent qualifications.&lt;/p&gt;

&lt;p&gt;Finally, you will need your contact information somewhere, other website links (covered below) and a link to your portfolio.&lt;/p&gt;

&lt;h4&gt;
  
  
  Portfolio
&lt;/h4&gt;

&lt;p&gt;An online portfolio is a chance to stand out a bit more to the employer, and a good place to show off the stuff you've built. It doesn't have to be complicated.&lt;/p&gt;

&lt;p&gt;If your main focus is building websites (as opposed to web applications, apps or backend programming), you should arguably make the whole thing yourself, or at least heavily customise it using the CMS you intend to mainly work with professionally.&lt;/p&gt;

&lt;p&gt;If not, I'd recommend using something a little more off-the-shelf and doing a bit of customisation, since you are going to need most of your time for working on the stuff to showcase. For example, I made a WordPress site for mine and integrated a paid theme. There was some hassle involved in learning to use WordPress, but I still ended up with an attractive, reliable site with a functioning blog in a relatively short space of time.&lt;/p&gt;

&lt;p&gt;You want your portfolio to do three main things - emphasise your key selling points, showcase your projects and host your blog. This can be done in three sections or pages  (depending on how your portfolio is laid out). Remember to also include a contact form or contact details.&lt;/p&gt;

&lt;h5&gt;
  
  
  Home / About
&lt;/h5&gt;

&lt;p&gt;This will rehash some of the key points from your CV, but hopefully with a bit more style. So highlight who you are, your main attributes and skills, but add some nicer design into the mix. Look at other developer portfolios for some inspiration. Bear in mind, if you google for this you'll find some insanely good ones which aren't the most realistic examples for you - it's better to just find some good developers - blog authors, devs on Twitter etc. and look at their personal site.&lt;/p&gt;

&lt;p&gt;You can also add a (brief) element of &lt;em&gt;story&lt;/em&gt; about who you are to make it more interesting, e.g. briefly explaining what you used to do and why and how you are transitioning to tech - but remember to &lt;em&gt;sell&lt;/em&gt; yourself along the way - emphasise why your skills suit tech and the characteristics and skills that helped you learn.&lt;/p&gt;

&lt;h5&gt;
  
  
  Projects
&lt;/h5&gt;

&lt;p&gt;Secondly, you want a page to show off your projects. As well as linking to the deployed project and the code, talk a little about the project, why you made it, why you made the choices you did and what you learned. This will really show you can think and communicate intelligently about tech and give insight into your learning process, which is important to employers.&lt;/p&gt;

&lt;h5&gt;
  
  
  Blog
&lt;/h5&gt;

&lt;p&gt;Thirdly, you ideally want a blog where you can write a little about tech and things you've learned. Yes, this is even more work, but it will show employers that you are enthusiastic, knowledgeable and eager to share that knowledge, which is a triple win. &lt;/p&gt;

&lt;p&gt;Of course, you can and should blog on other platforms. For example, &lt;a href="https://dev.to/"&gt;Dev&lt;/a&gt;, &lt;a href="https://dev.to/"&gt;freeCodeCamp news&lt;/a&gt; and &lt;a href="https://hashnode.com/"&gt;hashnode&lt;/a&gt; are popular platforms for free tech articles, and &lt;a href="https://medium.com/"&gt;Medium&lt;/a&gt; is also still popular, though they have a paywall system. However, the best strategy is to have any articles you publish on these platforms be copies that link back to the original your own website via the canonical url section ('This article was originally published on...'). That way employers can see your writing on your own site and your site gets a SEO boost, plus you have full control of your original articles.&lt;/p&gt;

&lt;p&gt;Many newcomers, and even experienced developers feel self-conscious about posting an article on technology. You could get something wrong, and some people might not like your article. However, if you use reliable sources of information and are not pretending to be an expert in the subject matter, you should publish it anyway. If something needs corrected you can make a correction, and anyone who responds with unconstructive criticism can safely be ignored.&lt;/p&gt;

&lt;p&gt;Remember, this is helping you get a job, and getting a job is about putting yourself out there. The greater the exposure, the greater the chance of reward. And the majority of people in the developer community will be supportive of you sharing your knowledge.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cover Letter
&lt;/h4&gt;

&lt;p&gt;Cover letters are important - they highlight why you are right for &lt;em&gt;this specific job,&lt;/em&gt; unlike your CV or portfolio. It's fine to have a rough template, but you need to tailor it for every application you make. Here are some key points to consider.&lt;/p&gt;

&lt;h5&gt;
  
  
  Format
&lt;/h5&gt;

&lt;p&gt;Many people use the traditional Word-processed document approach, and so did I, but you may prefer to just write your pitch in the body of your email. It does seem a little antiquated to produce a 'letter' with the company address when you aren't actually posting it, though on the other hand it does show some effort and give it a little gravitas. Different employers will have different preferences so you just need to pick one approach - either will probably do fine.&lt;/p&gt;

&lt;h5&gt;
  
  
  Style
&lt;/h5&gt;

&lt;p&gt;I see no reason to be formal in the content of the letter and I think an informal, natural style works best in this day and age. I start my letters with 'Hi,' and end with something like 'Thanks for your time', sidestepping those awkward old-fashioned introductions like 'To whom it may concern', or worse, 'Dear Sir/Madam'.&lt;/p&gt;

&lt;h5&gt;
  
  
  Content
&lt;/h5&gt;

&lt;p&gt;You can find plenty of good pointers and inspiration online for this, and hopefully you already understand the main points (sell yourself, be persuasive, use evidence etc.) so I just want to emphasise some key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be &lt;strong&gt;specific&lt;/strong&gt;. It's pretty obvious when you've copied a template and changed the company name. Yes, you may have never heard of the company before but you need to mention &lt;em&gt;something&lt;/em&gt; that attracts you to the company and shows you do know who they are.&lt;/li&gt;
&lt;li&gt;Pitch &lt;strong&gt;you&lt;/strong&gt;, not just your knowledge. Yes, you should mention that you tick off the main requirements for the job, but you are not going to be able to compete with someone with more experience on a purely technical level. You may as well acknowledge this, because you can bet the employer will already be thinking it. You have to argue that your drive, ability to learn and other personal attributes are what set &lt;em&gt;you&lt;/em&gt; apart and will add more value to the company.&lt;/li&gt;
&lt;li&gt;Be &lt;strong&gt;real and honest&lt;/strong&gt;. You are asking the employer to take a punt on someone with no professional experience - it's not unusual in the world of development, but it's still a big ask. Your letter really needs to get across your genuine enthusiasm for coding, and hopefully remind the employer of when they were first starting out. Just using lots of buzzwords and jargon won't cut it. You need to get your story into their head.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Other websites
&lt;/h4&gt;

&lt;p&gt;Since you have been creating personal projects, you should have a GitHub account set up so that employers can see the code. Ideally, the code will be clean and tidy and the commits will have sensible descriptions.&lt;/p&gt;

&lt;p&gt;As for social media, at a minimum you should be on LinkedIn as this will expose you to some opportunities, though not all good quality ones by any means. The setup is pretty simple - add the info from your CV, add a slightly longer work history if you want, and make sure to check the option for showing recruiters you're open to work.&lt;/p&gt;

&lt;p&gt;Other social media is optional but may be useful. Yes, building a following on a site like Twitter takes time and effort, but just being on there, making some connections and following some good people may still expose you to opportunities and useful information. Many people on there are doing the &lt;a href="https://www.100daysofcode.com/"&gt;#100DaysOfCode&lt;/a&gt; challenge so you may find it useful to do that or follow some people who are.&lt;/p&gt;

&lt;h4&gt;
  
  
  Commercial experience
&lt;/h4&gt;

&lt;p&gt;Some of you may wonder if you should take an internship of some kind to gain extra experience to bolster your application for a full-time job. I'm not going to say don't do this, especially if the opportunity presents itself to you, but I do think you should focus your effort on getting a full-time job straight away, since it &lt;em&gt;is&lt;/em&gt; possible.&lt;/p&gt;

&lt;p&gt;The position you start off with will affect how employers see you, and if you start off at a very low level, it might be quite difficult to advance quickly to a higher level. Focusing all your efforts on building very in-demand skills instead might take a bit longer, but you improve your chances of getting a good-quality job at the end of it.&lt;/p&gt;

&lt;p&gt;That said, if freelancing is something you are interested in and you have an opportunity to do it, getting some &lt;em&gt;paid&lt;/em&gt; development work under your belt will certainly improve your standing in the eyes of an employer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interviews
&lt;/h3&gt;

&lt;p&gt;The interview process is different for each company, but there are some key things you'll definitely need to do and prepare.&lt;/p&gt;

&lt;h4&gt;
  
  
  Coding exercises
&lt;/h4&gt;

&lt;p&gt;You may be asked to build something according to a set of instructions and then submit the code. This could be later on in the interview process but in my experience it was quite early on, to weed out candidates. &lt;/p&gt;

&lt;p&gt;On paper, this is great for you because you have the chance to prove your skills, despite your lack of professional experience. In reality, you may not actually have the time to do the assignment to the best of your ability, or the requirements may be unreasonable. &lt;/p&gt;

&lt;p&gt;Nevertheless, I suggest you treat these exercises as good experience at professional development tasks and give it your best shot. Submit it unfinished if you have to, and always ask for feedback (though you might not get it). With any luck, you'll get a task you can complete well in time, and pass this stage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Company research
&lt;/h4&gt;

&lt;p&gt;You will have done a little of this already, but obviously, you need to do some more before interview. Look at the company website, social media, linkedIn if possible. You know the drill.&lt;/p&gt;

&lt;h4&gt;
  
  
  Preparing answers
&lt;/h4&gt;

&lt;p&gt;The &lt;em&gt;main part&lt;/em&gt; of your interview preparation should be preparing answers to general interview questions about your skills and experience. How you communicate in general is so much more important than whether you know the answer to some technical trivia.&lt;/p&gt;

&lt;h5&gt;
  
  
  On paper
&lt;/h5&gt;

&lt;p&gt;I like to get my talking points for a potential interview question down on paper first.&lt;/p&gt;

&lt;p&gt;You probably want to start by preparing some raw material that might be useful for a variety of questions. For example, the story of the main application or website that you worked on - what was the task, what were the specific actions that you took, what was the result, plus any lessons learned.&lt;/p&gt;

&lt;p&gt;You probably also want to look at common questions and make sure you have something for it. So you could cover all the main topics likely to come up, and allocate specific examples and talking points to them. This also ensures you don't end up talking about the same example over and over.&lt;/p&gt;

&lt;p&gt;Topics that might come up are things like communication, teamworking, working under pressure and time management. Remember these 'soft' skills are still important for dev jobs and you need to be able to talk about them.&lt;/p&gt;

&lt;h5&gt;
  
  
  Out loud
&lt;/h5&gt;

&lt;p&gt;This is really useful and I suspect a lot of people overlook it: you should practise actually saying the stuff you've prepared. First of all, because you need to make sure you actually remember it and don't end up rambling in interview, but also, you need to make sure it comes across well - your body language as well as your words. Saying answers you've prepared that promote your positive qualities probably doesn't come naturally to you, so you need to practise.&lt;/p&gt;

&lt;p&gt;While practising alone or with someone you know (or better, don't know very well) is good, I find it really helpful to record myself practising on my laptop, so I can watch it back and see &lt;em&gt;exactly&lt;/em&gt; what impression the employer will get of me. This is definitely uncomfortable, but I find it helps me identify lots of things I can improve on.&lt;/p&gt;

&lt;h4&gt;
  
  
  Preparing questions
&lt;/h4&gt;

&lt;p&gt;There is &lt;em&gt;no easier thing&lt;/em&gt; you can do to improve your performance at interview than asking lots of questions. It will show that you are enthusiastic, that you understand and are interested in the company, and you are thorough and focused on details. So once you've done your company research, jot down lots of questions.&lt;/p&gt;

&lt;p&gt;You can get a lot of inspiration for this online. Asking about the tech is definitely worthwhile, and the opportunities for your development. There are also plenty of things you can ask about the company values, practices and strategy.&lt;/p&gt;

&lt;p&gt;Be genuine with this - if you are going to start your dev career with this company, you do need to make sure they are a good fit and will support you and help you grow - otherwise you are hurting your long-term potential for short-term gain.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Preparing for technical questions&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Full disclosure - in the four proper interviews I did before getting my first dev job, I wasn't really asked any 'quiz' or 'whiteboarding' questions, as such. Yeah, I got a bit lucky.&lt;/p&gt;

&lt;p&gt;There is plenty of material online to help you prepare for these questions. But I think the best preparation is actually knowing your stuff by just coding regularly, reading around the subject and trying to improve as a programmer. &lt;/p&gt;

&lt;p&gt;Yes, you may gain a short-term advantage by practising specific algorithm exercises and looking up commonly asked technical questions, but I still think your &lt;em&gt;main&lt;/em&gt; focus as a new developer should be learning in the context of building something, rather than in the abstract.&lt;/p&gt;

&lt;h4&gt;
  
  
  The interview itself
&lt;/h4&gt;

&lt;p&gt;There are 101 interview tips that people give, but let's focus on a few key things.&lt;/p&gt;

&lt;h5&gt;
  
  
  Confidence
&lt;/h5&gt;

&lt;p&gt;Confidence is so crucial. The employer is really looking for someone that tells them with their tone and body language, "Yes, I could definitely do this job well, you don't need to worry about me". How do you get this confidence if you don't naturally feel that way?&lt;/p&gt;

&lt;p&gt;Firstly, remind yourself of your positive traits. The things you've overcome. If you're coming into development from an unrelated field and stuck with it, then you've got a lot of things going for you and a lot of reasons to feel confident.&lt;/p&gt;

&lt;p&gt;Secondly, imagine that you're going to get the job. If you don't believe that can happen, you probably shouldn't be going for the interview. Then keep that frame of mind throughout the interview - think of the interview almost like a formality before you will be given the job (without being arrogant, obviously).&lt;/p&gt;

&lt;h5&gt;
  
  
  Positivity
&lt;/h5&gt;

&lt;p&gt;This is also crucial - employers want someone who will contribute positively to the team and relishes challenges. I find the above trick - imaging you're going to get the job - works really well for this too, because it allows your genuine excitement about the job to trump your nerves about the interview. &lt;/p&gt;

&lt;p&gt;Also remember that you can learn anything. Whatever doubts you have about your ability, whatever tough questions you might be asked, you have a safety net, which is that with a positive attitude, you could learn whatever you need to know, even if you don't know it right now. And that is more valuable to most employers than someone who knows quite a lot but seems difficult to work with.&lt;/p&gt;

&lt;h5&gt;
  
  
  Salesmanship
&lt;/h5&gt;

&lt;p&gt;At the end of the day, the interview is an exercise in persuasion. There's no scope for being modest or reticent. Drive the key points home. Add an extra sentence at the end of your examples that highlights how your unique strengths were crucial.&lt;/p&gt;

&lt;p&gt;The best opportunity for salesmanship is the beginning of the interview, especially when a 'tell us about yourself' style question is asked. This is your chance to highlight your &lt;em&gt;key selling points.&lt;/em&gt; Have something prepared that you know by heart. First impressions are very important. Nail it, and you'll set yourself up for success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factor 3: Number of applications 🧮
&lt;/h2&gt;

&lt;p&gt;Now you have the technical skills, and you know how to impress employers. What next? &lt;/p&gt;

&lt;p&gt;The only remaining variable at this point is how many shots you take. In general, more applications = greater chance of success. &lt;em&gt;But,&lt;/em&gt; you have a problem. Applications take time, and it's not as if you can't also still improve your technical and soft skills at this point. Therefore, you need to prioritise your applications and give the ones you do make the greatest chance of success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good quality jobs
&lt;/h3&gt;

&lt;p&gt;You should already have a narrow idea of the job you're looking for, as discussed above. You also want to make sure that the prospective job is worth your time. &lt;/p&gt;

&lt;p&gt;Many developer job listings come through recruitment agencies, and they barely even tell you anything about the job. My advice is don't waste your time on these. If you don't know what you're applying to, you can't make a good application. Personally, I found that Glassdoor Jobs and LinkedIn Jobs were good sites for better quality job adverts.&lt;/p&gt;

&lt;p&gt;Find a job advert that you can apply to directly and has a clear, relatively short list of requirements where it sounds like the company knows what they are talking about. Ideally, they sound like they have a good company ethos or even specify that self-taught developers are welcome. You want to spend a lot of time on this application and make sure it's very personalised and as good as it can be.&lt;/p&gt;

&lt;p&gt;If you find the job advert on a third-party website, see if the job is advertised on the company's site and apply there instead, ideally via an email address. As a general rule of thumb, the more direct to the company your application is, the better. &lt;/p&gt;

&lt;p&gt;Of course, most job adverts won't be ideal. Sometimes you have to play the numbers game with jobs that don't seem quite as promising - they might actually turn out to be good opportunities once you get further along in the process. And even if you don't think you want the job, you should never turn down interview process experience at this stage in your development career - the practise will help you get the job you &lt;em&gt;do&lt;/em&gt; want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Following up
&lt;/h3&gt;

&lt;p&gt;The advantage of applying very directly to the company is that you can follow up. Following up is key. An application doesn't count for much if it is ignored. But don't take it personally. Often you just need to give the employer a nudge.&lt;/p&gt;

&lt;p&gt;If you can find the email address for the company's HR department or general enquiries, follow up your application, say a week later, asking if they received it and re-emphasising how keen you are on the opportunity. If you still get no reply, there is no harm in trying again after another week or so has passed. &lt;/p&gt;

&lt;p&gt;Personally, I only got my current job because I followed up on my application submission with an email. If you don't ask, you don't get, and if you don't get, ask again!&lt;/p&gt;

&lt;h3&gt;
  
  
  Networking
&lt;/h3&gt;

&lt;p&gt;Using your network is a great way to hear about good quality jobs, and being referred for a job by someone else is a great way to ensure your application isn't ignored.&lt;/p&gt;

&lt;p&gt;Most of us aren't very comfortable with networking, but since it can help you get a job, you should give it your best shot. At the most basic level, it just means letting your family and friends, or really just as many people as possible, know that you are looking for a specific type of position.&lt;/p&gt;

&lt;p&gt;You should also be able to find various tech events and meetups in your area (less so during the pandemic, but there should be some online events at least). These can be useful just for your general knowledge of tech and the tech industry, but with the added bonus of making connections with people. The worst that can happen is you have wasted an hour or so.&lt;/p&gt;

&lt;p&gt;Also try to make the most of sites like LinkedIn and Twitter for making connections - you never know how it might pay off, so it's worth putting a bit of work in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The obstacles 🌩️
&lt;/h2&gt;

&lt;p&gt;You should know now what you need to do to get your first developer job. But every journey has obstacles. You should be prepared for the long haul.&lt;/p&gt;

&lt;p&gt;Articles like this one lay things out in a straightforward way, but the journey of learning to code is rarely straightforward and linear. Inefficiency is inevitable, especially if you are completely self-taught. You'll sometimes try to learn something at the wrong time and not succeed. You'll 'waste' time on silly mistakes or trying to get something set up that should have been simple. You'll seem to 'fail' countless times and probably feel 'not cut out for this'.&lt;/p&gt;

&lt;p&gt;I can't tell you what other global or personal calamities or inconveniences might befall you along your journey. You probably won't have any control over them, and you'll almost certainly experience certain 'negative' emotions in response. &lt;/p&gt;

&lt;p&gt;Luckily, there is usually something you can do about your internal world. You can train your mindset and responses to the emotional challenges of a big task like this one. The key here is that you've made a &lt;em&gt;commitment&lt;/em&gt; to achieving the goal, and to continuing with the actions you need to do &lt;em&gt;until&lt;/em&gt; you succeed, whenever that may be. Your secret weapons: vision, habit and persistence, can see you through.&lt;/p&gt;

&lt;p&gt;Of course, it's much easier to give up and say 'I'm no good'. It's your brain's defence mechanism against having to do hard and challenging things. But there's no use in letting one bad day turn into two. You have to get up the next day and try again. Because eventually you'll see that "I'm no good" was never the reality of the situation. The reality was: "this is a &lt;em&gt;learning process&lt;/em&gt;".&lt;/p&gt;

&lt;h3&gt;
  
  
  Overwhelm and stress
&lt;/h3&gt;

&lt;p&gt;Programming for modern computers dates back to the 1950s and the technology has developed and changed at breakneck speed since then. Even in the field of web development, which is under 30 years old, enough technology has developed that you could spend a lifetime learning it.&lt;/p&gt;

&lt;p&gt;The fact that most of the information (and misinformation) on this, plus millions of people's thoughts and opinions on it, is all on the web, unfiltered, for you to find with a simple google search, can be just as much a curse as a blessing. &lt;/p&gt;

&lt;p&gt;You will encounter more information than you've ever found on a topic before, and more topics than you ever imagined there would be. It's natural to be daunted by the sheer amount of information, and the content of it, especially when much of it is aimed at more experienced developers and uses a lot of terminology you don't understand.&lt;/p&gt;

&lt;p&gt;Combine this with the pressure and difficulties of building new habits, job-seeking, the interview process and any time and financial pressures you have, and you have a recipe for potential stress, overwhelm and burnout.&lt;/p&gt;

&lt;p&gt;The best thing you can do is just try to look after yourself, listen to your needs, take breaks, keep doing things you like, try to stay healthy, and exercise. Not ground-breaking advice, but sensible nonetheless. You will get to the end of the path in your own time, and it will be worth it.&lt;/p&gt;

&lt;p&gt;I can also give you a few words of comfort as you start out on your journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will find good teachers and resources that explain things in terms you can understand, and make you feel at home in the world of development. You will also find friendly and welcoming people in the development community that want to help and mentor you, if you look for them.&lt;/li&gt;
&lt;li&gt;If you accept that there will always be a vast amount of things that you don't know in development, but find your own corners of knowledge that you can master and feel comfortable in, you'll be happier.&lt;/li&gt;
&lt;li&gt;When you do finally find yourself in the right developer job, a lot of the pressure will be relieved, and you'll be able to enjoy the fruits of your labour, safe in the knowledge that despite all the obstacles, you finally made it!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, and feel free to contact me here or via Twitter if you have a question about this that I haven't covered here 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;Some of the tips on habit are derived from information in &lt;em&gt;The Power of Habit&lt;/em&gt; by Charles Duhigg (Random House, 2012) and &lt;em&gt;The Chimp Paradox&lt;/em&gt; by Prof Steve Peters (Vermilion, 2012).&lt;/p&gt;

&lt;p&gt;The idea that you lose willpower as the day goes on is known as &lt;em&gt;ego depletion&lt;/em&gt; and various studies have shown this effect, though the exact causes and nature of the effect are still up for debate. This article provides a good overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.verywellmind.com/ego-depletion-4175496"&gt;What Is Ego Depletion? - verywellmind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The information on learning science comes from the book &lt;em&gt;How We Learn&lt;/em&gt; by Benedict Carey (Macmillan, 2014). But I've included some online articles on the relevant topics here if you want to explore the ideas further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.psychologytoday.com/gb/blog/all-about-addiction/201105/desirable-difficulties-in-the-classroom"&gt;Desirable Difficulties in the Classroom - Psychology Today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Desirable_difficulty"&gt;Desirable difficulty - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learningsolutionsmag.com/articles/2168/forgetting-helps-you-remember-why-spaced-learning-works"&gt;Forgetting Helps You Remember: Why Spaced Learning Works - Learning Solutions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.scientificamerican.com/article/the-interleaving-effect-mixing-it-up-boosts-learning/"&gt;The Interleaving Effect: Mixing It Up Boosts Learning - Scientific American&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>career</category>
      <category>development</category>
    </item>
    <item>
      <title>Properly Understanding the DOM</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Sat, 12 Dec 2020 11:12:39 +0000</pubDate>
      <link>https://forem.com/joshcarvel/properly-understanding-the-dom-2cg0</link>
      <guid>https://forem.com/joshcarvel/properly-understanding-the-dom-2cg0</guid>
      <description>&lt;h2&gt;
  
  
  Intro 🧰
&lt;/h2&gt;

&lt;p&gt;If you're a front-end developer, you've probably heard of the DOM, or used some DOM methods in JavaScript. However, you may not know exactly what it is, or how it works.&lt;/p&gt;

&lt;p&gt;This article will give you a solid &lt;em&gt;understanding&lt;/em&gt; of the DOM and how it fits in with the rendering of webpages on the screen. Along the way, we'll cover some crucial concepts to do with JavaScript objects, the browser and rendering. This will help develop your expertise in web development and make you more productive with the tools that the DOM provides, even if you are using a JavaScript library or framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Some familiarity with HTML, CSS and JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The browser 💻
&lt;/h2&gt;

&lt;p&gt;Firstly, we need to understand the web browser on your device a little better. In this article I'll refer to three core components of browsers.&lt;/p&gt;

&lt;p&gt;The first is the &lt;strong&gt;rendering engine&lt;/strong&gt; (also called the browser engine), which reads HTML and CSS files and &lt;strong&gt;renders&lt;/strong&gt; (outputs) the content on the screen. This is the component that creates the DOM! It can actually be used outside the browser, for example email clients use a rendering engine to display HTML email. You may have heard of the rendering engines used in popular browsers - &lt;em&gt;Blink&lt;/em&gt; (Chromium browsers, i.e. Chrome, recent versions of Microsoft Edge and many more), &lt;em&gt;Gecko&lt;/em&gt; (Firefox) and &lt;em&gt;Webkit&lt;/em&gt; (Safari).&lt;/p&gt;

&lt;p&gt;The second component is the &lt;strong&gt;JavaScript engine&lt;/strong&gt;, which reads and runs any JavaScript files given to it. Again, this is a standalone component that can be run outside the browser. The most popular one is Google's &lt;em&gt;V8&lt;/em&gt;, used in Chromium browsers and by NodeJS/Deno. Firefox uses &lt;em&gt;SpiderMonkey&lt;/em&gt; and Safari's is called &lt;em&gt;JavaScriptCore&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The third is the &lt;strong&gt;JavaScript runtime environment.&lt;/strong&gt; This is some code that allows the JavaScript engine to access features relevant to the &lt;em&gt;environment&lt;/em&gt; it is running in. So in a web browser, it provides functionality specific to the browser, such as interacting with the DOM. NodeJS, for comparison, provides a different runtime environment for the JavaScript engine that is specific to non-browser environments such as a server or the command line.&lt;/p&gt;

&lt;p&gt;These components work together inside your browser to produce webpages. They tend to be written mainly in the programming language C++.&lt;/p&gt;

&lt;p&gt;The core functionality that browsers provide is, like the web itself, not centralised, but based on certain standards. When referring to the features browsers make available to developers, I'll refer to the Mozilla Developer Network web docs rather than the actual standards, because they are a more accessible guide to the tools available to us and how they are implemented in different browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The global object 🌍
&lt;/h2&gt;

&lt;p&gt;Another thing it's important to understand properly is &lt;em&gt;objects&lt;/em&gt; in JavaScript. In programming, we describe the world with objects - little containers of data that link to other data.&lt;/p&gt;

&lt;p&gt;Let's imagine for a moment we wanted to describe the whole world. That object would have a lot of &lt;em&gt;things&lt;/em&gt; on it, i.e. &lt;strong&gt;properties.&lt;/strong&gt; Things that exist in nature like trees, human inventions like the mobile phone, and things you can do like 'eat cake'. The last one would be a function in JavaScript, and the property is called a &lt;strong&gt;method&lt;/strong&gt; in that case.&lt;/p&gt;

&lt;p&gt;In our example, the world object is the 'place we put all the stuff'. JavaScript also has a place like this, and it's called the &lt;strong&gt;global object.&lt;/strong&gt; Assuming my JavaScript is running in the browser, the global object contains properties and methods related to the browser and the webpage.&lt;/p&gt;

&lt;p&gt;It's quite hard to define what the global browser object actually represents. Your webpage runs in a tab, with unique elements and events happening. A page in another tab is separate, running different JavaScript with its own global object. So we might call the global object the 'tab' object. But you also have access to browser properties, like browser history and storage for example. So what should we call it?&lt;/p&gt;

&lt;p&gt;Well, the browser provides it in a variable called &lt;code&gt;window&lt;/code&gt;. But it doesn't exactly represent a user interface window. It's just a label for the 'place we put all the stuff'. JavaScript makes it easy to access this place - we don't need to specify &lt;code&gt;window&lt;/code&gt; to access the stuff on it, just saying &lt;code&gt;someProperty&lt;/code&gt; is the same as saying &lt;code&gt;window.someProperty&lt;/code&gt; (in most cases).&lt;/p&gt;

&lt;p&gt;The definition of what the browser should provide on the window object has been standardised, using &lt;strong&gt;interfaces.&lt;/strong&gt; This is an object-orientated programming term which refers to the &lt;em&gt;description&lt;/em&gt; of an object, rather than the object itself. Though an interface is generally a point of interaction, here it means the description of an object, because that enables the interaction of objects to happen smoothly, since they know what properties and methods another object has.&lt;/p&gt;

&lt;p&gt;Here's two things we should know about interfaces: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The interface name is written in PascalCase as a convention.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interfaces can take properties and methods from other interfaces, by &lt;em&gt;inheriting&lt;/em&gt; them from an ancestor interface, or getting them from an unrelated interface called a &lt;em&gt;mixin&lt;/em&gt;. We'll see this later.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Web APIs 💬
&lt;/h2&gt;

&lt;p&gt;Here's MDN's documentation on the interface for the window object: &lt;strong&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window" rel="noopener noreferrer"&gt;Window&lt;/a&gt;.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Have a look and you'll see there's quite a lot on there. The functionality the browser gives us to communicate with it is known as &lt;strong&gt;Web APIs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;API stands for application programming interface. In other words, someone wrote an &lt;em&gt;application&lt;/em&gt;, in this case the browser, and they also wrote a set of features and rules so you could &lt;em&gt;interface&lt;/em&gt; (interact) with it using &lt;em&gt;programming&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, let's say you use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" rel="noopener noreferrer"&gt;fetch()&lt;/a&gt; in your JavaScript code to get a resource from the internet. That's not part of the JavaScript language - you couldn't use it in JavaScript not being run by a browser. But in a browser you can use it, because the browser attached the fetch method to the window object when it created it.&lt;/p&gt;

&lt;p&gt;When you call &lt;code&gt;fetch()&lt;/code&gt;, or any other Web API method, you are making use of the runtime environment provided by the browser. The main difference with these methods is that they are &lt;em&gt;asynchronous&lt;/em&gt;, which means they don't necessarily run immediately after the previous command in your JS code - you make a &lt;em&gt;request&lt;/em&gt; for an action, which is queued up and runs when possible. For example in the case of &lt;code&gt;fetch()&lt;/code&gt;, there will be a delay while it gets the requested resource.&lt;/p&gt;

&lt;p&gt;The Web APIs make use of objects with properties and methods, just like the window object. In the fetch API, one of these is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Response" rel="noopener noreferrer"&gt;Response&lt;/a&gt; object. The API defines exactly what the structure of the object should be. &lt;/p&gt;

&lt;p&gt;But we're not going to talk about all the weird and wonderful APIs available to us in the browser: we want to know what the DOM is. There's just one more thing to look at first: a property of the window object called &lt;em&gt;document&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documents and trees 🌲
&lt;/h2&gt;

&lt;p&gt;Just like how the window object is the container for almost all of the 'global' stuff (console, scrollbars, window dimensions etc.) in your browser, the &lt;strong&gt;document&lt;/strong&gt; is a container for the &lt;em&gt;content&lt;/em&gt;, i.e. the webpage itself. It represents what you &lt;em&gt;give&lt;/em&gt; the browser, not what's already there. This can be an HTML, XML or SVG document, but we're just going to talk about HTML.&lt;/p&gt;

&lt;p&gt;You can give your browser a HTML file by asking it to open one stored locally on your device, or you can request to view a website, causing the browser to retrieve the file from that website's server via the internet. The browser's rendering engine (mentioned at the beginning) then does two things: &lt;strong&gt;parse&lt;/strong&gt; the HTML (read the code line by line), then create a &lt;strong&gt;tree&lt;/strong&gt; of elements.&lt;/p&gt;

&lt;p&gt;When I say create a tree, I'm not talking about planting. It's one way of storing data with a programming language, by creating objects that have 'family' relationships between them. These 'family' relationships are the same you create in an HTML document.&lt;/p&gt;

&lt;p&gt;The relationships are defined by &lt;em&gt;edges&lt;/em&gt; (which clearly ought to be called 'branches', but never mind...). The objects at the end of an edge are known as &lt;strong&gt;nodes&lt;/strong&gt;, because this means the place where lines join (it's also the place where a leaf and stem join on a plant, so it's a bit closer to the tree metaphor). But remember, a node is still just a type of object.&lt;/p&gt;

&lt;p&gt;The node at the very top of the tree is called the &lt;strong&gt;root&lt;/strong&gt;. Visually, the structure would be sort of like a tree. What the browser creates is known as a &lt;strong&gt;document tree&lt;/strong&gt;: a node tree where the root node is a document. It stores information about the document in that root node, and each HTML element on the page and any text inside them also has its own node.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj2mhflsga77dvse84xlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj2mhflsga77dvse84xlw.png" alt="A document tree visualised. Birger Eriksson, CC BY-SA 3.0, via Wikimedia Commons (side banner removed)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter the DOM 📄
&lt;/h2&gt;

&lt;p&gt;Let's finally talk about the DOM. &lt;/p&gt;

&lt;p&gt;The DOM, technically, is &lt;em&gt;not&lt;/em&gt; the document tree, i.e. the data structure itself. It's the model that describes how the data should be stored and interacted with. However, you will often hear people saying things like 'manipulating the DOM', which is simpler to say than 'manipulating the document tree'. I'll use DOM in this sense too, for convenience.&lt;/p&gt;

&lt;p&gt;The technical term for it is an 'object model', which means it defines some objects and how they can be manipulated, but we don't need to worry about that. Just know that's what DOM stands for: &lt;strong&gt;Document Object Model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The key thing is that the DOM is one of the browser's Web APIs. We can get information about (read) DOM nodes and change them (write) using JavaScript. We know &lt;em&gt;how&lt;/em&gt; to do this because it's described in the interfaces for the DOM API.&lt;/p&gt;

&lt;p&gt;To be clear, the DOM is a generic API for manipulating documents. There is a specific offshoot for HTML called the &lt;strong&gt;HTML DOM API&lt;/strong&gt; (remember that other types of documents can be modelled by the DOM). But this distinction doesn't really affect us practically.&lt;/p&gt;

&lt;p&gt;We can see the interfaces we need in MDN's documentation on the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model" rel="noopener noreferrer"&gt;DOM&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API" rel="noopener noreferrer"&gt;HTML DOM&lt;/a&gt;. (The 'official' description is currently WHATWG's &lt;a href="https://dom.spec.whatwg.org/" rel="noopener noreferrer"&gt;DOM Living Standard&lt;/a&gt;, and the HTML DOM is defined in WHATWG's &lt;a href="https://html.spec.whatwg.org/multipage/" rel="noopener noreferrer"&gt;HTML Living Standard&lt;/a&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the DOM 👩‍💻
&lt;/h2&gt;

&lt;p&gt;Let's use an example to understand interfaces.&lt;/p&gt;

&lt;p&gt;In my JavaScript (which the browser's rendering engine discovered in my HTML document via the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag, and the browser's JavaScript engine is running with &lt;code&gt;window&lt;/code&gt; as the global object), I have access to the &lt;code&gt;document&lt;/code&gt; object, as discussed.&lt;/p&gt;

&lt;p&gt;It's described by the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document" rel="noopener noreferrer"&gt;Document&lt;/a&gt; interface. On the list of methods, you will see &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector" rel="noopener noreferrer"&gt;Document.querySelector()&lt;/a&gt;. This lets me use CSS selector syntax to get an &lt;strong&gt;element&lt;/strong&gt; from the document - in this case, an HTML element, because our document is HTML.&lt;/p&gt;

&lt;p&gt;Now say I have an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element in my HTML file with an id &lt;code&gt;my-input&lt;/code&gt;. I write the following in my JavaScript:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const input = document.querySelector('#my-input');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When the JavaScript engine parses my code, it will need to work out the value of the input variable. The &lt;code&gt;querySelector()&lt;/code&gt; call triggers the runtime environment to go find the right element (C++ object) in the document tree (provided by the rendering engine), convert it to a JavaScript object, then give it to the JavaScript engine. If it doesn't find one, it returns &lt;code&gt;null&lt;/code&gt;, a primitive value in JavaScript essentially meaning 'no value'.&lt;/p&gt;

&lt;p&gt;In my example, I now have a variable pointing to the element object. Specifically, it's a HTML input element, described by the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement" rel="noopener noreferrer"&gt;HTMLInputElement&lt;/a&gt; interface (part of the HTML DOM). You can see from the properties listed that I can access the value (the text) in the input and read/write it. Pretty useful. &lt;/p&gt;

&lt;p&gt;Now looking at the methods, you'll see things like &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus" rel="noopener noreferrer"&gt;blur()&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus" rel="noopener noreferrer"&gt;focus()&lt;/a&gt;. Very useful too. But look at where they come from - they are &lt;em&gt;inherited&lt;/em&gt; from &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement" rel="noopener noreferrer"&gt;HTMLElement&lt;/a&gt;. My &lt;code&gt;input&lt;/code&gt; is a type of HTMLElement, so it gets properties and methods shared by all HTML elements. &lt;/p&gt;

&lt;p&gt;The inheritance doesn't stop there - HTMLElement is a type of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element" rel="noopener noreferrer"&gt;Element&lt;/a&gt; (now we're back in the generic DOM API). There's some useful stuff there too, like &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute" rel="noopener noreferrer"&gt;setAttribute()&lt;/a&gt;, so I could add, say, a class on my input field in certain circumstances.&lt;/p&gt;

&lt;p&gt;Let's keep moving on up. An element is a type of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;. We know what those are. Element isn't the only type of node - Document is also, of course, a type of Node, since it's the root node of the tree. And we mentioned before that the text inside an element gets its own node, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Text" rel="noopener noreferrer"&gt;Text&lt;/a&gt;, which you can read/write from the node with the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent" rel="noopener noreferrer"&gt;textContent&lt;/a&gt; property.&lt;/p&gt;

&lt;p&gt;Note: we may be confused here because there is also an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText" rel="noopener noreferrer"&gt;HTMLElement.innerText&lt;/a&gt; and an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML" rel="noopener noreferrer"&gt;Element.innerHTML&lt;/a&gt; property. As MDN &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#Differences_from_innerText" rel="noopener noreferrer"&gt;explains&lt;/a&gt;, these properties have poorer performance and &lt;code&gt;innerHTML&lt;/code&gt; can leave you vulnerable to &lt;em&gt;cross-site scripting&lt;/em&gt; (e.g. I get the value from my input and set the &lt;code&gt;innerHTML&lt;/code&gt; of a &lt;code&gt;div&lt;/code&gt; somewhere else to whatever it is - someone could have written a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag with malicious JavaScript code that will be run on my page). So if I just want to add text to an element, &lt;code&gt;textContent&lt;/code&gt; is the better property to use.&lt;/p&gt;

&lt;p&gt;Now we get to the top of our chain of our inheritance - all of these are a type of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget" rel="noopener noreferrer"&gt;EventTarget&lt;/a&gt;. And so is Window. This allows me to add or remove event listeners, which allow me to respond to page &lt;strong&gt;events&lt;/strong&gt; (like clicks) with a JavaScript function.&lt;/p&gt;

&lt;p&gt;One last thing to discuss here: let's say we used &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll" rel="noopener noreferrer"&gt;Document.querySelectorAll()&lt;/a&gt; to get &lt;em&gt;all&lt;/em&gt; inputs of a particular type. Note that it returns a &lt;em&gt;NodeList.&lt;/em&gt; That's annoying, why not a JavaScript array? Well, remember that the DOM isn't part of JavaScript - it's &lt;em&gt;language-independent&lt;/em&gt;. You could use DOM methods in Python, for example. That means working with DOM objects in JavaScript isn't quite like working with any other kind of object.&lt;/p&gt;

&lt;h2&gt;
  
  
  The DOM in DevTools 🔨
&lt;/h2&gt;

&lt;p&gt;Handily, browsers give us some nice tools that help us view and interact with the DOM.&lt;/p&gt;

&lt;p&gt;Here I opened Chrome developer tools on the Google homepage and inspected their festive logo &lt;code&gt;img&lt;/code&gt; element:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9wmk9feuqe606jw9yu50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9wmk9feuqe606jw9yu50.png" alt="The Google logo img element inspected in Chrome devtools Elements tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Elements tab shows us the image tag and its place in the document. It looks like it's just an HTML tag, but it's not. We could see the original HTML by right-clicking the page and selecting 'view page source'. &lt;/p&gt;

&lt;p&gt;In fact, the Elements tab is a visual representation of the DOM, and the elements in it are objects. &lt;/p&gt;

&lt;p&gt;Let's prove this by going to the Console tab. If we enter &lt;code&gt;$0&lt;/code&gt; (the Console shortcut for logging the element currently selected in the Elements tab) this will just show us the same representation. But if I use &lt;code&gt;console.dir&lt;/code&gt; I can see the object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3stzbmm7cgi8a3uw9kbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3stzbmm7cgi8a3uw9kbc.png" alt="The Google logo img element inspected in Chrome devtools console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can see all the object's properties, including those inherited properties.&lt;/p&gt;

&lt;p&gt;In JavaScript, the object an object inherits from is called its &lt;strong&gt;prototype&lt;/strong&gt;, i.e. the thing you base something else on. Our image element inherits properties and methods from its prototype, 'HTMLImageElement', which in turn inherits from its prototype, 'HTMLElement', and so on. This is a &lt;strong&gt;prototype chain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We can see the prototype object by expanding the &lt;code&gt;__proto__&lt;/code&gt; property. If we kept following the chain up we'd end up at &lt;code&gt;Object&lt;/code&gt;, which is the object that contains the properties and methods &lt;em&gt;all&lt;/em&gt; JavaScript objects inherit. This is just for demonstration - you won't need to do this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpfk50zdd484fi5wk03xn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpfk50zdd484fi5wk03xn.png" alt="The Google logo img element __proto__ object inspected in Chrome devtools console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of these objects in the chain, except the actual image element, already existed on the window object of the JavaScript engine. If you did &lt;code&gt;console.log(window)&lt;/code&gt;  on a blank HTML page you could still find them. When I accessed the logo &lt;code&gt;img&lt;/code&gt; element using the DOM and it became a JavaScript object, its prototype chain was set with those objects.&lt;/p&gt;

&lt;p&gt;The property values were either provided as attributes in the HTML image tag, set using the DOM API in JavaScript, just known by the browser e.g. properties relating to dimensions, or have remained as default values since the object was created. If you just create a plain image element without any further information, the values are all defaults.&lt;/p&gt;

&lt;p&gt;Hopefully you now have a better idea of what DOM objects are and how to inspect them. If you want to learn more about inspecting the DOM with Chrome devtools, Google provides a guide &lt;a href="https://developers.google.com/web/tools/chrome-devtools/dom" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering 🎨
&lt;/h2&gt;

&lt;p&gt;Now we understand the DOM and how to use it, let’s look more closely at the process of rendering a page, so we can think more carefully about how we use the DOM.&lt;/p&gt;

&lt;p&gt;Any site you visit is essentially an HTML file (the 'document'), with references to other files (HTML, CSS or JavaScript) which are all stored on a server and sent to the browser via the internet. The browser parses the HTML and starts constructing the DOM.&lt;/p&gt;

&lt;p&gt;However, JavaScript can affect the parsing process. If the browser gets to a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;  tag in the HTML, it will pause DOM construction by default while the JavaScript code in the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag is executed, because the JavaScript might alter the HTML content by using the DOM API. &lt;/p&gt;

&lt;p&gt;This is why it's often advised that you put the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag at the &lt;em&gt;bottom&lt;/em&gt; of your HTML, so the HTML can be loaded first. Alternatively, you can change the default behaviour by using the &lt;code&gt;defer&lt;/code&gt; or &lt;code&gt;async&lt;/code&gt; attributes on the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script" rel="noopener noreferrer"&gt;script tag&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The browser also creates a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model" rel="noopener noreferrer"&gt;CSS Object Model&lt;/a&gt; (CSSOM). This is similar to the DOM, but instead of representing your HTML document, it represents your CSS style sheets and their content with interfaces. &lt;/p&gt;

&lt;p&gt;It’s an API, so you &lt;em&gt;could&lt;/em&gt; interact with it to alter your styles, but you are usually better off defining all the styles you will need in your stylesheet first, then if necessary changing what they apply to using the DOM, by altering the class names on your elements (or using the &lt;code&gt;style&lt;/code&gt; attribute on the elements if you prefer).&lt;/p&gt;

&lt;p&gt;To get ready for rendering, the DOM and CSSOM are combined to create another tree, the &lt;strong&gt;render tree&lt;/strong&gt;. Anything that won’t be displayed on the page, e.g. the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; element, is excluded. The render tree contains all the information the browser needs to display the webpage.&lt;/p&gt;

&lt;p&gt;The browser assembles the &lt;strong&gt;layout&lt;/strong&gt; of elements on the page (like doing a pencil sketch before a painting), then &lt;strong&gt;paints&lt;/strong&gt; the elements to the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd39r3tmiw48rn9pwntt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd39r3tmiw48rn9pwntt5.png" alt="A simple visualisation of the rendering process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that if we respond to user interaction on the page by changing the DOM, the browser will have to do some work to re-layout and repaint items on the page. This has a performance cost, and could be what we would call &lt;em&gt;expensive&lt;/em&gt; in performance terms. However, the browser responds to events efficiently as possible, only doing as much re-layout and repainting as necessary. This is explained in &lt;a href="https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#Dynamic_changes" rel="noopener noreferrer"&gt;Tali Garsiel's research on how browsers work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bear that in mind, because there is sometimes a misconception that the reason we have fancy front-end frameworks is that the &lt;em&gt;DOM itself&lt;/em&gt; is slow. That wouldn't make sense - frameworks &lt;em&gt;still have to use the DOM&lt;/em&gt;, so they couldn't possibly make it faster. Really, it's all down to how you &lt;em&gt;use&lt;/em&gt; the DOM.&lt;/p&gt;

&lt;p&gt;Let's look briefly at the history and present of DOM manipulation to understand this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries, frameworks and plain JS 📚
&lt;/h2&gt;

&lt;p&gt;You will often hear about JavaScript &lt;strong&gt;libraries&lt;/strong&gt; and &lt;strong&gt;frameworks&lt;/strong&gt;. A library gives you additional methods written by other developers, and you can call those methods whenever you want. A framework has more control of your application architecture, so &lt;em&gt;it&lt;/em&gt; calls the functions in your code when appropriate, not the other way around.&lt;/p&gt;

&lt;p&gt;For a long time, jQuery was the standard way to write JavaScript. It's a library that was created in 2006 to make DOM manipulation easier at a time when the DOM API was limited and very inconsistently implemented by browsers. It's still used today and some people like using its concise syntax, but its core functionality can now be achieved in modern browsers using plain JavaScript.&lt;/p&gt;

&lt;p&gt;Modern libraries and frameworks don't need to tackle deficiency in the DOM, but they do aim to improve your efficiency and productivity in using it. It's not the sole reason they exist, but it's a big one. &lt;/p&gt;

&lt;p&gt;If you are writing a simple website with limited user interaction, you probably won't run into the efficiency problem, provided you're not doing something very silly performance-wise with your DOM manipulation. But simple sites are not all we have on the web today – web &lt;em&gt;applications&lt;/em&gt; such as Facebook are very common. &lt;/p&gt;

&lt;p&gt;These applications contain dynamic, constantly changing content that heavily rely on user input and pulling new data from the server. JavaScript pulls the strings of these changes and is central to the operation of the application. This is a big departure from what the whole infrastructure of serving webpages to the browser was originally designed for. But the problem is not that lots of changes need to be made, it's how to tell the browser exactly &lt;em&gt;which&lt;/em&gt; bits need to change, so you're not re-rendering more than necessary, and to do so without causing any bugs.&lt;/p&gt;

&lt;p&gt;The core front end libraries and frameworks most used today are React, Angular and Vue.js. These aim to take efficient DOM manipulation off your hands, so there is more emphasis on &lt;em&gt;what&lt;/em&gt; you want the page to look like, not &lt;em&gt;how&lt;/em&gt; this should be achieved. If you want to make web applications professionally, your best bet is to simply pick one of these frameworks and learn it (you don't &lt;em&gt;have&lt;/em&gt; to, but most companies use one of them or one like them).&lt;/p&gt;

&lt;p&gt;If you are making simpler websites or are just curious to learn the DOM API, there are lots of guides to plain JavaScript DOM manipulation, like &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents" rel="noopener noreferrer"&gt;this one by MDN&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Let's recap the key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The DOM is an API provided by browsers, but the term is also often used to refer to the document tree. The document tree is a model of your HTML document created by the browser's rendering engine.&lt;/li&gt;
&lt;li&gt;The browser window is the global object in the browser's JavaScript engine. This gives you access to JavaScript runtime environment functionality, including a JS implementation of the DOM API. The DOM API allows you to interact with document tree objects, which are described by interfaces.&lt;/li&gt;
&lt;li&gt;Front end libraries and frameworks can help improve your productivity with the DOM, but you should be aware of why you are using them to ensure you get the best out of them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and happy DOM manipulation! 🙂 &lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;p&gt;* = particularly recommended for further study&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Browser_engine" rel="noopener noreferrer"&gt;Browser engine - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/JavaScript_engine" rel="noopener noreferrer"&gt;JavaScript engine - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://javascript.info/global-object" rel="noopener noreferrer"&gt;Global object - javascript.info&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window" rel="noopener noreferrer"&gt;Window - MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/API" rel="noopener noreferrer"&gt;API - MDN Glossary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.bitsrc.io/javascript-internals-javascript-engine-run-time-environment-settimeout-web-api-eeed263b1617" rel="noopener noreferrer"&gt;JavaScript Internals: JavaScript engine, Run-time environment &amp;amp; setTimeout Web API - Bits and Pieces (Medium)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Tree_(data_structure)" rel="noopener noreferrer"&gt;Tree (data structure) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/WD-DOM/introduction.html" rel="noopener noreferrer"&gt;What is the Document Object Model? - w3.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;* &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model" rel="noopener noreferrer"&gt;Document Object Model (and related pages) - MDN&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;* &lt;a href="https://www.youtube.com/watch?v=SmE4OwHztCc" rel="noopener noreferrer"&gt;Ryan Seddon: So how does the browser actually render a website | JSConf EU 2015&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/" rel="noopener noreferrer"&gt;How Browsers Work: Behind the scenes of modern web browsers - Tali Garsiel, published at html5rocks.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Document tree image credit: Birger Eriksson, &lt;a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="noopener noreferrer"&gt;CC BY-SA 3.0&lt;/a&gt;, via Wikimedia Commons (side banner removed)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was updated on 24 April 2021, mainly to include mention of the JavaScript runtime environment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Networks, the Internet and the Web Demystified</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Sat, 05 Dec 2020 12:24:40 +0000</pubDate>
      <link>https://forem.com/joshcarvel/networks-the-internet-and-the-web-demystified-37c8</link>
      <guid>https://forem.com/joshcarvel/networks-the-internet-and-the-web-demystified-37c8</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8sma3je7yz8lam3l45o3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8sma3je7yz8lam3l45o3.jpg" alt="Earth seen from space"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro 💡
&lt;/h2&gt;

&lt;p&gt;Computer networking is a confusing topic. So much jargon. So many complicated technologies. As a new developer, it's easy to get overwhelmed by it.&lt;/p&gt;

&lt;p&gt;In this article I'll demystify the fundamentals by tackling them one at a time, in simple language. You'll understand the different types of computer networks, and exactly how the internet and the web work (and if you don't know the difference between those two, this article is &lt;em&gt;definitely&lt;/em&gt; for you!).&lt;/p&gt;

&lt;p&gt;We'll start from the beginning of computer networking. As a developer in the 2020s you might not care about computing in the 1960s, but it's going to help you build up concepts one at a time and not get overwhelmed. It's also a good reminder of the incredible progress we've made, from networking a few huge mainframe computers for government research, to you reading this article on a web browser from anywhere in the world!&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of computing concepts such as bits and operating systems - see my &lt;a href="https://dev.to/joshcarvel/series/9456"&gt;How Computers Work series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The ARPANET 📦
&lt;/h2&gt;

&lt;p&gt;Computer networking began with the Advanced Research Projects Agency (ARPA), an agency of the US Department of Defense, established as part of its efforts in the space race in the 60s. ARPA funded computers at various universities, at a time when computers were rare, large and expensive.&lt;/p&gt;

&lt;p&gt;Within those institutions, there was a system of &lt;strong&gt;timesharing,&lt;/strong&gt; where multiple users could connect to the computer with separate physical &lt;strong&gt;terminals&lt;/strong&gt; containing a monitor, and the computer was powerful enough to serve all the users. Users could share files and even send what could be described as email as long as they were connected to the same computer.&lt;/p&gt;

&lt;p&gt;But the US government wanted ARPA researchers to be able to connect to the computers and allow results to be shared easily. Initially, an ARPA director called Bob Taylor was connected to three separate university computers via three separate terminals. He wanted to access them all from a single terminal, and secured the funding for what became the precursor to the internet, the ARPANET.&lt;/p&gt;

&lt;p&gt;Data would be sent over phone lines, since the infrastructure already existed. However, in a phone call, you intend to speak to each other continuously for a set period, during which a physical line of communication is reserved, and then stop, at which point the line is freed up. Computers, on the other hand, should be able to send messages to any other computer at any time. A Welsh computer scientist called Donald Davies had already considered this and the ARPANET used a system he had devised: &lt;strong&gt;packet-switching.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The user-facing computers on the network, known as &lt;strong&gt;hosts,&lt;/strong&gt; would communicate in short chunks of information known as &lt;strong&gt;packets.&lt;/strong&gt; A long message could be split into multiple packets which could travel down whichever phone line was available. So a single line could be handling packets from various different hosts, one after another. In between all the host computers were reliable, single-purpose computers which directed the traffic. They read the destination address from the packet and passed it on until it got to the destination host. Today we use &lt;strong&gt;routers&lt;/strong&gt; for this.&lt;/p&gt;

&lt;p&gt;The other advantage of this system was that it provided protection from lines going down - packets had many, many ways of getting to their destination. This was important for the US military in the 60s, and the implementation of packet-switching was strongly influenced by the work of Paul Baran, who described a communication system that could survive a nuclear strike!&lt;/p&gt;

&lt;p&gt;The first ARPANET message was sent in 1969 and the network developed throughout the 70s. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Internet 🌐
&lt;/h2&gt;

&lt;p&gt;Packet-switching established the system for sending messages, but ARPANET also needed a set of rules about how to use that system: a &lt;strong&gt;protocol.&lt;/strong&gt; The protocol included that packets would conform to a standard format, with the data to be transmitted, called the &lt;strong&gt;payload,&lt;/strong&gt; plus a &lt;strong&gt;header,&lt;/strong&gt; containing the address it was going to.&lt;/p&gt;

&lt;p&gt;However, from the early 1970s onwards, other computer networks began to emerge that used different protocols. You couldn't send a message from one network to another - the other network wouldn't understand it! This problem eventually led to the development of a way of inter-networking, or 'internetting'. All these networks working together became what we call the &lt;strong&gt;internet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The internet started to really get going in the late 1980s. Cisco Systems began popularising the modern router - a device that could connect your network to other networks. Each network just had to know how to talk to the router, not the computers on the other network. &lt;/p&gt;

&lt;p&gt;There are two important protocols which allow this happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internet Protocol (IP)
&lt;/h3&gt;

&lt;p&gt;This is a fairly straightforward protocol derived from the original ARPANET protocols. It requires that a packet has a header with an &lt;strong&gt;IP address&lt;/strong&gt;, which indicates where it's going. An IP address is a unique sequence of binary digits. Addresses are managed globally by the &lt;strong&gt;Internet Assigned Numbers Authority (IANA)&lt;/strong&gt; and assigned to your device by your internet service provider. It is &lt;em&gt;dynamic&lt;/em&gt; i.e. not permanent, so addresses can be reused when possible. Despite this, in the 1990s the world began to realise it would run out of IP addresses.&lt;/p&gt;

&lt;p&gt;The old system, &lt;em&gt;IPv4&lt;/em&gt;, used a 32-bit number, separated by dots into four 8-bit numbers displayed in their decimal equivalent, e.g. 172.217.7.238. We officially ran out of unique IPv4 addresses in 2019 and this system is very slowly being phased out. &lt;/p&gt;

&lt;p&gt;The new system, &lt;em&gt;IPv6&lt;/em&gt;, uses a 128-bit number, separated by colons into eight 16-bit numbers, displayed in their &lt;em&gt;hexidecimal&lt;/em&gt; equivalent (the base 16 number system, which uses the digits 1-10 plus the characters a-f, so it's shorter to write), e.g. 2001:cdba:0000:0000:0000:0000:3257:9652. This system was chosen for various reasons, but we can also safely say we won't run out, given that it can generate over 340 trillion trillion trillion unique addresses! &lt;/p&gt;

&lt;p&gt;Just type 'my IP address' into google to see your current IP address. &lt;/p&gt;

&lt;h3&gt;
  
  
  Transmission Control Protocol (TCP)
&lt;/h3&gt;

&lt;p&gt;While IP is used by routers, TCP is used by the host computers on either end of the transmission of data - the routers in between don't read the TCP information on the packet.&lt;/p&gt;

&lt;p&gt;A TCP header contains a lot of useful information. It contains a &lt;em&gt;sequence number&lt;/em&gt; which is used to determine the position of the data in the completed message, so if packets arrive out of order, the part of the destination host's operating system that knows how to deal with TCP will reassemble them.&lt;/p&gt;

&lt;p&gt;It also has a system to ensure data is not lost, known as the &lt;strong&gt;TCP handshake&lt;/strong&gt; or &lt;em&gt;three-way handshake&lt;/em&gt;. It uses &lt;em&gt;flags&lt;/em&gt;, i.e. a bit in a certain position in the header which is allocated a specific meaning and set to 1 or 0. In the first transmitted message, a flag referred to as SYN (synchronisation) is set to 1. The receiving host responds with a message with the ACK (acknowledgement) flag set to 1. Then the first host also sends a message with ACK set to 1. &lt;/p&gt;

&lt;p&gt;After three messages, the hosts are confident of a good connection. Ideally, the &lt;em&gt;fourth&lt;/em&gt; packet sent contains some actual data. However, if acknowledgements were not received, attempts will be made to retransmit the data (subject to a maximum number of attempts). Any duplicates received at the destination will be discarded.&lt;/p&gt;

&lt;p&gt;TCP also enables a receiving host's operating system to know what &lt;em&gt;program&lt;/em&gt; the data is meant for. Like a ship arriving at a harbour, TCP packets arrive at &lt;strong&gt;ports.&lt;/strong&gt; This is simply a unique identifying number, and like IP addresses, IANA maintains an official list of ports for specific uses. A TCP packet specifies the number of the destination port as well as the source port it has come from. Note that the combination of an IP address and port is generally referred to as a &lt;strong&gt;socket&lt;/strong&gt; or &lt;em&gt;endpoint&lt;/em&gt; and represents one end of a TCP connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internet protocol suite
&lt;/h3&gt;

&lt;p&gt;TCP and IP, designed by Vint Cerf and Bob Kahn and finalised in 1978, form the basis of what we today call the &lt;strong&gt;Internet protocol suite,&lt;/strong&gt; often referred to simply as &lt;em&gt;TCP/IP,&lt;/em&gt; though it also contains many other protocols. &lt;/p&gt;

&lt;p&gt;One such protocol which is commonly used is &lt;strong&gt;User Datagram Protocol (UDP).&lt;/strong&gt; Invented in 1980, this allowed for messages to be exchanged without the initial handshake, meaning messages are transmitted more quickly, but with greater unreliability. Today it's used by applications such as video chat apps, where speed of transmission is key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of network 🏢
&lt;/h2&gt;

&lt;p&gt;Let's now zoom in to the kinds of networks that were being linked together by the internet.&lt;/p&gt;

&lt;p&gt;There are many different classifications of network, mostly based on their geographical extent. For example, ARPANET was a &lt;strong&gt;Wide Area Network (WAN).&lt;/strong&gt; A small, local network on the other hand, is known as a &lt;strong&gt;Local Area Network (LAN)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;One of the first LANs was established in 1973 at Xerox's research centre, the famous Xerox PARC. At Xerox PARC they used personal computers before most of the rest of the world had even seen one, and a fast, scalable way of connecting them was invented, called &lt;strong&gt;ethernet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every computer on the network had a unique &lt;strong&gt;media access control (MAC) address.&lt;/strong&gt; Packets of data were sent along a cable containing what's called an &lt;strong&gt;ethernet frame,&lt;/strong&gt; which includes a header with the source and destination MAC addresses, and a data payload. The data was passed to all connected computers, but the only intended recipient processed it. &lt;/p&gt;

&lt;p&gt;Only one computer could send a message at one time, otherwise there would be a &lt;em&gt;collision.&lt;/em&gt; If the computers detected the network was busy, they waited for a period of time before attempting retransmission of that data - the period of time was increased exponentially each time the network was busy, which is called &lt;em&gt;exponential backoff.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The configuration of the connections between computers is known as the &lt;strong&gt;network topology.&lt;/strong&gt; The ethernet at Xerox PARC connected computers with a single cable, which is called the &lt;em&gt;bus topology&lt;/em&gt;. Later, it became possible to plug several cables into a device called a &lt;em&gt;hub&lt;/em&gt;, which could relay the signals as if the computers were all connected, but one cable going down wouldn't crash the whole network. Nowadays it is more common to use a &lt;strong&gt;switch&lt;/strong&gt; in place of a hub. A switch learns the MAC addresses of the devices on the network so it only sends data to the computers that need it, allowing multiple communications between different computers to happen at once.&lt;/p&gt;

&lt;p&gt;Using a hub or switch in this way is an example of the &lt;em&gt;star topology&lt;/em&gt; (the hub or switch is the centre and the other cables feed out from it). There are many types of topologies, each with their own pros and cons, but star is the most common these days. For example, your home network probably uses a star topology, with the router as the central point and your devices the points on the star.&lt;/p&gt;

&lt;p&gt;Ethernet spread to many offices in the 80s so users could do things like share files and connect to printers on the network. For this to work, the computers needed a &lt;strong&gt;network interface controller&lt;/strong&gt; (&lt;strong&gt;NIC&lt;/strong&gt;, also known as a &lt;em&gt;network adapter&lt;/em&gt;). These days they are built into motherboards. The operating system of the computer also needed facilities for networking built in - again, this is now standard.&lt;/p&gt;

&lt;p&gt;At this time &lt;strong&gt;servers,&lt;/strong&gt; such as file servers, mail servers and print servers, also came into widespread use in offices. The term &lt;em&gt;server&lt;/em&gt; usually refers to a computer that has the dedicated purpose of providing some service to another computer, known as the &lt;strong&gt;client,&lt;/strong&gt; although it may also refer to server software, which today can run on pretty much any computer. Most servers are dedicated machines that have no monitor, are in constant use and have a specific operating system and hardware optimised for their serving function.&lt;/p&gt;

&lt;p&gt;Having a &lt;em&gt;server-based network&lt;/em&gt; allows a network administrator to manage things like data storage, security and access to files, though it comes with its fair share of expenses. The opposite of a server-based network is a &lt;em&gt;peer-to-peer network.&lt;/em&gt; This means the computers are connected together on an equal footing - there is no administrative control. We could say it's more 'democratic'.&lt;/p&gt;

&lt;p&gt;The ARPANET and early internet were all about peer-to-peer networking, where files could be shared freely. But as businesses adopted networking and security concerns became more apparent, things became more siloed. Files could be restricted and you could set up a &lt;em&gt;firewall&lt;/em&gt; to block certain traffic to your network. Later on, when sites like Napster emerged, peer to peer file sharing went mainstream again, although the market for sharing copyrighted material was quickly shot down by legal challenges. Nowadays, we see new types of peer to peer networks facilitating cryptocurrencies like Bitcoin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modern networking
&lt;/h3&gt;

&lt;p&gt;Internet connections originally used phonelines in the traditional way with a &lt;em&gt;dial-up connection&lt;/em&gt; that hogged the phoneline and was pretty slow for data transfer. They were used with a &lt;strong&gt;modem&lt;/strong&gt; that &lt;em&gt;modulated&lt;/em&gt; digital data to analogue for the phone line, and &lt;em&gt;demodulated&lt;/em&gt; it back to digital for the computer (hence, &lt;em&gt;mo&lt;/em&gt;-&lt;em&gt;dem&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;In the early 2000s, &lt;strong&gt;broadband&lt;/strong&gt; came into widespread use. It divided the phone line into several channels, allowing more data to travel down the lines (greater &lt;em&gt;bandwidth&lt;/em&gt;) and enabling multiple connections at once, specifically using &lt;strong&gt;digital subscriber line (DSL)&lt;/strong&gt; technology. This was usually &lt;em&gt;asymmetric&lt;/em&gt; (&lt;strong&gt;ADSL&lt;/strong&gt;), which is optimised for downloading information more than uploading, which suits how most people use it and reduces the scope for interference on the line.&lt;/p&gt;

&lt;p&gt;However, most of the internet is now connected with fiber-optic cables. They go all over the world and under the oceans, carrying digital information at incredible speeds using light. ASDL is still often used, but only at the last leg of connection to the user (the 'last mile'), where it is less cost-effective to install fiber-optic cables. In either case, some kind of modem is used to translate the signal, but this is often built into the same device as the router. &lt;/p&gt;

&lt;p&gt;The router allows access for multiple devices on the local network, using the MAC addresses of the devices - assigned by the device manufacturer - to identify where to send the data. Most routers can send data wirelessly over short distances using radio waves, i.e. &lt;strong&gt;Wi-Fi.&lt;/strong&gt; The other devices have a wireless NIC built in so they can understand the signals. Ethernet can still be used and is often used by businesses for a fast, reliable connection.&lt;/p&gt;

&lt;p&gt;Outside of local networks, we can also get wireless internet access from our mobile network operator. The same towers that connect our devices for calls are used to send and receive data to and from our devices using radio waves, and are connected to the internet via cables. This is quite cost-effective to implement and has been improved over a number of 'generations' of technology, the latest being 5G (fifth generation).&lt;/p&gt;

&lt;p&gt;But there's one development that has impacted us more than any other, and it's what you're reading this article on right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The World Wide Web 🕸️
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;World Wide Web&lt;/strong&gt; and internet are often conflated, but as we know, the internet came first.&lt;/p&gt;

&lt;p&gt;The idea for the web originated with the idea of &lt;strong&gt;hypertext.&lt;/strong&gt; Inspirations for it date back to the 40s and the term was coined in the 60s. 'Hyper' comes from the Greek for 'beyond', and the idea was having text with &lt;em&gt;hyperlinks&lt;/em&gt; that take you beyond that text, to related information. Some systems were developed to implement this on computers, including one written by scientist Tim Berners-Lee while working at CERN in 1980. It was a web of sorts, but certainly not world-wide: the information was accessible to just him.&lt;/p&gt;

&lt;p&gt;Over the course of the 1980s, CERN became the largest &lt;em&gt;node&lt;/em&gt; (point of connection) on the internet. Berners-Lee came up with the big idea that a hypertext system could exist on the internet, so &lt;em&gt;everyone&lt;/em&gt; could access the same information from their own computer, without having to log into another system or ask someone else for it.&lt;/p&gt;

&lt;p&gt;In 1991, Berners-Lee wrote the world's first &lt;strong&gt;web server.&lt;/strong&gt; A web server is a server that serves files known as &lt;strong&gt;webpages.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's look at the technologies that make browsing webpages possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domains
&lt;/h3&gt;

&lt;p&gt;Since the birth of the internet, there have been &lt;strong&gt;domain names.&lt;/strong&gt; A &lt;strong&gt;domain&lt;/strong&gt; represents a computer or group of computers on the internet, and domain names provide a more user-friendly description of a location on the internet. Since 1985 there has been a dedicated system to match domain names to IP addresses, called the &lt;strong&gt;Domain Name System (DNS).&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This means a request for 'google.com' will go to a DNS server, and that server may pass the request on to another DNS server, until one that actually knows the address for that domain name is found, and that server will pass the request to the google server that has the page. In this example, there are many servers across the world that can serve you 'google.com', even though the domain name is the same. Once your computer has the IP address, it will remember (cache) it for a while, so it doesn't have to ask again.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;top-level domain&lt;/em&gt; is at the end of the domain name, for example .com (commercial), or .org (organisation). Management of these is overseen by IANA. Any name preceding this last dot is a &lt;em&gt;subdomain.&lt;/em&gt; So 'google' is a subdomain of '.com', and in 'play.google.com' (Google play store), 'play' is a subdomain of google. &lt;/p&gt;

&lt;p&gt;'www' is in fact just another subdomain, originally just added for extra clarity. It became a standard by accident. You don't have to include that subdomain when you register your domain name, and you can &lt;em&gt;redirect&lt;/em&gt; requests using 'www' to the domain without 'www'. Because the web is so dominant now, people generally avoid specifying 'www', and browsers usually add it automatically in the address bar.&lt;/p&gt;

&lt;p&gt;As you know, we refer to the collection of webpages at a particular domain name as a &lt;strong&gt;website&lt;/strong&gt;. A website is just a hierarchical collection of files (the webpages) on the web server. The server serves the homepage when no specific page is requested. To access a different page, the file path identifying that directory on the server is added after the domain name.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP
&lt;/h3&gt;

&lt;p&gt;Domains provided the infrastructure to make the web possible, but to specify the rules of requesting webpages, Berners-Lee needed a new protocol. He and his team came up with &lt;strong&gt;Hypertext Transfer Protocol (HTTP)&lt;/strong&gt;. Today, it works as follows.&lt;/p&gt;

&lt;p&gt;First, the client and server establish a reliable connection using the TCP protocol. Then, the client makes a specific type of HTTP request. For example, a &lt;strong&gt;GET&lt;/strong&gt; request, which requests a page (originally this was the only request available). The client can specify &lt;em&gt;headers&lt;/em&gt; with additional information, one of which must be the location of the resource, which looks like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Host: google.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The server then sends a response which includes a &lt;strong&gt;status code,&lt;/strong&gt; a number from one of the following groupings (only a handful of numbers in each group are used as status codes):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Informational responses (100–199)&lt;/li&gt;
&lt;li&gt;Successful responses (200–299)&lt;/li&gt;
&lt;li&gt;Redirects (300–399)&lt;/li&gt;
&lt;li&gt;Client errors (400–499)&lt;/li&gt;
&lt;li&gt;Server errors (500–599)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most common status codes you will have seen as a user are &lt;code&gt;404: Not Found&lt;/code&gt; (the resource just isn't on the server) and &lt;code&gt;500: Internal Server Error&lt;/code&gt; (an error occurred on the server). You are probably less familiar with &lt;code&gt;200: OK&lt;/code&gt;, because this means the request was successful, and in the browser you will see the webpage that was returned in the &lt;em&gt;body&lt;/em&gt; of the server's response, rather than a status code.&lt;/p&gt;

&lt;p&gt;There are also other types of request available, such as &lt;strong&gt;POST&lt;/strong&gt;, so the client can send data the user has inputted in a form to the server. For example, if you request to log into a website, the browser sends a POST request to the web server with your credentials. If your credentials are valid and the web server uses &lt;strong&gt;cookies&lt;/strong&gt; as authentication, its response would contain the &lt;code&gt;Set-Cookie&lt;/code&gt; header with an access &lt;em&gt;token&lt;/em&gt;. The browser stores the token and sends it in the &lt;code&gt;Cookie&lt;/code&gt; header on future requests so the server knows you are logged in. &lt;/p&gt;

&lt;h4&gt;
  
  
  HTTPS
&lt;/h4&gt;

&lt;p&gt;As the web grew it quickly (within a few years) became apparent that greater security was needed. Simply requesting webpages isn't much of a problem, but sending user data is. One such problem is known as a &lt;em&gt;man-in-the-middle-attack&lt;/em&gt; - in other words, someone could intercept communication between you and the web server without you knowing.&lt;/p&gt;

&lt;p&gt;So &lt;strong&gt;HTTPS (Hypertext Transfer Protocol Secure)&lt;/strong&gt; was developed to accommodate the use of &lt;strong&gt;encryption.&lt;/strong&gt; Encryption is where data is encoded into a scrambled form known as a &lt;em&gt;ciphertext.&lt;/em&gt; An &lt;em&gt;encryption key&lt;/em&gt; is a string of digits computers can apply in a mathematical way to decipher the message again.&lt;/p&gt;

&lt;p&gt;The client and server cannot make the encryption key public, as it would defeat the point. However, they do need to know what key the other is using. This is achieved with mathematics, by combining a &lt;em&gt;public key&lt;/em&gt; with a &lt;em&gt;private key&lt;/em&gt; in such a way that both client and server generate the same number to use as a key, and use it privately to decipher the encrypted messages they send to each other. Anyone trying to intercept the messages can't reverse-engineer the process using the publicly available variables, because they are missing one variable: a private key. (For further explanation see the Computerphile video in Sources below).&lt;/p&gt;

&lt;p&gt;The encryption protocol used by HTTPS is now &lt;strong&gt;Transport Layer Security (TLS)&lt;/strong&gt; but you have more likely heard of its predecessor &lt;strong&gt;Secure Sockets Layer (SSL).&lt;/strong&gt; A &lt;em&gt;TLS certificate&lt;/em&gt;, still widely referred to as a SSL certificate, certifies the ownership of a public key, indicating to the client that HTTPS can be used (browsers usually display a padlock icon in the address bar to indicate this). All websites these days are advised to have one, and Google ranks sites that do more favourably in its search algorithms. &lt;/p&gt;

&lt;h3&gt;
  
  
  URLs
&lt;/h3&gt;

&lt;p&gt;We haven't yet mentioned the &lt;strong&gt;Uniform Resource Locator (URL).&lt;/strong&gt; This brings together a domain name with a &lt;em&gt;scheme&lt;/em&gt; - a lowercase value indicating what protocol is being used, of which http and https are two possibilities.&lt;/p&gt;

&lt;p&gt;What other types of scheme are there? Well, a common one is &lt;em&gt;ftp&lt;/em&gt;, for &lt;strong&gt;File Transfer Protocol.&lt;/strong&gt; FTP has been around since the early days of the internet and requires you to login to a server to upload or remove files. HTTP was a kind of adaption of FTP to optimise it for web requests. FTP is still used in the context of the web - the author of a website would use it to upload a website to a server, or remove it from one.&lt;/p&gt;

&lt;p&gt;Other schemes you may have seen are &lt;em&gt;mailto&lt;/em&gt;, which allows you to send email from a webpage, or &lt;em&gt;file,&lt;/em&gt; which allows you to open a local file in a browser.&lt;/p&gt;

&lt;p&gt;The scheme is followed by a colon to separate it, and the domain name is prefaced with two forward slashes, which indicates a path to a computer, as opposed to a path to a file on a particular computer (usually a single forward slash).&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML
&lt;/h3&gt;

&lt;p&gt;To enable a webpage to be created, Berners-Lee needed a &lt;strong&gt;markup language.&lt;/strong&gt; A markup language allows the user to provide the computer with text along with annotations that indicate the display and function of that text. When the text is then displayed to the intended user, the annotations are hidden. Berners-Lee wrote his own markup language, based heavily on one in use at CERN at the time, but tailored for the web. It's called &lt;strong&gt;Hypertext Markup Language (HTML)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;HTML provides &lt;strong&gt;elements&lt;/strong&gt; that go on the webpage - headings, paragraph elements, lists and so on. An element is produced by using &lt;strong&gt;tags,&lt;/strong&gt; in most cases by writing an opening tag, followed by the text to display, followed by the closing tag. If I wanted a main heading that read 'My webpage', I would write that element like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;h1&amp;gt;My webpage&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But back in 1991, the star of the show was the &lt;em&gt;anchor&lt;/em&gt; tag, &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; which creates a hyperlink and makes hypertext possible. To tell the page where you want it to go, you have to add an &lt;strong&gt;attribute.&lt;/strong&gt; Each element has a valid set of attributes you can use for more control over how that element is used. The attribute to add a hyperlink is &lt;em&gt;href&lt;/em&gt; (hypertext reference) and is used with the relevant url as the value, like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;a href="https://www.google.com"&amp;gt;Go to google&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the link is to another page on the same site, a &lt;em&gt;relative file path&lt;/em&gt; could be used, e.g.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;a href="/shop.html"&amp;gt;Shop&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Later, form elements would be added which allow other kinds of interactivity.&lt;/p&gt;

&lt;p&gt;Each element has a very plain default display style, and the elements follow each other vertically down the page in the order they were written in the HTML. Originally, these default display styles couldn't be changed, but now they can. However, you can still often see them on older websites or even notice them for a split second on some modern websites before the stylesheets have loaded! 😉&lt;/p&gt;

&lt;h3&gt;
  
  
  Browsers
&lt;/h3&gt;

&lt;p&gt;The final piece of the puzzle was the &lt;strong&gt;web browser&lt;/strong&gt; - a program designed for requesting files from web servers (principally HTML files) and displaying them. Berners-Lee wrote the first browser, but it didn't take long for things to get pretty complicated.&lt;/p&gt;

&lt;p&gt;The technologies that underpin the web are open - that's the whole idea, and the main reason that it went global. In 1994, Berners-Lee founded the &lt;strong&gt;World Wide Web Consortium (W3C)&lt;/strong&gt; to establish some standards for web technologies, such as the HTML specification.&lt;/p&gt;

&lt;p&gt;The problem is, it's up to the companies and organisations that produce browsers to actually &lt;em&gt;implement&lt;/em&gt; the standards, and there's nothing to really stop them from doing their own thing for any technical or business reason. In the early days of the web, websites tended to be designed specifically for one type of browser (and browser version!) because the browsers differed from each other so much. This competition did at least establish the precedent of browsers being free, however.&lt;/p&gt;

&lt;p&gt;By the end of the first 'browser war' in 2001, Microsoft had triumphed over a company called Netscape by establishing Internet Explorer as the dominant browser. Netscape later became the non-profit Mozilla foundation, and they made their browser source code open-source and released it as Firefox in 2004. Firefox is still used today, with a usage share of around 5-10% on desktop browsers.&lt;/p&gt;

&lt;p&gt;Also in 2004, individuals from Mozilla, Opera (another browser provider) and Apple formed, wait for it... the &lt;strong&gt;Web Hypertext Application Technology Working Group&lt;/strong&gt; (&lt;strong&gt;WHATWG&lt;/strong&gt;). WHATWG was born from dissatisfaction with W3C's approach, and it is now instrumental in driving web standards forward. Mozilla also began what is now the &lt;a href="https://developer.mozilla.org/en-US/" rel="noopener noreferrer"&gt;Mozilla Developer Network (MDN) web docs&lt;/a&gt;, a hugely valuable resource for web developers which provides a reliable picture of the various web standards &lt;em&gt;and&lt;/em&gt; their actual implementation by browsers, which these days is, thankfully, a lot more consistent.&lt;/p&gt;

&lt;p&gt;The period since then has seen Google's browser, Chrome (first released in 2008), win the second 'browser war' and rise to huge prominence. Not only does it have around 70% of usage share, almost all other notable browsers besides Firefox and Safari (Apple's browser) use Chromium, the core part of the browser, which is open-source. This includes Microsoft Edge, the successor to Internet Explorer, as of version 79. Google (and Microsoft) are also now part of the WHATWG's Steering Group.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layers 🍰
&lt;/h2&gt;

&lt;p&gt;Before we finish, let's take a step back again.&lt;/p&gt;

&lt;p&gt;Most explanations of computer networking inevitably reference the &lt;strong&gt;Open Systems Interconnection (OSI) model&lt;/strong&gt;. This is a general-purpose concept that defines the different &lt;em&gt;layers&lt;/em&gt; of features or services in a network, and it will help us recap. &lt;/p&gt;

&lt;p&gt;It defines 7 layers that work independently of the other layers. This is helpful because when something goes wrong, you can first narrow the problem down to a specific layer of the network.&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Physical Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one is simple: networks rely on electricity, radio waves and the physical components that carry them to function. All of this makes up the physical layer. &lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Data Link Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This layer covers the connection between two nodes on a network, such as the transmission of data frames linked by two computers via ethernet. Error correction is done at this layer to reduce corruption of data caused by things like interference on the line.&lt;/p&gt;

&lt;p&gt;Technologies at the physical and data link layer are standardised by the Institute of Electrical and Electronics Engineers (IEEE), in the &lt;em&gt;IEEE 802&lt;/em&gt; standards. This is a grouping of standards for things like Ethernet, WiFi, and so on.&lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;Network Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The network layer refers to the forwarding of packets between networks. This is is the layer that routers and the Internet Protocol operate at.&lt;/p&gt;

&lt;p&gt;4. &lt;strong&gt;Transport Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is about the delivery of the data between computers at either end of the connection, and getting data to the right software application. TCP falls under this layer.&lt;/p&gt;

&lt;p&gt;Layers 5 and 6 are the &lt;em&gt;Session Layer&lt;/em&gt; and the &lt;em&gt;Presentation Layer&lt;/em&gt;, but we won't discuss them because they are not that relevant to the Internet Protocol Suite, which predates the OSI model.&lt;/p&gt;

&lt;p&gt;7. &lt;strong&gt;Application Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This refers to the data the user sees and interacts with in an application such as a web browser, and the protocols that are closest to it like HTTP. If you're writing a web application and send an incorrect HTTP request, then the network problem is at the application layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Let's recap the key takeaways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Networks come in many forms and sizes, and are built on layers of technology working together.&lt;/li&gt;
&lt;li&gt;The internet brings different computer networks together and allows a variety of services such as email, file transfer, and of course, the web, to exist.&lt;/li&gt;
&lt;li&gt;The internet and the web were created with the advantages in mind, and the disadvantages were discovered later. We're only now just starting to get a grip on the monumental ways they can affect our lives. That the web will be free, secure and a force for good is far from a given, and achieving it takes a lot of work from people that believe in those ideals.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;What is made of the Web is up to us. You, me, and everyone else — Tim Berners-Lee&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Nerds 2.0.1 - A Brief History of the Internet&lt;/em&gt; - documentary (1998)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Computer_network" rel="noopener noreferrer"&gt;Computer network (and related pages) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLH2l6uzC4UEW0s7-KewFLBC1D0l6XRfye" rel="noopener noreferrer"&gt;Crash Course Computer Science Episodes 28-30&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/ARPANET" rel="noopener noreferrer"&gt;ARPANET - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://theconversation.com/au/topics/how-the-internet-was-born-32844" rel="noopener noreferrer"&gt;How the Internet was born (series) - The Conversation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://archive.nytimes.com/www.nytimes.com/library/tech/99/12/biztech/articles/122099outlook-bobb.html" rel="noopener noreferrer"&gt;An Internet Pioneer Ponders the Next Revolution - New York Times archive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.washingtonpost.com/sf/business/2015/05/30/net-of-insecurity-part-1/" rel="noopener noreferrer"&gt;Net of Insecurity Part 1 - Washington Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Packet_switching" rel="noopener noreferrer"&gt;Packet switching - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.computerhistory.org/timeline/networking-the-web/" rel="noopener noreferrer"&gt;Timeline of Computer History: Networking and the web - Computer History Museum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Router_(computing)" rel="noopener noreferrer"&gt;Router (computing) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Internet_protocol_suite" rel="noopener noreferrer"&gt;Internet protocol suite (and related pages) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.steves-internet-guide.com/tcpip-ports-sockets/" rel="noopener noreferrer"&gt;TCP/IP Ports and Sockets Explained - Steve's Internet Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/" rel="noopener noreferrer"&gt;Understanding TCP Sequence and Acknowledgment Numbers - packetlife.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Ethernet" rel="noopener noreferrer"&gt;Ethernet - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Network_interface_controller" rel="noopener noreferrer"&gt;Network interface controller - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=1z0ULvg_pW8" rel="noopener noreferrer"&gt;Hub, Switch, &amp;amp; Router Explained - What's the difference? - PowerCert Animated Videos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://catalogimages.wiley.com/images/db/pdf/0782140815.excerpt.pdf" rel="noopener noreferrer"&gt;Introduction to Networking (book excerpt) - Wiley&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/peer-to-peer/059600110X/ch01.html" rel="noopener noreferrer"&gt;A Network of Peers: Peer-to-Peer Models Through the History of the Internet (book excerpt) - O'Reilly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Peer-to-peer" rel="noopener noreferrer"&gt;Peer-to-peer - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Broadband" rel="noopener noreferrer"&gt;Broadband (and related pages) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.explainthatstuff.com/howbroadbandworks.html" rel="noopener noreferrer"&gt;Broadband and mobile broadband - Explain that stuff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.explainthatstuff.com/wirelessinternet.html" rel="noopener noreferrer"&gt;Wireless Internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/History_of_the_World_Wide_Web" rel="noopener noreferrer"&gt;History of the World Wide Web (and related pages) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.networkworld.com/article/3268449/what-is-dns-and-how-does-it-work.html" rel="noopener noreferrer"&gt;What is DNS and how does it work? - Network world&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Domain_Name_System" rel="noopener noreferrer"&gt;Domain Name System - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.icann.org/news/blog/do-you-know-iana" rel="noopener noreferrer"&gt;Do you know IANA? - ICANN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.quora.com/Why-was-the-www-domain-required-in-URLs-in-the-past" rel="noopener noreferrer"&gt;Why was the 'www' domain required in URLs in the past? - Quora question&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/People/Berners-Lee/FAQ.html" rel="noopener noreferrer"&gt;Frequently asked questions - w3.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/People/Berners-Lee/Kids.html" rel="noopener noreferrer"&gt;Answers for Young People - w3.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview" rel="noopener noreferrer"&gt;An overview of HTTP - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://computer.howstuffworks.com/cookie.htm" rel="noopener noreferrer"&gt;How Internet Cookies Work - howstuffworks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/HTTP_cookie" rel="noopener noreferrer"&gt;HTTP cookie - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/HTTPS" rel="noopener noreferrer"&gt;HTTPS - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=NmM9HA2MQGI" rel="noopener noreferrer"&gt;Secret Key Exchange (Diffie-Hellman) - Computerphile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/URL" rel="noopener noreferrer"&gt;URL - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Web_browser" rel="noopener noreferrer"&gt;Web browser (and related pages) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/OSI_model" rel="noopener noreferrer"&gt;OSI model - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>computerscience</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How Computers Work (Part 3): Software</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Fri, 06 Nov 2020 08:19:59 +0000</pubDate>
      <link>https://forem.com/joshcarvel/how-computers-work-part-3-software-kk8</link>
      <guid>https://forem.com/joshcarvel/how-computers-work-part-3-software-kk8</guid>
      <description>&lt;h2&gt;
  
  
  Intro 👋
&lt;/h2&gt;

&lt;p&gt;In Parts 1 and 2, we learned the fundamentals of how computers are able to do what they do, and the hardware of computers. &lt;/p&gt;

&lt;p&gt;In this final part, we'll look more closely at computer instructions: software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Parts 1 &amp;amp; 2, or basic understanding of computing concepts and hardware&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is software? 💿
&lt;/h2&gt;

&lt;p&gt;A computer can be thought of in terms of &lt;strong&gt;hardware,&lt;/strong&gt; the physical components, and &lt;strong&gt;software&lt;/strong&gt;, which is a term for computer &lt;strong&gt;programs&lt;/strong&gt;. Programs are just specific instructions to achieve certain tasks. Writing these instructions is &lt;strong&gt;programming.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The computer can only process binary instructions, but they can be written in various other ways and converted to binary. In the early days of digital computing, there was a system involving punching holes in cards that would be fed into the computer. The computer would run the instructions (that did some mathematical calculation, for example), you would get some output, then you would give it another program, and so on.&lt;/p&gt;

&lt;p&gt;These days, things are a lot more sophisticated. For one thing, we can make the computers do the work of making computers understand us! We can write instructions using &lt;strong&gt;high-level programming languages&lt;/strong&gt;, which are abstracted away from the low-level details of how computers work. Instructions are written in more human-readable form, and other programs do the conversions that eventually turn our instructions into binary.&lt;/p&gt;

&lt;p&gt;We can also run many programs at once, handle multiple users, and much more, thanks to &lt;strong&gt;operating systems&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Let's look at the different types of modern software.&lt;/p&gt;

&lt;h2&gt;
  
  
  BIOS 🥾
&lt;/h2&gt;

&lt;p&gt;Your computer can't do much without &lt;strong&gt;BIOS&lt;/strong&gt; (Basic Input/Output System).&lt;/p&gt;

&lt;p&gt;BIOS is some instructions that run when the computer first powers on. As mentioned in Part 2, the instructions are stored in flash memory on a chip attached to the motherboard. You may be familiar with configuring some BIOS settings, which in many older computers was accessible to the user only by pressing a certain key very quickly when the first screen came up. &lt;/p&gt;

&lt;p&gt;A key BIOS task is loading the operating system from memory. Because the computer loads its own instructions without any external input, this is known as &lt;strong&gt;booting&lt;/strong&gt;, after the old phrase 'to pull oneself up by one's own bootstraps'.&lt;/p&gt;

&lt;p&gt;BIOS is also a go-between for the CPU and hardware, including external devices (hence the name input/output system). Part of this role involves testing that all the hardware components are working when the computer switches on, known as a &lt;em&gt;power-on self-test&lt;/em&gt; (POST). This is a task BIOS does as part of the &lt;strong&gt;boot sequence&lt;/strong&gt;: the steps it takes when it starts up.&lt;/p&gt;

&lt;p&gt;BIOS is a type of &lt;strong&gt;firmware.&lt;/strong&gt; This means it is software that controls the low-level details of hardware on a device, and is specifically configured for that device. In the past, the firmware of a device was rarely replaced, although nowadays firmware can be updated and even physically replaced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operating systems 📃
&lt;/h2&gt;

&lt;p&gt;An operating system (OS) is just a computer program, but it has privileged access to the hardware and handles a lot of fundamental operations, like running all the other programs you want to run. It has a number of elements to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The kernel
&lt;/h3&gt;

&lt;p&gt;The core part of any OS is called the &lt;strong&gt;kernel&lt;/strong&gt;. The kernel code is always present in RAM while your computer is on. It handles a number of essential tasks.&lt;/p&gt;

&lt;h4&gt;
  
  
  Process management
&lt;/h4&gt;

&lt;p&gt;To run a program, the CPU needs to be told to move the program data from the disk (or other storage device) into RAM and start running it. The kernel handles this.&lt;/p&gt;

&lt;p&gt;This 'running' of the program is called a &lt;strong&gt;process.&lt;/strong&gt; If you've ever opened up Task Manager on Windows, or the equivalent on other OSs, you will have seen these processes listed, and noticed that while some relate to programs you opened yourself, most are background processes that the OS initiated. You may also notice that you can open up a program more than once, and see multiple processes, one for each &lt;em&gt;instance&lt;/em&gt; of the program.&lt;/p&gt;

&lt;p&gt;A process needs space in RAM to hold various values that it needs to do its work, which the kernel gives it. However, the process also needs to do things that only the kernel is trusted to do (because if they go wrong, the whole computer could crash), like interact with input/output devices, access files, start new processes, and so on. &lt;/p&gt;

&lt;p&gt;So the process asks the kernel to do it with a magic word (not 'please', just an instruction name the kernel understands). In programming, a request for an action is known as a &lt;em&gt;call&lt;/em&gt;, in the sense that you are calling on something to be done. In this case, the call is to the operating system and it's known as a &lt;strong&gt;system call.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The kernel handles sensitive access sort of like a vault. When no special access is needed, the kernel runs a process's code in what's called &lt;em&gt;user mode&lt;/em&gt;, where access is locked down. When greater access is needed, the kernel switches to &lt;em&gt;kernel mode&lt;/em&gt; (also called 'supervisor mode') to open things up.&lt;/p&gt;

&lt;p&gt;Another important aspect of process management is that processes are frequently &lt;em&gt;interrupted&lt;/em&gt;. &lt;strong&gt;Interrupts&lt;/strong&gt; may be generated by hardware e.g. keyboard input, software e.g. a request for a system call, or the CPU, e.g. indicating an error.&lt;/p&gt;

&lt;p&gt;Interrupts may be responded to immediately if serious, otherwise they are scheduled according to priority. The CPU stops the process it is running, saves its status in memory, switches to kernel mode and executes a response (these are pre-set responses which map to specific types of interrupts, just like with system calls).&lt;/p&gt;

&lt;p&gt;Most operating systems are also designed to run processes 'simultaneously', i.e. &lt;strong&gt;multitasking&lt;/strong&gt;. It does this pretty much how we would do multitasking (but much, much quicker) - kicking off one task, then another, then switching back to the first one when it needs attention, and so on. As noted in Part 2, it can also make use of the multiple cores of the CPU. The code that handles all this is called the &lt;strong&gt;scheduler&lt;/strong&gt;, and it runs for very short periods between the chunks of process code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Memory management
&lt;/h4&gt;

&lt;p&gt;The kernel also handles &lt;strong&gt;memory management&lt;/strong&gt;, using the &lt;em&gt;memory management unit&lt;/em&gt; (MMU). It makes sure the data used by one program is not overwritten by data used by another. At its core, this just means allocating specific blocks of memory for a specific process, which belong to that process only while it is running. &lt;/p&gt;

&lt;p&gt;This also provides a level of &lt;em&gt;memory protection:&lt;/em&gt; programs should not be able to read or modify the memory of other programs. This helps limit the damage done if one program starts doing undesirable things with memory, either unintentionally or intentionally (malicious software).&lt;/p&gt;

&lt;p&gt;Computers usually use an abstraction called &lt;strong&gt;virtual memory,&lt;/strong&gt; where the computer's memory is represented in a more ideal way to processes than it actually is in reality. One problem this solves is that a process's data may become scattered across memory addresses over time, which is difficult for the process to work with. The process can instead be given a nice, consecutive block of &lt;strong&gt;logical addresses&lt;/strong&gt; (also known as virtual addresses) which are mapped to physical memory addresses by the MMU. Each block is known as a &lt;strong&gt;page.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another benefit is that the computer can optimise the space available in RAM, by keeping some process data that isn't currently needed in disk storage temporarily, a technique known as &lt;strong&gt;paging&lt;/strong&gt; (if the entire process's memory is moved to storage, it's called &lt;em&gt;swapping&lt;/em&gt;). Paging causes some delay due to moving data back and forth between RAM and storage, but the trade-off is seen to be worth it.&lt;/p&gt;

&lt;h4&gt;
  
  
  File management
&lt;/h4&gt;

&lt;p&gt;Another crucial role of the kernel is handling &lt;strong&gt;files,&lt;/strong&gt; i.e. data that we want to be self-contained. The kernel provides a &lt;strong&gt;file system&lt;/strong&gt; so we can work with data easily. File systems help with moving data into storage, where data is just a long sequence of binary values. To know where one file begins and another ends, we need a file that stores this information: a &lt;strong&gt;directory.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;On our desktop we have the more abstract concept of 'folders', and think of them as places our files live. But most of the time the folder just refers to a directory listing the file information. For each file this contains details of the address in storage, its length, name, creation and last modification dates, the file owner and read/write access of the file. This is updated whenever there is a change.&lt;/p&gt;

&lt;p&gt;A particular file has a particular &lt;strong&gt;file format&lt;/strong&gt;, which indicates to the operating system how to decode it and what sorts of applications it should be opened in. The file &lt;em&gt;extension&lt;/em&gt; at the end of the name indicates the format, e.g. a plain text file has extension &lt;em&gt;.txt&lt;/em&gt;. The file itself also begins with some &lt;strong&gt;metadata&lt;/strong&gt; (data about data) which helps the computer interpret the data in the file. &lt;/p&gt;

&lt;p&gt;Operating systems such as Windows and macOS hide the file extension in their file explorer, because simply changing the extension doesn't change the data, so the file may be interpreted incorrectly (at best, the incorrect extension will just be ignored). But you &lt;em&gt;can&lt;/em&gt; change the encoding by &lt;em&gt;saving&lt;/em&gt; it to a different file format, when possible.&lt;/p&gt;

&lt;p&gt;Modern file systems store files in blocks so that there is extra space for the file to become bigger. If the file exceeds its block space however, the rest of the file may be stored somewhere else. This is known as &lt;strong&gt;fragmentation&lt;/strong&gt;, and the directory has to keep track of where all the fragments are in storage. Reading a fragmented file can cause delay in hard disk drives (not so much in SSDs), which can be mitigated by running a process called &lt;strong&gt;defragmentation&lt;/strong&gt;, where the file fragments are put back together. Most OSs now do this automatically for you.&lt;/p&gt;

&lt;p&gt;If you 'delete' a file, the record is removed from the directory, but the data in storage isn't overwritten until something else needs that block. This is why you are advised to clear your computer's disk drive when getting rid of an old computer - some 'deleted' data may still be recoverable.&lt;/p&gt;

&lt;p&gt;When you have lots of files, you need a &lt;strong&gt;hierarchical file system&lt;/strong&gt;, where files are grouped in directories and subdirectories, to keep things organised. At the top of the hierarchy is the &lt;strong&gt;root directory,&lt;/strong&gt; which references other files, including directories. We can describe the route to those files with a &lt;em&gt;file path&lt;/em&gt;. Moving a file's location is as simple as changing the two affected directories - the data itself doesn't move.&lt;/p&gt;

&lt;p&gt;On Windows the root directory represents the storage disk drive as a whole, which for historical reasons (drives A &amp;amp; B were floppy disk drives), is known as the C: drive. On other systems the root directory is usually just '/'. OSs that allow multiple users can deal with this by assigning users their own subdirectory of files they have read/write access to, and not showing them other user's files, while allowing an administrator to access all files.&lt;/p&gt;

&lt;p&gt;A file system is implemented in what's known as a &lt;strong&gt;partition,&lt;/strong&gt; i.e. a segment of the disk. Often a disk is divided into multiple partitions with separate file systems, for example to allow the user to have different OSs in separate partitions on the same computer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Device management
&lt;/h4&gt;

&lt;p&gt;We can think of software as something that &lt;em&gt;communicates&lt;/em&gt; with the hardware. However, not all computer hardware is the same: there are lots of different configurations. A certain hardware component may expect instructions in a different form than a similar one created by someone else for a different computer. So it seems you would have to write different instructions for each version of the component. &lt;/p&gt;

&lt;p&gt;This is the problem &lt;strong&gt;device drivers&lt;/strong&gt; aim to solve. They are a middleman, a translator. The software asks for a particular action in a standard language, and the device driver translates the request to account for hardware differences. These days many hardware components, such as keyboards, tend to conform to a generic standard for their type, so the OS can include &lt;em&gt;generic&lt;/em&gt; drivers for these components. The OS also allows you to install more specific device drivers where necessary.&lt;/p&gt;

&lt;h4&gt;
  
  
  Networking and security
&lt;/h4&gt;

&lt;p&gt;Aside from the tasks mentioned above, the kernel does some other things. It provides the ability for &lt;strong&gt;networking&lt;/strong&gt; i.e. accessing the resources of other computers, and various security features.&lt;/p&gt;

&lt;h3&gt;
  
  
  User interfaces
&lt;/h3&gt;

&lt;p&gt;The main OS feature outside of the kernel is user interfaces, which you use to interact with the computer. &lt;/p&gt;

&lt;h4&gt;
  
  
  Command line interface (CLI)
&lt;/h4&gt;

&lt;p&gt;The CLI is the interface at which you enter commands with the keyboard.&lt;/p&gt;

&lt;p&gt;There has to be a graphical element to this interface for the user to see the input and output, but it's very basic and doesn't accept mouse input. We can call this part the &lt;em&gt;terminal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Beneath that is a program that receives certain commands, interprets them, executes the instruction then sends the output back to the screen. This program is not part of the kernel, it just communicates with it. It's known as the &lt;em&gt;shell&lt;/em&gt; (the kernel of a nut or seed is surrounded by its shell), or in this context could also be called a &lt;em&gt;command line interpreter.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Operating systems usually have a default command line interface, and they can vary in various ways, such as the commands they understand. But on modern computers you can download and use different types.&lt;/p&gt;

&lt;h4&gt;
  
  
  Text-based user interface (TUI)
&lt;/h4&gt;

&lt;p&gt;A TUI is a less common interface that was seen in older computers for certain purposes and you might still see sometimes, for example on the BIOS screen. It's just a much more basic graphical interface where you select text options.&lt;/p&gt;

&lt;h4&gt;
  
  
  Graphical user interface (GUI)
&lt;/h4&gt;

&lt;p&gt;The GUI (pronounced 'gooey') dates back to 1973 when Xerox developed the Alto computer at their research centre Xerox PARC. The computer featured a mouse and the GUI had windows, icons and drop-down menus, and began the trend of the desktop metaphor that is still used today (the &lt;em&gt;desktop environment&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;The Alto wasn't a commercial product, but the GUI began to go mainstream after Steve Jobs visited Xerox PARC in 1979 and saw the potential. Apple's Lisa computer in 1983 featured a GUI, though the Macintosh in 1984 was the first commercially successful usage.&lt;/p&gt;

&lt;p&gt;The desktop environment on modern computers is actually made up of a number of components, such as the windowing system, file system and graphical theme, which are customisable to a greater or lesser extent depending on the operating system. Beneath them there is still a shell that processes the instructions.&lt;/p&gt;

&lt;p&gt;Though GUIs revolutionised how we use computers, and made many tasks simpler, they didn't replace CLIs. Although these days there are GUIs for a great many things, CLIs still give you the flexibility to achieve any computing task, which is not quite true of GUIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utility programs
&lt;/h3&gt;

&lt;p&gt;Utility programs are what they sound like: programs to support the computer infrastructure. This includes things like backup, anti-virus utilities and disk defragmentation. These are considered part of the operating system, though the user may install replacements or additional utilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modern OSs in context 🖥️
&lt;/h2&gt;

&lt;p&gt;Now we'll look at the different operating systems we have today and how they came about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unix
&lt;/h3&gt;

&lt;p&gt;Most operating systems around today derive from an OS called &lt;strong&gt;Unix&lt;/strong&gt;, developed at the famous Bell Labs in the 1970s. &lt;/p&gt;

&lt;p&gt;AT&amp;amp;T, which ran Bell Labs, was legally restricted from selling software, and required to cheaply grant licences for the Unix source code to other educational institutions. In 1982, AT&amp;amp;T became legally free to sell Unix. But by then, the University of California, Berkeley, had already developed a slightly different version - the Berkeley Software Distribution (BSD) - based on the source code they had been licensed in the 1970s.&lt;/p&gt;

&lt;p&gt;By the 1990s, Berkeley made the BSD source code freely available to study and use. Today we would call this &lt;strong&gt;open-source software.&lt;/strong&gt; It contained no source files from the AT&amp;amp;T version (though a legal battle went on for years). OSs like this are known as &lt;strong&gt;Unix-like&lt;/strong&gt; operating systems and are not AT&amp;amp;T copyright. Though Berkeley stopped working on BSD, others took on the mantle.&lt;/p&gt;

&lt;p&gt;One of the derivatives is known as &lt;strong&gt;FreeBSD&lt;/strong&gt;. Like BSD, it uses a &lt;em&gt;permissive software license&lt;/em&gt;. This means you can modify the software and claim full copyright rights over the derivative product. This is one reason FreeBSD is used in some way by many companies. It is a key part of the PS4 operating system and in OSs created by Apple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apple OSs
&lt;/h3&gt;

&lt;p&gt;Apple became a successful company after releasing the Apple II in 1977, one of the first highly successful, mass-produced personal computers. However, they failed to produce a personal computer and operating system to match their initial success in the following two decades.&lt;/p&gt;

&lt;p&gt;Since the early 2000s, Apple computers have used &lt;strong&gt;macOS&lt;/strong&gt; (previously known as Mac OS X and OS X). The kernel of macOS, called Darwin, used many elements of Free BSD, and Darwin is the basis for all the other Apple OSs - &lt;strong&gt;iOS&lt;/strong&gt;, iPadOS, watchOS and tvOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux
&lt;/h3&gt;

&lt;p&gt;In 1991, a Helsinki University student called Linus Torvalds released a Unix-like kernel he had made called Linux (a combination of his name and the 'x' from Unix, pronounced '&lt;em&gt;lin-ucks&lt;/em&gt;'). However, he hadn't written the other software needed to create a fully-fledged OS, such as a shell and a program to compile (translate) the code he had written.&lt;/p&gt;

&lt;p&gt;As it happened, there was a project that had begun in the 1980s and had already made that other software, but didn't yet have a working kernel. It was called the GNU Project, with GNU standing for 'GNU's not Unix!' (yes, really!). GNU's aim was to freely distribute a Unix-like operating system and lots of software to go with it. So Linux and GNU developers began co-operating. GNU developers made their software compatible with Linux so a fully-fledged OS could be produced, and Torvalds started releasing Linux versions under a GNU license.&lt;/p&gt;

&lt;p&gt;GNU is about &lt;strong&gt;free software&lt;/strong&gt; (in the sense that it is not &lt;em&gt;owned&lt;/em&gt; by any individual). It's more ethically opinionated than open-source (though definitions of the two movements are disputed). While BSD was one stop short of public domain, more or less just requiring a copyright notice, GNU software is distributed under a 'copyleft' scheme, meaning the work can never be redistributed under a more restrictive scheme.&lt;/p&gt;

&lt;p&gt;OSs that derive from the Linux kernel and other software are known as &lt;strong&gt;Linux distributions&lt;/strong&gt;, and there are hundreds of them, for all sorts of different needs and preferences. At one time, distributions using GNU software were referred to as 'GNU/Linux' distributions. Now they're usually just called Linux, a point of controversy to this day.&lt;/p&gt;

&lt;p&gt;Linux systems are &lt;em&gt;everywhere.&lt;/em&gt; Though not exactly a Linux distribution, Google's &lt;strong&gt;Android&lt;/strong&gt;, the OS that runs on roughly 3/4 of the world's smartphones and tablets, is based on a modified version of the Linux kernel, as is the &lt;strong&gt;Chrome OS&lt;/strong&gt; used in its Chromebooks. &lt;/p&gt;

&lt;p&gt;You will find it running on mainframe computers, supercomputers, routers, smart TVs, smart home technology, smartwatches, video game consoles and much more. By most estimates, most web servers are run on Linux, and it continues to be popular among programmers and those who enjoy its high configurability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;p&gt;"But what about &lt;em&gt;Microsoft Windows&lt;/em&gt;?!", I hear you cry. Well, Windows is the big exception.&lt;/p&gt;

&lt;p&gt;As it happens, Microsoft had acquired a licence for a version of Unix from AT&amp;amp;T in the late 1970s, which they would sell to other companies, under the name Xenix for legal reasons. Xenix actually became the most popular Unix variant of the time, and Microsoft believed it would be the standard operating system of the future.&lt;/p&gt;

&lt;p&gt;In 1980, IBM began to compete in the personal computer market, and went to Microsoft for various things, notably their programming language Microsoft BASIC, and an operating system. Xenix was not suitable for the hardware of the PC, so IBM considered CP/M, a common operating system of the time for business computers, but couldn't reach an agreement with its creator. Microsoft jumped in, buying the rights to an OS initially known as QDOS (Quick and Dirty Operating System), essentially a CP/M clone, for just $50,000. Their version was called MS-DOS (Microsoft Disk Operating System).&lt;/p&gt;

&lt;p&gt;Microsoft was paid a fixed fee by IBM for MS-DOS, but retained the rights to sell MS-DOS to other companies, which IBM didn't think was important. It turned out to be very important indeed when lots of companies began reverse-engineering and selling clones of the IBM PC (using a legal loophole where an engineer who has seen the copyrighted source code can write instructions, which will be used by another engineer in a 'clean room' who has never seen the source code). Microsoft sold MS-DOS to many of these companies, while IBM got pushed out of the PC market.&lt;/p&gt;

&lt;p&gt;When AT&amp;amp;T became free to sell Unix and enter the PC market in 1982, Microsoft decided that pursuing Xenix was not a profitable strategy. MS-DOS was successful, so they worked on a follow up, Microsoft Windows, which is used on at least 3/4 of all personal computers today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applications 📱
&lt;/h2&gt;

&lt;p&gt;User-facing programs are known as &lt;strong&gt;applications&lt;/strong&gt; or apps. An app communicates with what we might call the &lt;em&gt;platform&lt;/em&gt; or &lt;em&gt;environment&lt;/em&gt; it will be run on, using the &lt;strong&gt;application programming interface&lt;/strong&gt; (API) that the environment makes available.&lt;/p&gt;

&lt;p&gt;The API is the code that understands a particular set of instructions. The instructions are documented somewhere so the programmer can use them without knowing the details of the hardware. For example, OS system calls are implemented via an API (though they vary depending on the OS). Other environments such as mobile devices and web browsers have different APIs that allow software to be written for them. &lt;/p&gt;

&lt;p&gt;An app that is run directly by a particular device's OS is called a &lt;strong&gt;native application.&lt;/strong&gt; More recently, &lt;strong&gt;web applications&lt;/strong&gt; have become more popular. In a web app, the code is stored on a server and the device's web browser downloads the code via the internet, so the user doesn't have to download any code themselves. There are trade-offs to both approaches.&lt;/p&gt;

&lt;p&gt;Applications for different platforms tend to have different programming languages that they require the software to be written in, for various reasons such as suitability as well as business reasons. For example, even to specifically write for mobile devices you have to write in Java for Android, but in Swift for iOS. This is one advantage that web applications have - they can be written in one language, JavaScript, and be run on any device so long as it has a web browser and an internet connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Let's briefly recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Software is just instructions the computer understands, but today it can be written in a variety of high-level programming languages for a variety of different platforms.&lt;/li&gt;
&lt;li&gt;Applications are not the only type of software, and modern applications couldn't be run without the OS kernel managing things like processes and memory.&lt;/li&gt;
&lt;li&gt;There are various financial, political and technical reasons for the different forms of software we have today.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That concludes this three-part series on computers. I hope it has provided a solid introduction and a good jumping-off point for further exploration.&lt;/p&gt;

&lt;p&gt;Thanks for reading! 😀&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;p&gt;* = particularly recommended for further study&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;* &lt;a href="https://www.youtube.com/playlist?list=PLH2l6uzC4UEW0s7-KewFLBC1D0l6XRfye"&gt;Crash Course Computer Science Episodes 18 and 20&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;* &lt;a href="https://www.youtube.com/watch?v=9GDX-IyZ_C8"&gt;Operating System Basics - Brian Will&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;* &lt;a href="https://dwmkerr.com/effective-shell-part-5-understanding-the-shell/"&gt;Understanding the Shell - dwmkerr.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://computer.howstuffworks.com/bios.htm"&gt;How BIOS works - howstuffworks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Operating_system"&gt;Operating system (and associated pages) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/virtual-memory-in-operating-system/"&gt;Virtual Memory in Operating System - GeeksforGeeks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.howtogeek.com/184659/beginner-geek-hard-disk-partitions-explained/"&gt;Hard Disk Partitions Explained - How-To Geek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Shell_(computing)"&gt;Shell (computing) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.howtogeek.com/182649/htg-explains-what-is-unix/"&gt;What Is Unix, and Why Does It Matter? - How-To Geek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=jowCUo_UGts"&gt;Unix vs Linux - Gary Explains&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.quora.com/If-macOS-is-Unix-and-Linux-was-inspired-Unix-then-what-is-Windows-based-on-and-why-was-it-implemented-like-this-by-Bill-Gates"&gt;Quora question on origin of Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Usage_share_of_operating_systems"&gt;Usage share of operating systems - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Triumph of the Nerds - documentary (1996)&lt;/li&gt;
&lt;li&gt;Revolution OS - documentary (2001)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>How Computers Work (Part 2): Hardware</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Fri, 30 Oct 2020 13:56:00 +0000</pubDate>
      <link>https://forem.com/joshcarvel/how-computers-work-part-2-57al</link>
      <guid>https://forem.com/joshcarvel/how-computers-work-part-2-57al</guid>
      <description>&lt;h2&gt;
  
  
  Intro 🛠️
&lt;/h2&gt;

&lt;p&gt;In Part 1, we learned the basics of how computers store and process data.&lt;/p&gt;

&lt;p&gt;In this part we'll look at the components that handle these operations: hardware. Specifically, the sort of hardware found in personal computers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/joshcarvel/how-computers-work-part-1-2o9l"&gt;Part 1&lt;/a&gt;, or basic understanding of computing fundamentals such as binary, bits and logic gates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The motherboard 👩
&lt;/h2&gt;

&lt;p&gt;Inside a modern personal computer you will find many things, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A power supply, batteries and cables to connect various parts&lt;/li&gt;
&lt;li&gt;Devices for cooling (since using electricity generates heat), usually a 'heat sink' and fan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drives&lt;/strong&gt; (usually in desktop PCs) that accept discs or disks with stored data&lt;/li&gt;
&lt;li&gt;Internal storage (hard disk or SSD)&lt;/li&gt;
&lt;li&gt;(In laptops) built-in speakers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But most of the action takes place on the &lt;strong&gt;motherboard,&lt;/strong&gt; i.e. the main circuit board of the computer, so that will be our focus here.&lt;/p&gt;

&lt;p&gt;In early computers, different electrical components were just wired together in a complicated fashion. Two innovations changed this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chips (integrated circuits)
&lt;/h3&gt;

&lt;p&gt;The first is the &lt;strong&gt;integrated circuit&lt;/strong&gt;, commonly known as a chip or microchip. This allows lots of tiny transistors to be connected on one small, flat piece (or 'chip') of silicon.&lt;/p&gt;

&lt;p&gt;The type of chip seen today, which uses &lt;em&gt;photolithography&lt;/em&gt; (using light to imprint circuit designs in silicon) was invented by Robert Noyce in 1959. In the early 1960s, an integrated circuit might hold around 5 transistors, but thanks to advances in science, the number of transistors that could fit doubled roughly every two years, known as 'Moore's law' after an engineer called Gordon Moore. &lt;/p&gt;

&lt;p&gt;In 1968, Moore and Noyce formed a company that became the world's largest chip manufacturer. Since it specialised in integrated electronics, they called it &lt;strong&gt;Intel.&lt;/strong&gt; Today, Intel chips can hold &lt;em&gt;billions&lt;/em&gt; of transistors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Printed circuit boards
&lt;/h3&gt;

&lt;p&gt;Integrated circuits dramatically reduce the number of components needed, but the components still need to be wired together. &lt;strong&gt;Printed circuit boards&lt;/strong&gt; &lt;strong&gt;(PCBs)&lt;/strong&gt; helped with this. &lt;/p&gt;

&lt;p&gt;Wires (usually made from copper) that connect components are arranged in an intricate design for maximum efficiency, and placed on a board usually made of fibreglass (plastic reinforced with glass).&lt;/p&gt;

&lt;p&gt;You can see the outline of these wires on a circuit board, but that's not all of them! The insulating material may have wires on &lt;em&gt;both&lt;/em&gt; sides, and there may be multiple layers, like a sort of electrical lasagne, with connections being made vertically (via small holes) as well as horizontally on the surface.&lt;/p&gt;

&lt;p&gt;Being able to put chips on PCBs revolutionised what computers could do. This is how we get to the modern motherboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Motherboard components
&lt;/h3&gt;

&lt;p&gt;The motherboard is a PCB which the main components of a computer are connected to. Here are some notable ones (not all of them):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;central processing unit (CPU)&lt;/strong&gt;, which connects to a socket on the motherboard and controls operations&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;chipset,&lt;/strong&gt; which connects the CPU to the other components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAM:&lt;/strong&gt; 'sticks' of memory (chips on a PCB) which connect into slots on the motherboard, and are the main place data is held while the computer runs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BIOS&lt;/strong&gt; chip, which stores the instructions the CPU uses to start up the computer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ports,&lt;/strong&gt; which connect devices known as &lt;strong&gt;peripherals&lt;/strong&gt; that provide some input (e.g. keyboard), output (e.g. monitor), or both (e.g. USB stick)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expansion cards:&lt;/strong&gt; PCBs that connect to an expansion slot and enhance the functionality of the computer, for example a graphics card or sound card (used in desktop computers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll focus on the CPU, because it's the most crucial to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CPU 👑
&lt;/h2&gt;

&lt;p&gt;Computer instructions need to be interpreted and carried out, i.e. &lt;em&gt;processed&lt;/em&gt;. This mainly happens in the CPU. &lt;/p&gt;

&lt;p&gt;The CPU is a type of &lt;em&gt;processor&lt;/em&gt;, of which there are others, such as the graphics processing unit (GPU). It's usually made using integrated circuits (usually a CPU is a single chip), in which case it's referred to as a &lt;em&gt;microprocessor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The CPU, quite simply, is in charge of the computer. It has a few main components which we'll talk about, though the actual implementation is dependent on the type of CPU chip.&lt;/p&gt;

&lt;h3&gt;
  
  
  The control unit
&lt;/h3&gt;

&lt;p&gt;The CPU is in charge of the computer, but the &lt;em&gt;control unit&lt;/em&gt; is in charge of the CPU! It directs the processing of instructions. &lt;/p&gt;

&lt;p&gt;No matter how complicated computer instructions are, they always involve basic actions that the CPU can perform, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting data in and out of memory&lt;/li&gt;
&lt;li&gt;Mathematical and logical operations&lt;/li&gt;
&lt;li&gt;Inputting and outputting data from external devices such as a keyboard or monitor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these instructions is given a code in binary, like how a particular video game action such as 'jump' is associated with a particular button. (Jump is actually a computer instruction too! We'll look at it shortly). &lt;/p&gt;

&lt;p&gt;This is an &lt;strong&gt;opcode&lt;/strong&gt; (operation code). It is supplied along with the memory address of some data to do the operation on (called the &lt;strong&gt;operand&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;These codes are not universal - it depends on the particular &lt;strong&gt;instruction set architecture&lt;/strong&gt; (ISA) that the CPU chip has been built with, i.e. the way the circuits have been configured.&lt;/p&gt;

&lt;p&gt;The most common series of ISAs was developed by Intel and is called &lt;strong&gt;x86&lt;/strong&gt; architecture (because Intel produced a number of chips that used it whose name ended with 86).&lt;/p&gt;

&lt;h4&gt;
  
  
  RAM, caches &amp;amp; registers
&lt;/h4&gt;

&lt;p&gt;To perform operations, the control unit works with &lt;strong&gt;RAM&lt;/strong&gt;, a large bank of memory which is separate from the CPU but nearby on the motherboard, connected with wires. RAM connects to the motherboard via slots and you can add more to your computer. The most common type is called &lt;em&gt;dynamic RAM&lt;/em&gt; (DRAM), and it's cheaper than the other main type, &lt;em&gt;static RAM&lt;/em&gt; (SRAM).&lt;/p&gt;

&lt;p&gt;The wires that transfer data on the motherboard are called &lt;strong&gt;buses,&lt;/strong&gt; because they transport information. They are grouped together to carry bits, for example you might have 64 wires together to transport a 64-bit number.&lt;/p&gt;

&lt;p&gt;The CPU is connected to RAM by an &lt;strong&gt;address bus,&lt;/strong&gt; which the CPU uses to tell RAM the address of some data it wants to access. It is also connected by a &lt;strong&gt;data bus,&lt;/strong&gt; through which data can be transferred back and forth.&lt;/p&gt;

&lt;p&gt;For any given computer program, the data it wants to perform operations on and the instructions it wants the CPU to carry out are both stored in RAM. Each instruction contains an opcode and operand, together in a single binary number.&lt;/p&gt;

&lt;p&gt;Sending data down wires is quick, but it still takes time, so location matters. For this reason, there is an area of memory &lt;em&gt;within&lt;/em&gt; the CPU for temporarily holding values - the &lt;strong&gt;registers.&lt;/strong&gt; Each register can hold a single value and like the buses, this is usually between 8 and 64 bits. &lt;/p&gt;

&lt;p&gt;The registers are used to hold data needed for operations, such as the current instruction. But there is also some memory kept for values that are not being used right now, but are likely to be needed soon: the &lt;strong&gt;caches.&lt;/strong&gt; These are divided into 'levels' and there are often three of them. Level 1 cache, the closest and smallest, is usually on the CPU chip itself. The others are bigger but further away, though not as far as RAM.&lt;/p&gt;

&lt;h4&gt;
  
  
  The instruction cycle
&lt;/h4&gt;

&lt;p&gt;Each instruction is &lt;em&gt;fetched&lt;/em&gt; from RAM by the control unit, using the buses, one at a time. Each half of the instruction (opcode and operand) is read separately, so the control unit knows the action to perform, and it can get the data to perform it from RAM using the buses.&lt;/p&gt;

&lt;p&gt;Once the control unit receives an instruction, it &lt;em&gt;decodes&lt;/em&gt; it. This means it runs it through a circuit containing logic gates, which triggers binary values to be sent on a certain path of wires depending on what the binary opcode is. This is all just determined by the instruction set that has been hardwired into the chip.&lt;/p&gt;

&lt;p&gt;Now the CPU is ready to &lt;em&gt;execute&lt;/em&gt;, i.e. perform the operation. Again, this is a case of the CPU's circuits doing the job they have been wired to do - it's just the data they do it with that changes.&lt;/p&gt;

&lt;p&gt;The whole cycle is known as the &lt;strong&gt;instruction cycle&lt;/strong&gt; (also known as the fetch-decode-execute cycle or fetch-execute cycle). &lt;/p&gt;

&lt;h4&gt;
  
  
  Optimisation
&lt;/h4&gt;

&lt;p&gt;A simple CPU (as used in early digital computers) would wait to go through the whole cycle before moving on to the next instruction, but modern CPUs do multitasking, so when one instruction is being decoded, the next one is already being fetched, and so on.&lt;/p&gt;

&lt;p&gt;In addition, since some operations take longer to perform, modern processors can split the circuitry that executes instructions into separate units specialised for different instructions (still on the same processor) and process them at the same time, allowing it to get more done quicker.&lt;/p&gt;

&lt;h3&gt;
  
  
  The clock
&lt;/h3&gt;

&lt;p&gt;The control unit directs the CPU, but it relies on the &lt;strong&gt;clock&lt;/strong&gt; to function. &lt;/p&gt;

&lt;p&gt;The clock generates the consistent electrical pulses that are sent down the wires and received by transistors. It does this in the same way a digital watch keeps time - using a quartz crystal that vibrates at a fixed interval when electricity is applied.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;clock rate&lt;/strong&gt; is the speed this happens, measured in &lt;em&gt;clock cycles per second&lt;/em&gt;. A clock 'cycle' is &lt;em&gt;not&lt;/em&gt; the same as the instruction cycle. &lt;/p&gt;

&lt;p&gt;In early computers, an instruction would actually take multiple clock cycles, because there are a few steps to carry out each instruction, each requiring a pulse of electricity. The process has been refined since then using optimisations such as those described above, so the opposite is now true - multiple instructions can be carried out per clock cycle.&lt;/p&gt;

&lt;p&gt;This and many other factors affect how productive the computer actually is. But to keep things simple, the clock rate (also known as clock speed or frequency) is often used as a rough indication of how fast the computer can work. It's measured in &lt;em&gt;gigahertz&lt;/em&gt;, i.e. &lt;em&gt;billion&lt;/em&gt; cycles per second!&lt;/p&gt;

&lt;h3&gt;
  
  
  The ALU
&lt;/h3&gt;

&lt;p&gt;The component that makes operations possible is the &lt;strong&gt;arithmetic and logic unit (ALU).&lt;/strong&gt; The ALU takes two pieces of data and returns one output. &lt;/p&gt;

&lt;h4&gt;
  
  
  Maths
&lt;/h4&gt;

&lt;p&gt;In Part 1 we looked at how logic gates are used with true and false values. Computers can do maths the same way, but we think of the values as 0 and 1 instead.&lt;/p&gt;

&lt;p&gt;When it does maths, the ALU uses a type of logic gate called 'exclusive or', abbreviated to &lt;strong&gt;XOR&lt;/strong&gt;. For the output to be 1, one of the inputs must be 1, and the other must be 0.&lt;/p&gt;

&lt;p&gt;Here are the four possible variations and outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0 + 0 = 0&lt;/li&gt;
&lt;li&gt;0 + 1 = 1&lt;/li&gt;
&lt;li&gt;1 + 0 = 1&lt;/li&gt;
&lt;li&gt;1 + 1 = 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are essentially doing binary maths here! You may notice the sums all look correct except for the last one. But it's actually just the answer for the '1s' column - a remainder 1 is carried to the next column.&lt;/p&gt;

&lt;p&gt;In this simple sum there would just be 0s in the '2s' column for both numbers being added. 0 + 0 = 0, plus the 1 remainder = 1 in the '2s' column. So the complete answer is 10, which is binary for two.&lt;/p&gt;

&lt;p&gt;For this to work, computers have to be wired for the largest length of number they are expecting to deal with - they need the physical wires to represent each column, so the calculation can be performed. So a computer designed to deal with 8-bit numbers (like early computers), would represent the number 1 as 00000001.&lt;/p&gt;

&lt;p&gt;Doing different types of calculations usually requires more logic gates, dealing with bigger numbers requires more wires, and there are some adjustments needed for negative numbers, but any mathematical operation can be achieved which this approach.&lt;/p&gt;

&lt;h4&gt;
  
  
  Logic
&lt;/h4&gt;

&lt;p&gt;Let's look at an example of a logical operation now.&lt;/p&gt;

&lt;p&gt;A common logical operation is for the control unit to 'jump' to a different instruction in the instruction list in RAM, &lt;em&gt;if&lt;/em&gt; a certain condition is true. Imagine we have a simple 'guess the secret number' game, and the instructions tell the computer to keep prompting the user to guess again on the screen when a guess is made.&lt;/p&gt;

&lt;p&gt;But, &lt;em&gt;if&lt;/em&gt; the user's guess is &lt;em&gt;equal to&lt;/em&gt; the secret number, the computer should jump to a different address in RAM to get an instruction for congratulating the user.&lt;/p&gt;

&lt;p&gt;To do this, the ALU can subtract number A from number B, e.g. 5 - 5. If the result is 0, the numbers must be the same! (This would work the same way with words, which are just encoded as binary numbers).&lt;/p&gt;

&lt;p&gt;In this case, we don't want the output of the calculation, we just want a true or false answer: is the result 0? ALUs have a wire specifically for this, along with some other useful indicator wires, which just output a 1 or 0: true or false. These are known as the &lt;em&gt;flags&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So if the zero flag indicates true, the control unit can 'jump', by fetching a different instruction at the specified RAM address. This is just one example - all manner of logical instructions can be achieved using the ALU and its flags.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cores
&lt;/h3&gt;

&lt;p&gt;For quite a while, computers did 'multitasking' in pretty much the same way you would - just switching back and forth between multiple tasks, and often completing each task slower than if you had spent all the time on it.&lt;/p&gt;

&lt;p&gt;But if you had some other people to do the other tasks for you, you would get more done, and this is how modern CPUs tend to work. There are essentially multiple CPUs, known as &lt;strong&gt;cores,&lt;/strong&gt; usually all on the same chip. Different sets of instructions can be carried out on different cores at the same time (as long as they don't depend on each other), allowing more work to be done quicker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Computer specifications 💻
&lt;/h2&gt;

&lt;p&gt;We'll finish by looking at some key hardware specifications (specs). Hardware is a key factor in choosing a computer, especially if you are using the computer for programming.&lt;/p&gt;

&lt;p&gt;Let's say you are choosing a laptop for typical programming, or you just want some solid performance. Here are three respectable specs to consider (as of time of writing):&lt;/p&gt;

&lt;p&gt;1. &lt;u&gt;A mid-range CPU chip&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;CPU chips are named quite confusingly. Here is an example: the 'Intel Core i5-8250U'.&lt;/p&gt;

&lt;p&gt;To find a respectable mid-range Intel chip, focus on three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The brand: look for 'Intel Core', other brands are 'budget' chips&lt;/li&gt;
&lt;li&gt;The model number (i3, i5, i7 etc.): look for i5 or higher&lt;/li&gt;
&lt;li&gt;The 'generation': this number comes immediately after the dash following the model number, look for 7 or above&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The suffix at the end is also informative, because it tells you what the processor is optimised for, e.g. the 'U' in the example above means it is optimised for saving battery power.&lt;/p&gt;

&lt;p&gt;The 3 digits in between can be ignored as they are just for Intel's stock-keeping purposes, like a barcode. The naming convention is explained in more detail on &lt;a href="https://www.intel.ca/content/www/ca/en/processors/processor-numbers.html"&gt;Intel's website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main alternative to Intel is AMD, and the AMD Ryzen series competes with the Intel Core. The model numbers match, so AMD Ryzen 5 is roughly equivalent to i5, and there are fewer generations, so 2nd generation is fine. Here is some &lt;a href="https://www.techconsumerguide.com/a-simple-guide-to-amd-ryzen-naming-scheme/"&gt;further explanation&lt;/a&gt; of their naming.&lt;/p&gt;

&lt;p&gt;Though you don't need to, if you look in more detail at the specs of a chip, you will see the number of cores that it has (our example chip has 4) and the 'base' (usual) clock speed (1.60GHz) and a 'max' clock speed that it &lt;em&gt;might&lt;/em&gt; be able to reach if it needs to (3.40GHz in our example).&lt;/p&gt;

&lt;p&gt;While I have given a rough guide here, it is worthwhile doing further research on this, because exactly how you use your computer and what your priorities are will greatly affect the type of CPU you should look for.&lt;/p&gt;

&lt;p&gt;2. &lt;u&gt;8GB RAM or more&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;RAM is a much simpler matter. You will want 8GB unless you are on a very tight budget, and 16GB if you are doing a lot of intensive work or gaming etc. You might need to stretch to 32GB but usually not.&lt;/p&gt;

&lt;p&gt;3. &lt;u&gt;A solid-state drive (SSD)&lt;/u&gt; &lt;/p&gt;

&lt;p&gt;We mentioned this in Part 1 of this series. These allow much faster access to the stored data, although you get less storage for the price.&lt;/p&gt;

&lt;p&gt;Aside from these three specs, there are many other factors to consider. For the screen you want at least &lt;em&gt;full HD&lt;/em&gt; resolution (1920x1080 pixels) and an &lt;em&gt;IPS&lt;/em&gt; panel, not TN (the ones where the colours look weird when you change the screen angle). Then you have battery life, ports, weight, and more to consider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That concludes our look at hardware. In the final part of this series we'll look at the world of operating systems and software 😀. First, a brief recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The key component of a computer is the motherboard, a printed circuit board containing the computer's main memory and components, including the CPU.&lt;/li&gt;
&lt;li&gt;The CPU is directed by the control unit, driven by the clock, and performs operations on data from RAM using the ALU.&lt;/li&gt;
&lt;li&gt;The type of CPU, amount and type of memory/storage and other factors have a big impact on the performance of the computer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;p&gt;* = particularly recommended for further study&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;* &lt;a href="https://www.youtube.com/playlist?list=PLH2l6uzC4UEW0s7-KewFLBC1D0l6XRfye"&gt;Crash Course Computer Science: Episodes 5, 7 and 17&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;* &lt;a href="https://www.youtube.com/watch?v=cNN_tTXABUA"&gt;See How a CPU Works - In One Lesson&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://computer.howstuffworks.com/motherboard.htm"&gt;How Motherboards Work - howstuffworks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.lifewire.com/tour-inside-a-desktop-pc-2624588"&gt;What Does the Inside of Your PC Look Like? - Lifewire&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.androidauthority.com/instructions-per-cycle-gary-explains-705127/"&gt;Instructions Per Cycle – Gary explains - Android Authority&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.howtogeek.com/177790/why-you-cant-use-cpu-clock-speed-to-compare-computer-performance/"&gt;Why You Can’t Use CPU Clock Speed to Compare Computer Performance - How-To Geek&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Computer_hardware"&gt;Computer hardware - Wikipedia&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>How Computers Work (Part 1)</title>
      <dc:creator>Josh Carvel</dc:creator>
      <pubDate>Thu, 29 Oct 2020 08:36:24 +0000</pubDate>
      <link>https://forem.com/joshcarvel/how-computers-work-part-1-2o9l</link>
      <guid>https://forem.com/joshcarvel/how-computers-work-part-1-2o9l</guid>
      <description>&lt;h2&gt;
  
  
  Intro ☕
&lt;/h2&gt;

&lt;p&gt;As a new developer with no computing background, it's possible to jump into coding without really knowing anything else about computers, besides being a typical user of them. But it can be confusing, and a little embarrassing, to be completely clueless on this topic.&lt;/p&gt;

&lt;p&gt;This three-part series takes an enormous topic and gives you the &lt;em&gt;absolute fundamentals&lt;/em&gt; that you could learn over a cup of coffee, using language you can &lt;em&gt;actually understand&lt;/em&gt;, so you have the confidence to make your home in the world of computers.&lt;/p&gt;

&lt;p&gt;This part looks at the fundamentals, Part 2 covers hardware and the CPU, and Part 3 covers software and operating systems.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using electricity ⚡
&lt;/h2&gt;

&lt;p&gt;As you know, modern computers are powered using electricity, which is conducted along copper wires in the computer's circuitry. When the computer receives some &lt;strong&gt;input&lt;/strong&gt; (keyboard press, mouse click, voice command etc.) that information is converted to electrical signals, and when we want some &lt;strong&gt;output&lt;/strong&gt;, the electrical signals are converted into something like light (displaying text and images on the monitor) or sound (via speakers).&lt;/p&gt;

&lt;p&gt;Measuring the voltage (pressure) of an electrical signal over time gives you lots of different values. A device that uses those values exactly as they are for the output is called &lt;strong&gt;analogue&lt;/strong&gt;, from a Greek word meaning 'proportionate', i.e. the processed values are proportional to the voltage. Old TVs and radios are an example.&lt;/p&gt;

&lt;p&gt;Modern computers are &lt;strong&gt;digital&lt;/strong&gt;. They don't just relay information, they give electrical signals &lt;em&gt;meaning&lt;/em&gt;. A signal under a certain threshold of voltage can be thought of as 'off', and over a certain threshold is 'on'. The data is reduced to just two values. We can also think of these values as the digits 0 and 1 (hence the term 'digital').&lt;/p&gt;

&lt;p&gt;It is possible to use more values in computers, so you may wonder why we just use two. For one thing, it is easier to identify the signals reliably when there are just two. But it also makes it easier to write logic - we'll get to this shortly.&lt;/p&gt;

&lt;p&gt;Almost unbelievably, with just two values we can do all the things modern computers can do. But how?&lt;/p&gt;

&lt;h2&gt;
  
  
  Encoding data 📖
&lt;/h2&gt;

&lt;p&gt;The first thing you can do with 0 and 1 is represent data.&lt;/p&gt;

&lt;p&gt;There is a number system based on these two numbers: &lt;strong&gt;binary&lt;/strong&gt; (from 'bi', meaning two). We use binary as a code for all the data we have. We can take words, numbers, audio, images - you name it - and convert it to binary, process it in a computer then convert it back again for the output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Numbers
&lt;/h3&gt;

&lt;p&gt;We use the &lt;strong&gt;decimal&lt;/strong&gt; number system (from 'deci', meaning ten), which has 10 digits (0 - 9). When we get to 9, we run out of digits. So we imagine columns of digits, that increase in multiples of ten each time (remember long addition/subtraction from school?). If we have '1' in our tens column, and '0' in our 1s column, we call that 'ten' and write it as 10.&lt;/p&gt;

&lt;p&gt;In binary, you run out of digits after 1! How do we count to 2? &lt;/p&gt;

&lt;p&gt;Well, we still have columns, but they are in multiples of two. We can have 1 in the 2s column, and 0 in the 1s column, which is written 10. It looks the same as ten in decimal, but it's the number two in binary. &lt;/p&gt;

&lt;p&gt;So you can represent decimal numbers in binary, it just takes a lot more columns, i.e. digits, to do it. This is how computers process numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Characters
&lt;/h3&gt;

&lt;p&gt;What about words, not to mention punctuation and symbols? &lt;/p&gt;

&lt;p&gt;All we need is a code where characters are swapped out for numbers. As computers developed, there were lots of different (incompatible!) ways of doing this. &lt;/p&gt;

&lt;p&gt;Thankfully, we now we have a &lt;em&gt;universal&lt;/em&gt; standard, &lt;strong&gt;Unicode.&lt;/strong&gt; It's a standard with a governing body (the Unicode Consortium) whose mission is to encode &lt;em&gt;all&lt;/em&gt; of the world's languages and symbols, old and new, so all computers can understand and process them the same way. &lt;/p&gt;

&lt;p&gt;Side-note: this is how we ended up with emojis. An engineer in Japan in the 90s encoded certain numbers as little pictures for some Japanese phones, so it eventually made its way into Unicode. Years later Apple added them to the iPhone, they became popular and now year after year, the Unicode Consortium begrudgingly adds new emojis to the standard to make them more universal and representative! 😃&lt;/p&gt;

&lt;p&gt;Unicode assigns a unique identifier (a number prefixed with U+) to every character in use, such as a lowercase 'a', for example. Computers encode that number in binary (usually using an encoding called &lt;em&gt;UTF-8&lt;/em&gt;), and the number is decoded on the way out so an 'a' can be shown on the screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pictures
&lt;/h3&gt;

&lt;p&gt;Digital pictures are divided into tiny picture elements. Merging 'pics' and 'el' (elements), gave rise to the term &lt;strong&gt;pixel.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;We will leave aside how screens actually display pixels, which can vary. When we talk about a pixel in a digital image, we're talking about an individual element of colour.&lt;/p&gt;

&lt;p&gt;Various shades of a primary colour such as red can be encoded as a number between 0 and 255, and thought of as one pixel. Since all colours can be made from a combination of primary colours (red, blue and green), if you combine the 256 possible values for each primary colour you get over 16 million possible colours! (256 x 256 x 256). Adding another value between 0-255 for transparency gives you over 4 billion.&lt;/p&gt;

&lt;p&gt;So computers just split images into a lot of pixels. The numerical values for each colour in each row can be stored in a list. The dimensions of the image are also stored so the computer knows where each row ends, and therefore can recreate the image.&lt;/p&gt;

&lt;p&gt;The more pixels are stored, the more realistic the image will look at its intended size, though you have to store more numbers so it takes up more memory space. Hence, the graphics on early computers with less memory space looked very 'pixelated', i.e. they had fewer pixels so the pixels were more noticeable to the naked eye.&lt;/p&gt;

&lt;p&gt;Bear in mind that with pictures and other types of files, computers can use various shortcuts and tricks to optimise the memory space they have available and make file sizes smaller. This is called &lt;strong&gt;compression.&lt;/strong&gt; For example, an image of a plain black square doesn't need the colour value of black repeated over and over in memory: the fact that it has 'x' many black squares could be encoded instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audio
&lt;/h3&gt;

&lt;p&gt;A sound wave can be recorded digitally by measuring by its amplitude at a fixed interval (the sample rate): a common method takes 44,100 samples per second. That gives you enough data points to recreate the sound wave. The amplitude values are of course stored in binary. &lt;/p&gt;

&lt;p&gt;Raw, uncompressed audio data is often stored in a specific format known as a .wav file. The audio can also be compressed to various degrees, for example to create an .mp3 file. mp3 files use &lt;em&gt;lossy&lt;/em&gt; compression - this means it discards and approximates some parts of the audio data to make the file smaller. Often the aim is to reduce the parts of the sound wave that are considered beyond the range of human hearing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Video
&lt;/h3&gt;

&lt;p&gt;Video is basically a sequence of images and can be stored as such. However, if left uncompressed the file size would be impractically large for the average video. Almost all video uses lossy compression for this reason. For example an .mp4 file may be up to 200 times smaller than the original file.&lt;/p&gt;

&lt;p&gt;The compression usually works by identifying parts of the image that haven't changed and only transmitting information about the parts that have changed. In many cases it will simply describe transformations that should be applied to these changed parts, rather than describing the whole image over and over. However, if this goes wrong and the transformations are applied over the top of the wrong part of the video, it can look very glitchy!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bits, bytes, and so on 🗄️
&lt;/h2&gt;

&lt;p&gt;Even at the low levels of computing, humans don't think about data in binary form. This is where units of information come in.&lt;/p&gt;

&lt;p&gt;In computing, 1 binary digit (a 1 or 0) is called a &lt;strong&gt;bit.&lt;/strong&gt; It represents one bit of data.&lt;/p&gt;

&lt;p&gt;It's not very useful on its own, so you will hear much more often about &lt;strong&gt;bytes.&lt;/strong&gt; Bytes are 8 bits. With that you can represent any number from 0 to 255, which is enough to store a standard English character or a colour value. That's one of the main reasons the number 8 was settled on for a byte.&lt;/p&gt;

&lt;p&gt;It's also convenient because it is a multiple of two, specifically 2&lt;sup&gt;3&lt;/sup&gt; (2 x 2 x 2 = 8). Multiples of two are used because binary is based on two digits. The next unit that engineers use is 2&lt;sup&gt;10&lt;/sup&gt;, which is 1,024. For convenience, it came to be known as a &lt;strong&gt;kilobyte&lt;/strong&gt;, since a kilo is 1,000 of something in the metric system and it was pretty close to that. &lt;/p&gt;

&lt;p&gt;However, people started using kilobyte to mean 1,000 bytes. This generated a debate that goes on to this day. And with the growth of computing capabilities, larger and larger units were needed. In the traditional definitions, we had 1,024&lt;sup&gt;2&lt;/sup&gt; bytes: a &lt;strong&gt;megabyte&lt;/strong&gt;, 1,024&lt;sup&gt;3&lt;/sup&gt; bytes: a &lt;strong&gt;gigabyte&lt;/strong&gt;, and now we even talk about &lt;strong&gt;terabytes&lt;/strong&gt; of data on storage devices (1,024&lt;sup&gt;4&lt;/sup&gt; bytes). &lt;/p&gt;

&lt;p&gt;But people, including technical people, still often use these unit names to mean multiples of 1,000 instead, which makes a big difference in how many bytes we are talking about for the larger units. Alternative terms have been suggested for the binary versions (e.g. 'kibibyte' for kilobyte), but it hasn't exactly caught on.&lt;/p&gt;

&lt;p&gt;If you think this is confusing, that's because it is. Sorry! Let's move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instructions 📜
&lt;/h2&gt;

&lt;p&gt;We now know how data is encoded as bytes of information, but none of that explains how computers &lt;em&gt;do&lt;/em&gt; anything with it. We need &lt;em&gt;instructions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To do this, we need a slight shift in thinking. Let's think of the value above a certain voltage (1) as &lt;em&gt;true&lt;/em&gt; instead, and the other value (0) as &lt;em&gt;false&lt;/em&gt;. With that simple shift, we can write logic using a branch of mathematics called &lt;strong&gt;boolean&lt;/strong&gt; algebra, after mathematician George Boole, which is all about performing operations on true and false values.&lt;/p&gt;

&lt;p&gt;We can do this because the flow of electric charge (current) in a computer's circuitry can be manipulated depending on whether a &lt;em&gt;true&lt;/em&gt; or &lt;em&gt;false&lt;/em&gt; value is received by components called &lt;strong&gt;transistors.&lt;/strong&gt; Transistors are made from silicon (hence 'Silicon Valley'), a metal that is a semi-conductor, which can be made to either conduct or not conduct electricity. We can think of it like a switch that is &lt;em&gt;on&lt;/em&gt; or &lt;em&gt;off.&lt;/em&gt; We pass a value from an input wire into the transistor, and get a value from an output wire.&lt;/p&gt;

&lt;p&gt;Clever placement of transistors in a circuit can be used to create components called &lt;strong&gt;logic gates.&lt;/strong&gt; The basic building blocks of computer logic are the following three logic gates: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NOT&lt;/strong&gt;: output is &lt;em&gt;true&lt;/em&gt; if input is &lt;em&gt;false&lt;/em&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the simplest boolean operation: NOT &lt;em&gt;true&lt;/em&gt; means &lt;em&gt;false&lt;/em&gt;, and vice versa. &lt;/p&gt;

&lt;p&gt;It uses just one transistor in a way that acts like a reversed switch. When the transistor is &lt;em&gt;off&lt;/em&gt;, current flows along its normal path to the output wire. But if it's &lt;em&gt;on&lt;/em&gt;, current is directed &lt;em&gt;away&lt;/em&gt; from the output wire.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AND&lt;/strong&gt;: output is &lt;em&gt;true&lt;/em&gt; if &lt;strong&gt;both&lt;/strong&gt; inputs are &lt;em&gt;true&lt;/em&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here one bit AND another bit must both be &lt;em&gt;true&lt;/em&gt;. Two inputs are fed into two transistors that interrupt the flow of current towards the output. Both transistors must be &lt;em&gt;on&lt;/em&gt; for current to flow through.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;OR&lt;/strong&gt;: output is &lt;em&gt;true&lt;/em&gt; if &lt;strong&gt;either&lt;/strong&gt; input is &lt;em&gt;true&lt;/em&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two transistors are used in parallel: just one needs to be &lt;em&gt;on&lt;/em&gt; for current to flow through to the output.&lt;/p&gt;

&lt;p&gt;We can use logic gates to make statements like: "if this bit of data is true, AND this other bit of data is NOT true, then send a true value to some other component". The value can be carried to the other component because the output wire would be fed into it.&lt;/p&gt;

&lt;p&gt;That particular sort of statement is quite common and so the arrangement of transistors it uses actually form its own logic gate, the &lt;strong&gt;XOR&lt;/strong&gt; ('exclusive or'), which we come to in Part 2.&lt;/p&gt;

&lt;p&gt;Of course the computer doesn't 'understand' the logic being expressed or the information passing through, but a human can design the circuitry in a way that is useful to us.&lt;/p&gt;

&lt;p&gt;Now imagine you have &lt;em&gt;billions&lt;/em&gt; of microscopic transistors in the circuitry. It sounds crazy, but that is exactly what is in your phone, computer or device right now. That's one reason it can carry out so many instructions so fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory 🧠
&lt;/h2&gt;

&lt;p&gt;Computer logic isn't all that useful if you can't keep values in memory and come back to them later. This is why your computer has memory.&lt;/p&gt;

&lt;p&gt;Memory is built from lots and lots of &lt;strong&gt;memory cells&lt;/strong&gt; that can hold onto a 0 or a 1. There are many ways this can be done, all using pretty complicated science, which I'll only briefly attempt to explain.&lt;/p&gt;

&lt;p&gt;Each method also has its own trade-offs. Here's some key characteristics memory can have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance/speed:&lt;/strong&gt; Memory which allows you to access values quickly is more expensive, and vice versa.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volatility:&lt;/strong&gt; If the memory needs a power source to hold values, it is &lt;strong&gt;volatile.&lt;/strong&gt; If not, it's called &lt;strong&gt;non-volatile&lt;/strong&gt; or &lt;strong&gt;persistent&lt;/strong&gt; memory. Confusingly, volatile memory may also just be called 'memory', and non-volatile memory 'storage'.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access method:&lt;/strong&gt; The main distinction is between &lt;strong&gt;random access&lt;/strong&gt; (access any value at any time) and &lt;strong&gt;serial access&lt;/strong&gt; (go through the sequence to get to a certain bit of data). For example, you can't jump to a certain section on a tape or CD, you have to fast-forward through the other bits first.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Computers use a range of different types of memory internally to balance these factors, and we also have external forms of storage for convenience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Primary memory
&lt;/h3&gt;

&lt;p&gt;We can call memory that the CPU accesses directly &lt;em&gt;primary memory&lt;/em&gt; (there are other definitions of 'primary' or 'main' memory but we'll stick to this distinction here).&lt;/p&gt;

&lt;p&gt;First we have the &lt;strong&gt;registers&lt;/strong&gt; built into the computer's processor chip (we cover the processor in Part 2), holding values such as the code corresponding to the next instruction to be processed. Then there are some &lt;strong&gt;caches,&lt;/strong&gt; either within the processor or a bit further away, storing values that the processor is likely to need.&lt;/p&gt;

&lt;p&gt;These types of memory are fast, random access and volatile. They use a circuit known as a &lt;strong&gt;latch&lt;/strong&gt; (it can latch onto one of two states). A latch uses logic gates and feeds outputs back into inputs in such a way that we can set and reset the value and the circuit will hold onto it. But even though the circuit can 'hold' a 1 or 0, i.e. a certain level of voltage, it can't do so if no current is supplied, hence it is volatile memory.&lt;/p&gt;

&lt;p&gt;Further away from the processor still, we have &lt;strong&gt;RAM.&lt;/strong&gt; This stands for Random Access Memory, though that doesn't really distinguish it from the types of memory just mentioned. Though one type of RAM does use latches, the most common type instead uses a device called a capacitor which maintains electrical charge, though the charge needs to be regularly refreshed. It's not as quick to retrieve values, but still fast enough to run software.&lt;/p&gt;

&lt;p&gt;RAM uses a grid with intersecting wires. 'Write enable' wires can be activated for a particular row and column in the grid: a memory &lt;strong&gt;address.&lt;/strong&gt; Then a 1 or 0 can be sent along a 'data' wire to be stored at those coordinates. Storing 1 bit at a time isn't very useful, but lots of grids can be used together, and the same address (i.e. coordinates) can be passed to each grid at once to store a value of say, 32 or 64 bits. The computer uses a different memory location to store all the addresses for when it needs to access the data again.&lt;/p&gt;

&lt;p&gt;There is also some form of non-volatile memory which contains important code the computer needs to start up (BIOS, covered in parts 2 and 3). Originally, this was stored with &lt;strong&gt;ROM&lt;/strong&gt; (read-only memory, in its original form), which couldn't be changed at all. Many variants of ROM were produced over time which allowed data to be deleted and written over in some way. The culmination of these efforts is &lt;strong&gt;flash memory,&lt;/strong&gt; invented at Toshiba, in which data is deleted and replaced in blocks, but fewer transistors are used so it is relatively cheap. This is still technically in the family of 'read-only' memory because you can't write an individual bit with one action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secondary memory
&lt;/h3&gt;

&lt;p&gt;Your computer needs some non-volatile memory to hold all your data and programs, which it loads into RAM every time computer starts up for quicker access. To this day, many computers use &lt;strong&gt;hard disk drives&lt;/strong&gt;, also just called hard drives. It's a magnetic disk sort of like a CD, in a case with an arm that reads data from the disk sort of like a vinyl record player. The data is stored on the disk using magnetism, where the 1s and 0s are represented by magnetic grains which are polarised one way or the other. &lt;/p&gt;

&lt;p&gt;Note that 'discs' (with a 'c' not a 'k') like CDs and DVDs, are similar but use light, not magnetism, to store 1s and 0s, and are known as &lt;em&gt;optical storage&lt;/em&gt;. CD-ROMs (read-only CDs) were commonly used to distribute software programs before we could download them over the internet.&lt;/p&gt;

&lt;p&gt;More recently, solid-state drives were invented: &lt;strong&gt;SSDs&lt;/strong&gt;. These use flash memory and have no moving parts - they can access and delete data quicker than hard drives and run more smoothly, with less noise. On the other hand, they are more expensive. &lt;/p&gt;

&lt;p&gt;You can also get external hard disk or solid state drives for storing a lot of data externally. If you have a smaller amount of data to store, you would probably use a &lt;strong&gt;flash drive&lt;/strong&gt; (a.k.a. 'USB stick' - USB describes the type of connection to the computer it uses). They use flash memory too and are an inexpensive and common form of external storage. The precursor to the flash drive was the floppy disk - a sort of mini hard disk read by a floppy disk drive in the computer. Though now out of use, they are immortalised in the form of the humble 'save' icon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully you now have a much better idea of how computers work. Part 2 will look at little closer at computer hardware and how instructions are carried out by the CPU. &lt;/p&gt;

&lt;p&gt;First, a brief recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our data is represented by binary states which we produce using physical phenomena such as voltage. We encode it then decode it again as output that has meaning to us.&lt;/li&gt;
&lt;li&gt;Computers use billions of transistors to process these binary values in circuitry we design to implement logic using boolean operations.&lt;/li&gt;
&lt;li&gt;We can record the values in memory, but there are many types with different characteristics - computers use a variety of types to achieve value for money.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;I cross-reference my sources as much as possible. If you think some information in this article is incorrect, please leave a polite comment or message me with supporting evidence 🙂.&lt;/p&gt;

&lt;p&gt;* = particularly recommended for further study&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;* &lt;a href="https://www.youtube.com/playlist?list=PLH2l6uzC4UEW0s7-KewFLBC1D0l6XRfye"&gt;Crash Course Computer Science: Episodes 3, 4, 6 and 21&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;* &lt;a href="https://www.youtube.com/watch?v=MijmeoH9LT4"&gt;Characters, Symbols and the Unicode Miracle - Computerphile&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=tITwM5GDIAI"&gt;Emoji and the Levitating Businessman - Computerphile&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/44,100_Hz"&gt;44,100 Hz - Wikipedia&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Byte"&gt;Byte - Wikipedia&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.thecalculatorsite.com/articles/units/is-a-kilobyte-1000-or-1024-bytes.php"&gt;Is a Kilobyte 1000 Or 1024 Bytes? - thecalculatorsite&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=wteUW2sL7bc"&gt;How do hard drives work? - TED-Ed&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Computer_memory"&gt;Wikipedia - Computer memory (and associated pages)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://computer.howstuffworks.com/rom.htm"&gt;How ROM Works - howstuffworks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://softwareengineering.stackexchange.com/questions/403361/why-is-flash-memory-considered-read-only-by-definition"&gt;Stack Exchange question on flash memory&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
