Skip to main content

Single-threaded JS

1. What "single-threaded" means

Single-threaded means that all JavaScript code runs in a single thread, on a single "executor" (the main thread).

That is:

  • only one JS instruction can run at a time;
  • there is no parallel code execution (unlike C++, Java, Go);
  • if one function occupies the thread, all other code waits for it to finish.

2. Why JS was made this way

JavaScript was created for the browser, in order to:

  • safely interact with the DOM (so there are no conflicts from simultaneous changes);
  • be simple and predictable, and not require complex synchronization (mutexes, locks, and so on).

The idea: "one thread = one owner of the DOM = no data races".

3. How this works in practice

Example

javascript
console.log('A'); setTimeout(() => console.log('B'), 0); console.log('C');

Result:

javascript
A C B

Why:

  • JS runs console.log('A'), then setTimeout(...), then console.log('C');
  • setTimeout is an asynchronous operation, it goes to the browser's (or Node's) web API;
  • once the timer finishes, the callback returns to the task queue;
  • the event loop puts the callback back on the main thread once it's free.

4. What the event loop does

The Event Loop is the "coordinator" that makes sure the main thread doesn't sit idle.

How it works:

  1. JS runs code from the call stack (the main thread).
  2. When it hits an asynchronous operation, it goes to an external Web API (network requests, timers, promises).
  3. Once finished, these operations land in the task queue.
  4. The event loop checks: if the stack is empty, it takes the next task from the queue and runs it.

This way, JS looks "asynchronous", but under the hood it is still single-threaded.

5. But don't the browser and Node.js do many things at once?

Yes, but not JS itself!

Asynchrony is implemented through external APIs, which run in other threads or processes:

  • timers (setTimeout, setInterval) are handled by a separate subsystem;
  • network requests (fetch, XMLHttpRequest) are handled at the browser level;
  • the filesystem and sockets (in Node.js) run through the libuv thread pool;
  • once finished, these tasks are returned to the main JS thread.

The JS engine itself (for example, V8) is single-threaded. The runtime environment (Browser API, Node.js) is multi-threaded.

6. What blocks single-threaded JS

Since everything runs in a single thread:

  • long loops (for, while);

  • large JSON.parse calls;

  • recursive computations;

  • synchronous file operations (in Node.js)

  • block the event loop, and the interface or server "freezes".

7. How the "single-threaded" problem in JS is solved

ApproachWhere it's usedWhat it does
Web WorkersBrowserRun JS code in a separate thread without access to the DOM
Worker ThreadsNode.jsParallel execution of CPU-bound tasks
Async/awaitEverywhereMakes I/O operations non-blocking
Offloading to WebAssemblyEverywhereHeavy computations, moved into native code

8. A simple analogy

Imagine a cafe:

  • One chef (the JS thread).
  • Several waiters and couriers (Web API, async tasks).
  • The chef cooks one dish at a time, but the waiters keep working.
  • Once it's ready, the waiters bring the order back to the chef (the event loop brings the task back).

Brief summary

TermMeaning
Single-threadedJS runs code in a single thread
AsynchronyImplemented through external APIs and the event loop
Event loopCoordinates the execution of asynchronous tasks
Blocking operationsCan "freeze" the UI/server
Solutionsasync/await, Workers, WebAssembly

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.