How code becomes a running program
Every tool a developer uses does one job in a single chain: you write text files, a program runs them, Git records them, GitHub shares them, and GitHub Actions checks them. This lesson draws that chain once, installs the tools on Windows or macOS, and ends with your first script printing a store's sales total.
By the end you can
- Explain what a runtime is, and why the same JavaScript file behaves differently in a browser and in Node.js
- Say what "install", "build" and "run" each mean in a real project
- Place VS Code, the terminal, Git, GitHub and Actions on one map, and know which Kolom course covers each
- Install VS Code, Git and Node.js LTS on Windows or macOS, and prove they work with four commands
- Write, run, break and fix a small Node script, and run it again through an npm script
The everyday picture
Think of a busy restaurant kitchen. The recipe is written on paper. It does nothing by itself. A cook reads it line by line and does the work: cut, fry, plate. The cook works inside a kitchen that supplies gas, water, knives and a fridge. The cook never builds a stove; he asks the kitchen for one.
Before opening, the owner sends the menu to a printer. The printer turns rough notes into a clean card that customers can read quickly. Nobody cooks from the menu card, but nobody orders without it.
Software has the same four roles. Your source code is the recipe. The runtime (Node.js, or the browser) is the cook. The operating system (Windows, macOS, Android on a store's handheld scanner) is the kitchen. A compiler or bundler is the printer: it turns code into a form that is faster or easier to run. Keep these four in mind and most confusing error messages start to make sense, because each one comes from one of the four.
A project is a folder of files
Open any repository your team owns, say partner-api (the service behind Mangrove's Partner app), and you find a folder. Inside are more folders and files. That is the whole truth of the project. The code, the settings, the list of libraries it needs, the test cases and the build instructions are all files. If something is not in a file, the computer does not know it.
Most of these are text files: .js, .ts, .json, .md, .yml. You can open them in any editor, and Git can show exactly which line changed. The rest are binary files: images, fonts, an Android .apk. Git stores them too, but it cannot show a useful line-by-line difference.
An editor changes text files. An IDE is an editor with running, debugging and testing built in. VS Code starts as a fast editor and becomes IDE-like through extensions. That is why two developers' VS Code windows can look very different. VS Code essentials and VS Code for teams, the last two lessons of this course, show how a team makes them look the same where it matters.
Quick check
For which file can Git show you exactly which line changed?
package.json is a text file, so Git can compare it line by line. An .apk and a .png are binary files. Git still stores every version of them, but a diff can only tell you that they changed, not what changed.
Engines, runtimes and compilers
Your CPU only understands machine code, numbers that mean "add these", "jump there". JavaScript is text. Something must stand between them. That something is a JavaScript engine. V8 is the engine inside Chrome and Node.js. Safari uses JavaScriptCore. React Native apps, such as Mangrove's Store app in the store-app repo, use Hermes by default.
An engine alone can only do maths and logic. It cannot read a file, open a network connection or draw a button. A runtime adds those abilities. The browser adds the page (the DOM), fetch, clicks and timers. Node.js adds files, network servers, the process and its environment variables. Same engine, different kitchen. So document exists in a browser and is undefined in Node, and require('fs') works in Node and fails in a browser.
How the engine turns text into machine code varies. An interpreter runs code statement by statement. A compiler translates code ahead of time. Modern engines do both. V8 turns your file into bytecode and runs it, then compiles the functions that run often into machine code while the program is running. This is called JIT compilation. Hermes moves part of the work earlier: it compiles JavaScript to bytecode during the app build, so the app starts faster on a cheap phone or scanner.
Quick check
Your script reads a CSV file from disk. Which part makes reading the file possible?
An engine only runs the language: maths, logic, functions. Reading files is an ability the Node.js runtime adds around the engine. That is why the same engine inside Chrome cannot open a file on your disk.
fetch, Node offers files, the network and environment variables.Install, build, run
Engineers use these three words all day. Each one is a concrete step.
Install means downloading the libraries the project depends on. A Node project lists them in package.json. When you type npm install, npm reads that list, downloads each dependency from the npm registry, and puts them in a folder called node_modules. That folder can hold hundreds of megabytes, and you can delete it at any time, because npm install recreates it from the list. This is why it never goes into Git (Everyday Git shows how to keep it out).
Build means turning source files into the files you actually ship. For partner-api that may be TypeScript compiled to plain JavaScript (TypeScript for a JavaScript team). For mangrove-dashboard, the back-office web app, it is a bundler joining hundreds of files into a few small ones. For store-app it is a JavaScript bundle compiled to Hermes bytecode and packed into an Android app. Some projects, like a small Node script, need no build at all.
Run means starting a runtime and pointing it at an entry point: node hello.js, or npm start, which runs whatever command the project stored under the name start. A running program is called a process. When it ends, it returns an exit code: 0 for success, anything else for failure. The next lesson, The terminal without fear, uses that number a lot.
Quick check
A teammate types npm start and the API begins answering requests. Which of the three steps is that?
Starting a process from an entry point is run. npm start looks up the command stored under start in package.json and starts it. Install would have downloaded libraries, and build would have produced files to ship, without starting anything.
Think first: you delete node_modules by accident. What did you lose?
Nothing that matters. package.json lists the libraries and the lockfile (package-lock.json) records their exact versions. Running npm install downloads the same files again. Work you lose is work that lives only in a file nobody committed, or only on one laptop. That is the problem Git solves.
Where each tool fits
People mix up these names, so here is the whole Developer track on one map. VS Code is where you edit files. The terminal is where you type commands, such as running Node or Git. Git is a program on your laptop that takes snapshots of the project folder, so you can see every change and go back to any point. It works with no internet at all. GitHub is a website that keeps a shared copy of the repository, where teammates review each other's changes. GitHub Actions is a GitHub service that runs your tests on a fresh machine every time someone pushes.
Git and GitHub are often confused. Git is the tool, like a shop's ledger book. GitHub is one place to keep a shared copy of the ledger, like head office. GitLab and Bitbucket do the same job as GitHub, and Git is identical with all three.
Quick check
You are on a long flight with no internet. Which of these can you still do?
Git runs entirely on your laptop, so committing needs no network. Pushing, and anything GitHub Actions does, happens on GitHub's servers, so it waits until you are online again.
git push sends them to GitHub, where the team reviews a pull request (PR). Actions tests every push and reports pass or fail on the PR. A passing build can be deployed to the stores.| Tool | What it is | Where it runs | Where to learn it |
|---|---|---|---|
| VS Code | Editor that extensions turn into a full workbench | Your laptop | VS Code essentials, VS Code for teams |
| Terminal and shell | A text window (terminal) running a program that reads your commands (shell) | Your laptop, also inside VS Code | The terminal without fear |
| Git | Version control: snapshots, branches, undo | Your laptop, offline | The Git from the Inside course, from What Git really is |
| GitHub | Hosting for shared repositories, pull requests, issues | The cloud (github.com) | The GitHub for Teams course, from Remotes, clone, push and pull |
| GitHub Actions | Runs your checks and deployments automatically | Fresh cloud machines | Continuous integration, Deploying and securing |
| Node.js and npm | JavaScript runtime, and its package manager | Your laptop and servers | JavaScript Deep Dive, from JavaScript in one sitting, then Node.js and npm |
Build it
Install the four tools, prove they work, then write, break, fix and run your first script. This course uses Node.js 24, the current LTS (long-term support) line; Node 22 also works for everything here. If you want to practise reading and fixing an error before you install anything, the first Practice task below runs in your browser.
-
Install VS Code
Download it from code.visualstudio.com. On Windows, use the User installer (no admin rights needed) and keep Add to PATH ticked, which it is by default. On macOS, drag
Visual Studio Code.appinto Applications, open it, press Cmd+Shift+P and run Shell Command: Install 'code' command in PATH. On both, close and reopen any terminal afterwards so it sees the new PATH. -
Install Git
On Windows, install Git for Windows from git-scm.com. It also installs Git Bash, a bash shell for Windows. Keep the defaults, except on two screens: choose Use Visual Studio Code as Git's default editor, and on the initial branch screen choose Override the default branch name and type
main. On macOS, typinggit --versionoffers to install Apple's Command Line Tools, which include Git. Homebrew gives you a newer Git.PowerShell# Optional: install from the terminal instead of clicking installers winget install --id Microsoft.VisualStudioCode -e winget install --id Git.Git -e --source wingetTerminal# Optional: Homebrew (from brew.sh) installs and updates both brew install --cask visual-studio-code brew install git -
Install Node.js LTS
The simplest way is the LTS installer from nodejs.org. It installs
node,npmandnpxtogether. Many teams use a version manager instead, because different repos need different Node versions. Here is fnm, one of the common ones. Node.js and npm, in the JavaScript in the Real World course, covers.nvmrcand pinning versions per repo.PowerShellwinget install --id OpenJS.NodeJS.LTS -e # option A: plain installer winget install Schniz.fnm # option B: version manager # then add the fnm line to your PowerShell profile, creating the file if needed if (-not (Test-Path $PROFILE)) { New-Item $PROFILE -Force } Add-Content $PROFILE 'fnm env --use-on-cd --shell powershell | Out-String | Invoke-Expression' # open a new PowerShell window, then: fnm install 24Terminalbrew install fnm # add the next line to ~/.zshrc so every new terminal can find fnm's Node echo 'eval "$(fnm env --use-on-cd --shell zsh)"' >> ~/.zshrc source ~/.zshrc fnm install 24 # the first version you install becomes the default -
Prove all four work
Open a new terminal: PowerShell or Git Bash on Windows, Terminal on macOS. These commands are the same in every shell. Your numbers will be the same or newer.
Terminalcode --version git --version node -v npm -vOutput1.140.0 07f806f999227108933c2e30515b26eecc1fda74 arm64 git version 2.55.0 v24.21.0 11.19.0code --versionprints three lines: the VS Code version, the exact source commit it was built from, and your CPU type (x64on most Windows laptops,arm64on Apple Silicon Macs). On Windows, Git's version ends in something like.windows.1. If a command prints "not recognized" or "command not found", the install did not reach your PATH. Close every terminal, open a new one and try again. The next lesson explains why this works. -
Write hello.js
Create a folder called
hello-sales, then open it in VS Code with File: Open Folder... from the Command Palette (Ctrl+Shift+P on Windows, Cmd+Shift+P on macOS). Add a file namedhello.jswith this code. Prices are stored in cents, as whole numbers, because computers store decimals like 0.1 inexactly: in Node,0.1 + 0.2prints0.30000000000000004. Working with data: arrays, Maps, JSON, dates and money explains why.JavaScript// hello.js: add up today's sales for one store. // Prices are whole cents (100 cents = 1 dollar), so the maths stays exact. const sales = [ { articleCode: 'A-1001', name: 'Basmati rice 5 kg', qty: 2, unitPriceCents: 850 }, { articleCode: 'A-2040', name: 'Sunflower oil 1 L', qty: 3, unitPriceCents: 379 }, { articleCode: 'A-0007', name: 'Eggs, 12 pcs', qty: 1, unitPriceCents: 300 }, ]; let totalCents = 0; for (const line of sales) { totalCents += line.qty * line.unitPriceCents; // quantity times unit price } console.log(`Store S-014, ${new Date().toDateString()}`); console.log(`Lines sold: ${sales.length}`); console.log(`Total: $${(totalCents / 100).toFixed(2)}`);An
articleCodeis a product code: Mangrove's systems call each product an article.S-014is one of its stores. -
Run it in VS Code's terminal
Open the integrated terminal with Ctrl+` (the backtick key, left of 1; the same keys on macOS). It opens in your project folder. Run the file with Node:
Terminalnode hello.jsOutputStore S-014, Wed Oct 07 2026 Lines sold: 3 Total: $31.37 -
Break it on purpose, and read the error
Change
salestosalein theforline, save, and run it again. Read errors from the top. The first line gives the file, the line number (10) and the code, with a caret under the problem. The error name and message say what went wrong. The lines starting withatare the stack trace; the top one points to your file at line 10, column 20, and the rest are Node's own code. Fix the typo and run it again.Output/Users/you/work/hello-sales/hello.js:10 for (const line of sale) { ^ ReferenceError: sale is not defined at Object.<anonymous> (/Users/you/work/hello-sales/hello.js:10:20) at Module._compile (node:internal/modules/cjs/loader:1929:14) at Object..js (node:internal/modules/cjs/loader:2060:10) at Module.load (node:internal/modules/cjs/loader:1651:32) at Module._load (node:internal/modules/cjs/loader:1443:12) at wrapModuleLoad (node:internal/modules/cjs/loader:261:19) at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) at node:internal/main/run_main_module:33:47 Node.js v24.21.0 -
Make it a project with an npm script
npm init -ywrites apackage.jsonwith default values.npm pkg setadds a script namedstart. Now anyone who clones the folder can run it withnpm start, without knowing the file name. Real projects use the same idea fornpm test,npm run buildandnpm run lint.Terminalnpm init -y npm pkg set scripts.start="node hello.js" npm startOutputWrote to /Users/you/work/hello-sales/package.json: { "name": "hello-sales", "version": "1.0.0", "description": "", "main": "hello.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "type": "commonjs" } > hello-sales@1.0.0 start > node hello.js Store S-014, Wed Oct 07 2026 Lines sold: 3 Total: $31.37The two lines starting with
>are npm telling you which script it runs. That is how you find out whatnpm startreally does in a repo you have never seen.
Bring it to your team
These questions show whether a project can be built by anyone, or only by the person who wrote it.
- "If I clone this repo on a new laptop today, which commands do I run to see it working, and are they in the README?"
- "Which Node.js version does this repo need, and where is that written down?"
- "What exactly happens between merge and the app on users' phones or our stores' scanners: which build step, which machine, and how long does each take?"
- "Which
npmscripts do we use every day, and what does each one really run?" - "Is this change in code, in configuration, or in data? Who can change each one without a release?"
Red flags
- Only one person's laptop can build a release.
node_modulesor build output committed to the repository.- Nobody knows which Node version production runs.
- "It works on my machine" said twice in the same week about the same project.
Practice
Read the error, then fix the till total
This function should return the total of a list of sale lines, in cents. Each line looks like { qty: 2, unitPriceCents: 850 }. Press Run first and read the message: it is the same kind of error as in step 7 of Build it. Fix that, run again, and fix the second bug the tests reveal.
function saleTotalCents(lines) {
let total = 0;
for (const line of sale) {
total += line.qty * line.unitPrice;
}
return total;
}
test('adds quantity times unit price for every line', () => {
const lines = [
{ qty: 2, unitPriceCents: 850 },
{ qty: 3, unitPriceCents: 379 },
{ qty: 1, unitPriceCents: 300 },
];
expect(saleTotalCents(lines)).toBe(3137);
});
test('a single line is quantity times unit price', () => {
expect(saleTotalCents([{ qty: 4, unitPriceCents: 250 }])).toBe(1000);
});
test('an empty list of lines totals 0 cents', () => {
expect(saleTotalCents([])).toBe(0);
});
Show a solution
function saleTotalCents(lines) {
let total = 0;
for (const line of lines) { // the parameter is called lines, not sale
total += line.qty * line.unitPriceCents; // the field is unitPriceCents
}
return total;
}Write the "Getting started" part of a README
Using your hello-sales project from Build it, write a short README.md section that a new teammate could follow on a fresh laptop and see the script working. Imagine they have never seen the project and you are not there to help.
- It names the tools needed and the Node.js version (for example "Node.js 24 LTS").
- The commands appear in order, each one copyable, with no
$prompt in front. - It uses
npm start, so the reader does not need to know the file name. - It shows what success looks like: the output the reader should expect.
- It says what to do if a command is "not found" (open a new terminal).
Show a model answer
## Getting started
You need Git, VS Code and Node.js 24 LTS (Node 22 also works).
Check them in a new terminal: `git --version`, `node -v`, `npm -v`.
1. Get the code and open the folder:
`git clone <repo link> hello-sales`, then `cd hello-sales`
2. Run it:
`npm start`
You should see three lines, ending with a total such as `Total: $31.37`.
If a command says "not found", close the terminal, open a new one and try again.Seven short lines are enough. The point is that a stranger can go from nothing to a working script without asking anyone.
Check yourself
A script uses document.querySelector and works in Chrome, but in Node it fails with "document is not defined". Why?
Chrome and Node both use V8, so the engine is the same. The page (the DOM) is something the browser runtime adds around the engine. Node adds different things: files, the network, environment variables. No build step or file extension gives Node a page.
Which sentence about Git and GitHub is correct?
Git is a standalone program. You can commit for months with no network and no account. GitHub is a hosting service built around Git. GitLab and Bitbucket do the same job, and the Git commands are identical with all of them.
A teammate says "I ran the build". In a NestJS project like partner-api, what most likely happened?
Downloading dependencies is install. Starting the server is run. Uploading is push. Build is the step in between that turns source into what you ship; for a TypeScript API that is mainly compiling to JavaScript.
Flashcards
Key takeaways
- A project is a folder of files. Code, settings and the list of dependencies are all text files, and that is what Git tracks.
- An engine (V8, Hermes) executes JavaScript. A runtime (browser, Node) adds what the code can ask for: the page, or files and the network.
- Install downloads dependencies, build turns source into what you ship, run starts a process from an entry point.
- VS Code edits, Git snapshots on your laptop, GitHub shares and reviews, Actions tests every push.
- Four commands prove your setup:
code --version,git --version,node -v,npm -v.
Sources
- Node.js Learn, the OpenJS Foundation: guides to Node, npm and the runtime
- Visual Studio Code documentation, Microsoft
- Pro Git, Scott Chacon and Ben Straub, free online