How Code Actually Runs
Compiled vs. interpreted: translating a whole book upfront vs. interpreting line by line as you read aloud.
The Gap: How Does Text Become Action?
Here's something worth pausing on. Your computer's processor (the chip doing the actual work) only understands ones and zeros. Binary. Electrical signals that are either on or off. That's it.
So when someone writes print("hello"), how does that text turn into something a chip can execute? There's a translation step. And how that translation happens is one of the most fundamental differences between programming languages.
Compiled Languages: Translate the Whole Book First
Some languages (Go, Rust, C) take the translation approach of doing it all upfront. You write your code, then run a program called a compiler that reads every line and translates the entire thing into machine code (those ones and zeros) in one shot.
Think of it like translating a book from English to French. You hire a translator, hand them the complete manuscript, and they spend time working through every page. When they're done, you have a finished French edition. From that point on, anyone who reads French can pick it up and start reading instantly. No translator needed.
That's compilation. Slow upfront (the compiler needs to process everything), but once it's done, the result runs directly on the hardware. Fast. No middleman.
The catch? You compile for a specific machine. A version compiled for a Mac won't run on a Linux server without recompiling. You're producing a machine-specific translation.
Interpreted Languages: Translate Line by Line as You Read Aloud
Other languages (Python, JavaScript) take a completely different approach. Instead of translating everything upfront, they use an interpreter that reads and executes your code line by line, in real time.
Watch Python execute line-by-line in real time. It's translating just in time.
Think of a live interpreter at a conference. The speaker says a sentence in English, the interpreter immediately says it in French, then the speaker says the next sentence, and so on. No waiting for a full translation. You start getting output right away. But every sentence has to pass through the interpreter before the audience hears it.
This is more flexible. The same Python file runs on a Mac, a Linux server, or a Windows machine, as long as each has a Python interpreter installed. But it's slower, because the translation happens every single time you run the code. There's always a middleman in the loop.
Here's the core trade-off in one line: compiled = translate the whole book first, interpreted = translate line by line as you read aloud.
The compiler does heavy work upfront, but the result runs at full hardware speed.
| Compiled | Interpreted | |
|---|---|---|
| Speed | Fast execution | Slower execution |
| Startup | Slow (compile first) | Instant (no compile) |
| Portability | Machine-specific binary | Runs anywhere with runtime |
| Examples | Go, Rust, C, C++ | Python, JavaScript, Ruby |
| Used for | Systems, performance-critical | Web apps, scripting, AI |
Compiled translates everything first, then runs. Interpreted translates and runs one line at a time.
Most modern languages blur this line. JavaScript gets compiled "just in time" (JIT) by the V8 engine for speed. Java compiles to an intermediate format, then interprets that. But the core trade-off remains: translate everything upfront (fast execution, less portable) vs. translate on the fly (slower execution, more portable).
Runtimes: The Environment That Makes Code Go
When people say "install Python" or "install Node.js," they're installing a runtime. A runtime is the interpreter plus everything else your code needs to actually execute: memory management, access to files, network capabilities, the whole environment.
Node.js is the runtime for JavaScript (outside of a browser). Python has its own runtime. When you "run" a Python script, you're really asking the Python runtime to read your file, interpret each line, manage memory, handle errors, and produce output.
Without a runtime, your code is just a text file. The runtime is what brings it to life.
A company might run its team dashboard on Node.js (JavaScript runtime) inside Cloud Run, while its automated reporting service runs on Python's runtime. Different languages, different runtimes, same cloud infrastructure.
Static vs. Dynamic: Pre-Built or Built on Demand?
Now that you know how code runs, there's one more distinction that changes everything about how websites work: when the code runs.
A static site is a collection of pre-built HTML files sitting on a disk. When someone visits your URL, the server finds the file and hands it over. No code runs at request time. It's like handing someone a printed flyer. The flyer was printed yesterday, and everyone gets the same one.
A dynamic site runs code on every request to build the HTML on the fly. Like a custom-written letter for each person. The server reads the request, looks up data, assembles a page, and sends it back. More flexible, but more work.
In practice, there's a spectrum:
Fully static. Hand-written HTML files. What you see is what was written. No build step, no server logic.
SSG (Static Site Generation). Code runs once at deploy time to generate all the HTML pages. After that, they're served as static files. Fast for visitors, but the content only updates when you redeploy.
SSR (Server-Side Rendering). Code runs on the server for every request. The page is built fresh each time. Slower than static, but the data is always current.
SPA (Single-Page Application). The server sends a mostly empty HTML shell, and JavaScript running in the visitor's browser builds the entire page. The "server" barely does anything. The browser does the heavy lifting.
Real-World Examples: How Different Sites Work
Static HTML on Netlify. A documentation site is a collection of pre-built HTML files. No server, no code execution at request time. Netlify just serves the files. If someone wants to update a page, they edit the HTML and redeploy. Simple, fast, cheap.
SSR on Cloud Run. An analytics dashboard builds each page fresh on every request. When you load it, Cloud Run spins up, queries a database and an analytics API for the latest data, assembles the HTML, and sends it to your browser. You always see current numbers.
SSG on Vercel. A marketing website uses static site generation. At deploy time, Next.js builds every page into static HTML. Visitors get near-instant load times because there's no server-side work per request. When the content team updates the CMS, a rebuild generates fresh pages.
The choice between static and dynamic comes down to one question: does the content change between requests? If everyone sees the same thing, go static. If each visitor might see different data, go dynamic.
Further Reading
Concepts from this lesson:
- Compiled vs Interpreted Languages (freeCodeCamp): clear explainer with diagrams
- What is Node.js? (Node.js): official intro to the JavaScript runtime
- Static vs Dynamic Websites (Cloudflare): when to use which approach