Viscosity
Review

Viscosity’s internals, and how to learn compiler engineering from scratch

By Tariq Shams

Array of structs on top: each particle keeps x, y and vx together. Struct of arrays below: all the x values sit together, then all the y values, then all the vx values. How you write it: an array of objects What Viscosity can turn it into: a struct of arrays x y vx: the same colour always means the same field

Having found no project doing something which I expected to be deterministically possible, I created Viscosity, the world’s first automatic, ahead-of-time Array of Structures to Structures of Arrays compiler for any language, starting with JavaScript and TypeScript, with more languages to come. However, I didn’t just want to create documentation. I wanted others to be able to learn how to create something like this, regardless of their engineering background. So I wrote a book with the help of Opus 5.5 (2026 frontier LLMs are great for writing technical documentation, no surprise given the training corpus, and given that programming is uniquely suited to reinforcement learning with verifiable rewards) that takes someone with beginner-level programming experience, or someone who is already an expert engineer (it doesn’t matter), to being able to write their own programming language, a compiler, and Viscosity itself. You build it all in TypeScript first (which the book teaches) and then again in Rust (which the book also teaches), in the spirit of how Robert Nystrom wrote Crafting Interpreters (an excellent book which I wish I had found when I took my compilers class in undergrad, where I had to read a theoretical compiler book to tease out the implementation details).

Given that AI is rapidly extending the capabilities of us engineers, I didn’t want to just create Viscosity, but rather a community that learns from each other, with this book being a start.

Additionally, while you may command and direct LLMs and their agentic harnesses to do things for you, never outsource your understanding and your reasoning; the knowledge you gain will help you connect dots years from now.

After you read this book, I believe you will be able to make meaningful contributions to Viscosity and make software faster for humanity (and hopefully enjoy the journey as well).

Tariq

Contents

200 of 200 chapters written so far. Planned chapters are greyed out.

  1. Part I. JavaScript for engine builders Days 1–4
    Track A · TypeScript

    Functions, arrays, objects, references, closures, classes, strings, errors, modules, TypeScript, testing, and the raw bytes behind typed arrays.

  2. Part II. How machines run code Days 5–6

    Memory, CPU caches and cache lines, prefetching, SIMD, how JavaScript stores numbers and objects, AoS vs SoA measured, and how to benchmark honestly.

  3. Part III. A tree-walking interpreter Days 7–11

    Build Drip, a small language: grammars, scanning, recursive descent and Pratt parsing, evaluation, environments, closures, resolution, classes.

  4. Part IV. A bytecode virtual machine Days 12–15

    Compile Drip to bytecode and run it on a stack VM: hash tables, string interning, call frames, upvalues and a garbage collector.

  5. Part V. Inside real JavaScript engines Days 16–18

    V8’s tiers, shapes and inline caches, elements kinds, speculation and deoptimization, garbage collection, other engines, and the columnar-array research.

  6. Part VI. The compiler middle-end Days 19–22

    Intermediate representations, control-flow graphs, dominators, SSA, dataflow analysis, classic optimizations, alias and escape analysis, and pass managers.

  7. Part VII. Building Viscosity Days 23–28

    The plugin architecture, VIR, the JavaScript front-end, collection discovery, safety analysis, the cost model, SoA and AoSoA code generation, materialization, PGO, explain, and testing it all.

  8. Part VIII. Beyond JavaScript Days 29–30

    A Python front-end plugin, WebAssembly as a target, the research frontier, and shipping Viscosity.

  9. Part IX. Rust for TypeScript developers Days 31–36
    Track B · Rust

    Ownership and borrowing drawn as pictures, structs, enums and match, traits and generics, lifetimes, testing, smart pointers, arenas, memory layout and WebAssembly.

  10. Part X. Drip in Rust Days 37–42

    Rebuild the Drip bytecode VM in Rust, with arenas and a garbage collector, and benchmark it against the TypeScript versions.

  11. Part XI. Viscosity in Rust Days 43–49

    Port the engine: VIR with typed indices, trait-based plugins, the oxc front-end, analyses, code generation, WebAssembly, and differential tests against the TypeScript engine.

  12. Part XII. Shipping Days 50

    The command-line interface, release builds, the TypeScript vs Rust benchmark matrix, and the capstone.