One of the biggest misconceptions I had early in my career was believing JavaScript itself handled things like:
- timers
- network requests
- DOM events
- file system operations
It turns out…
JavaScript engines like V8 don’t actually implement any of those features.
Take this example:
```js id="g7q2vn"
setTimeout(() => {
console.log("Hello");
}, 2000);
Most developers assume:
> JavaScript starts a timer and waits 2 seconds.
But that’s not what happens.
---
# What V8 Actually Does
V8 only handles:
* parsing JavaScript
* compiling JavaScript
* executing JavaScript
That’s it.
It has no built-in understanding of:
* timers
* HTTP requests
* mouse clicks
* file systems
* sockets
Those capabilities are provided by the runtime environment around V8.
Depending on where your code runs, that runtime could be:
* the browser
* Node.js
* Deno
* Bun
---
# So who handles `setTimeout()`?
When you call:
```js id="dx9s1f"
setTimeout(fn, 2000);
the flow looks roughly like this:
```text id="5ww7ik"
JavaScript
↓
V8 Engine
↓
Runtime Bindings
↓
Native C/C++ APIs
↓
Operating System
The runtime delegates the timer to native code.
In browsers:
* Web APIs handle timers internally
In Node.js:
* libuv handles timers and async I/O
The operating system performs the actual waiting.
Once complete:
1. the callback enters a queue
2. the event loop notices it
3. JavaScript eventually executes it
Which means:
➡️ the timer itself never ran inside JavaScript.
---
# This Explains Why JS Can Be Non-Blocking
JavaScript is single-threaded.
Yet it still handles:
* timers
* networking
* file reading
* user events
* streaming
without freezing constantly.
Why?
Because the expensive work happens outside the JS engine entirely.
JavaScript delegates async work to native systems and later receives completed tasks back through the event loop.
That mental model made async JavaScript finally “click” for me.
---
# The Bigger Insight
Most APIs developers use daily are not part of ECMAScript itself.
Examples:
| API | Provided by |
| -------------------- | -------------------------------- |
| `fetch()` | Browser/Runtime networking layer |
| `addEventListener()` | Browser event system |
| `console.log()` | Native stdout implementation |
| `fs.readFile()` | Node.js runtime |
| Timers | Browser APIs / libuv |
JavaScript alone is actually a very small language.
The real power comes from the runtime surrounding it.
And once you understand that distinction:
* event loops make more sense
* async/await becomes clearer
* performance debugging improves
* Node.js architecture feels less “magical”
Understanding runtimes changed the way I think about JavaScript completely.
What runtime/internal concept gave you the biggest “aha” moment?
Top comments (0)