JavaScript Guide
Language internals, runtime, frameworks — how things work at code level
Language Internals
The Event Loop — Why setTimeout(fn, 0) Doesn't Execute Immediately
Execution order of Call Stack, Task Queue, and Microtask Queue
Why JavaScript is single-threaded yet async: the event loop pulls callbacks from Task Queue when Call Stack is empty. Promise .then goes to Microtask Queue, executing before regular Tasks.
Closures & Scope Chain — How Functions Remember Outer Variables
The internal structure of scope chains created by Lexical Environment objects
Closures capture and preserve the Lexical Environment at function creation time. When a function references outer scope variables, that Lexical Environment object survives garbage collection.
Prototype Chain — Inheritance Before class Existed
The relationship between __proto__, prototype, and Object.create()
JavaScript's class is syntactic sugar. Internally it works via prototype chains. An object's __proto__ points to its parent, and property lookup follows the chain upward.
Promise Internals — How then() Enters the Microtask Queue
Promise's 3 states and the execution mechanism of thenable chaining
Promise is a state machine with 3 states: pending/fulfilled/rejected. On resolve(), callbacks registered via then enter the Microtask Queue. async/await is syntactic sugar for Promises.
TypeScript
TypeScript Type System — It All Disappears After Compilation
What structural typing is and why it differs from Java's nominal typing
TypeScript types exist only at compile time — zero trace in runtime JavaScript. Unlike Java, compatibility is judged by "structure" not "name" (Structural Typing).
TypeScript Generics — Understanding T Once and for All
Using "types decided later" in functions, classes, and interfaces
T is a placeholder for "unknown type." T becomes a concrete type at call time. Without generics you'd use any, and any defeats the purpose of TypeScript.
Discriminated Unions — The Pattern Used Instead of Enums in TypeScript
Branch on a type field and TypeScript auto-narrows types in each branch
Pattern distinguishing union types via a common field (discriminant). switch/if branches auto-narrow types. Similar to Rust's enum + match.
Node.js
Node.js Event Loop — 6 Phases Different from the Browser
timers → pending → idle → poll → check → close, and where process.nextTick fits
Node.js event loop (libuv) cycles through 6 phases unlike browsers. setTimeout in timers phase, setImmediate in check phase, process.nextTick between all phases.
Node.js Streams — Processing Large Data Without Memory Explosion
How Readable, Writable, Transform + backpressure work
Reading a 10GB file with fs.readFile() explodes memory. Streams flow data in chunks keeping memory constant. Backpressure pauses producers when consumers are slow.
ESM vs CommonJS — Why require and import Are Different
Sync vs async loading, and what "type": "module" means
CommonJS (require) is sync loading, ESM (import) is async. Compatibility issues and solutions from both systems coexisting in Node.js.
Browser APIs
Web Workers — How to Use Multi-Threading in JavaScript
Structured Clone of postMessage and SharedArrayBuffer
Web Workers run JavaScript on a separate thread from main. No DOM access, communicate via postMessage. Offload heavy computation to Workers to keep UI responsive.
Service Worker Lifecycle — The Order of install, activate, fetch
The core of PWA — how offline caching works
Service Workers act as proxies between browser and network. Lifecycle: install → activate → fetch. Cache API stores resources for offline app functionality.
Intersection Observer — Detect Element Visibility Without Scroll Events
Performance-friendly implementation for lazy loading, infinite scroll, animation triggers
Intersection Observer fires callbacks when elements enter/exit the viewport. Better performance than scroll events + getBoundingClientRect(), executed at browser-optimized timing.
Popover API — Why You Can Now Build Tooltips Without JavaScript
A single popover attribute handles open/close, Esc dismissal, and accessibility automatically
Traditional tooltips required event listeners, state management, and manual ARIA synchronization. The Popover API replaces all of that natively. Just popover and popovertarget attributes handle open/close, Esc key, and keyboard navigation automatically.
Cookie, localStorage or sessionStorage — Three Questions Decide It
Why the folder tree went to a cookie and the scroll position to sessionStorage on the same screen
Does the server read it, must the first HTML show it, should it survive closing the tab. Ask in that order and almost everything sorts itself out. Secrets skip the questions and go to an HttpOnly cookie.
event.target vs currentTarget — The Bug That Only Fired on the Icon Stroke
Read data-* from currentTarget. SVG only takes clicks on painted strokes
When you read data-* from the element that owns the listener, use event.currentTarget. event.target is the innermost element actually clicked, so hitting the stroke of an SVG icon inside a button gives you a <path> and undefined.
Web Audio
Drums on setInterval Drift — Say "Play at 0.55s", Not "Play Now"
A lookahead scheduler: the JS timer only wakes things up, the audio clock does the timing
To keep time in the browser, don't play sounds directly in a timer callback. Wake every 25ms and schedule the next 0.1s of notes on the AudioContext clock. Under the same interference, setInterval wobbled between 114 and 136ms; the scheduled version stayed on its 0.5s grid.
"Left Ear Only" Means Two Things — StereoPanner Moves, ChannelSplitter Picks
pan: -1 doesn't drop the right channel, it folds it into the left. Measured
Earphones just play the L/R they receive. On the web, StereoPannerNode with pan: -1 moves the right channel into the left, while ChannelSplitter keeps only the left channel and drops the right. Both leave the right ear silent, but the left ear hears different things.
Test Audio With AnalyserNode, Not the Screen — Why All 17 Demos Looked Silent in a Background Tab
The drawing stops, the sound doesn't. Measuring the peak also catches clipping
If you check audio demos through browser automation by looking at a canvas waveform, requestAnimationFrame pauses in background tabs and everything reads as silent. Measure the peak from AnalyserNode's time-domain data instead and you catch both silence and clipping (above 1). It found three clipping cases for us.
Strudel Is Great for Beat Sketches, Weak for Finished Tracks — and Lazy Importing It Silently Drops Effects
Notes from embedding it in an app, plus the audio init trap that waits for "the next mousedown"
Strudel is strong at tweaking loops on the fly and weak at finishing a song or shipping inside a product. Its bundle (about 659KB) made us dynamic-import it on click, and then audio init waited for a mousedown that had already happened, so AudioWorklet effects like shape dropped out with no visible error. Firing one mousedown yourself fixes it.
WASM & 3D
"100% Local" Is About Your Media Files — The Price of Running Whisper and ffmpeg as WASM
What I found running rescript, an in-browser video editor
A "100% local" editor means your video and audio files don't go to a server, not that nothing leaves the browser. rescript ships with usage stats and crash reports on by default. Going local costs you a model download on first run and a SharedArrayBuffer requirement that needs COOP/COEP headers from the server.
.blend Won't Open on the Web — Blender to Web Is a Translation That Keeps Only What the GPU Can Eat
And why our 3D game ships with zero model files
A .blend file is close to a raw dump of Blender's memory, so the web can't open it. Exporting to glTF bakes or drops modifiers, Geometry Nodes, Cycles nodes and physics; the web gets triangles, buffers and PBR values and redraws the picture from scratch. Our 3D hide-and-seek game needed walking tied to distance, so it builds avatars from boxes in code instead of loading GLB.
Open Source Analysis
What Is background-removal-js? Remove Image Backgrounds to Transparent PNG in the Browser
IS-Net ONNX Model + WASM Inference + Canvas API — A Fully Client-Side Pipeline
background-removal-js (imgly) removes image backgrounds and returns a transparent PNG. It runs IS-Net via ONNX Runtime WASM in the browser. No server.
OpenGenerativeUI — How CopilotKit Recreated Claude's Visual Artifacts as Open Source
CopilotKit Deep Agents + LangGraph + Sandboxed iframe — The Pipeline Where AI Generates Charts, 3D, and Diagrams in Real Time
CopilotKit shipped an open-source reproduction of Claude's interactive visual artifact generation. Next.js 16 frontend + Python LangGraph agent generates HTML/SVG/Chart.js/Three.js code, rendered in sandboxed iframes. MIT license. 1.1K stars.
Pretext — A Pure JS Layout Library That Measures Text Height Without DOM
Get glyph widths from Canvas measureText(), then line calculation is pure arithmetic — zero layout reflow
To find out how many lines text takes in a browser, you'd normally use getBoundingClientRect or offsetHeight — but these force layout reflow. Pretext uses Canvas measureText() to get glyph widths directly from the font engine, then performs line calculation as pure arithmetic on cached width values. Zero DOM access. layout() runs in 0.09ms for 500 text batches. By chenglou (creator of React/Relay). ⭐ 7.1K.