{"slug": "ai-code-mirroring-monomorphic-typescript-into-zig", "title": "AI Code Mirroring Monomorphic TypeScript into Zig", "summary": "A developer building a multiplayer particle-in-cell game engine has created a workflow in which an AI agent performs exact 1:1 ports of monomorphic TypeScript simulation functions into Zig, allowing individual functions to be swapped for native versions at runtime. Because the TypeScript was refactored into closure-based, arena-allocated code operating on typed arrays, the mirrored Zig is logically identical and can be ported deterministically, yielding speedups of 1x to 10x depending on the function. The pattern effectively turns the AI into an optimizing transpiler embedded in the project's CI/CD pipeline.", "body_md": "**Atwood’s Law** states that any application that can be written in JavaScript will eventually be written in JavaScript.\n\nYou may still think this was a joke. People probably laughed when it was first brought up, saying something like, “Yeah, some juniors will build some dumb thing in JS, and it’ll be slow because they’re bottom-feeders.” And the fact is, JS will never truly compare with native. To this day it doesn’t, not even WebAssembly in terms of raw performance. But the rug pull here is more obscene, so reader discretion is advised. Sorry, it’s not my fault; it’s just how things worked out.\n\nFor context, I’m building a game engine right now. The backend is one big, complex multiplayer PIC (particle-in-cell) simulator built on an ECS (entity component system), so it’s basically just particles and fields. It’s mostly written in TypeScript, with certain parts in a mix of Zig and Rust. All the complex math and heuristics live in the multithreaded simulation parts of the engine, and they’re written as… monomorphic TypeScript.\n\nOver a year ago, I came up with a new design to refactor parts of the engine into a monomorphic, closure-based style of TypeScript that compiles down to more optimized V8 machine code. Before that, I used a more class-based approach. This refactor was part of a larger batch meant to make the code easier to work with, more streamlined, cleaner, more performant, and more scalable overall. I took a very methodical approach using a vibe-coded assembly tester: I’d write certain functions, the AI would compile them to V8 assembly, tell me whether they looked OK, and run various microbenchmarks comparing different coding styles.\n\nYes, microbenchmarking is pure dopamine, and maybe some of it was a splurge. Instead of designing proper game mechanics, I got caught up in random engine heuristics. The process took me down some wrong rabbit holes of micro-optimization where I probably wasted time, and that’s on me, but I think I’m learning to control those urges better now.\n\nAnyway, I never expected my code to be as fast as native. I was happy to accept being 50–100% slower, since I only needed the simulation instance to be so big.\n\nWhat actually happened is that, because of my constant urge to refactor and optimize instead of doing actual work, some of the new monomorphic code organically became decoupled. Every method inside each function, all the way up to the top-level function, could be read as pure raw loads and stores on a typed array mixed with some floating-point operations (which, I guess, is true of *all* code). And because the engine has its own memory allocator built on one big arena (it even has its own defragmenter), all running on a custom ECS, every simulation function is just pure ops over that data.\n\nThat led to the next stage: I plugged my code into an agent and told it to do an exact 1:1 port of each TypeScript function into Zig. Instead of using my custom closure helpers for accessing and reading data, everything was flattened into raw array operations or aliased into `inline` functions. This gave me the ability to swap a function like `runResolvers` for a `runResolversNative` version whenever I wanted, in dev mode or production.\n\nSome functions can still diverge a bit. For example, the field solver has a SIMD path while still producing byte-exact output, and some math utilities use an optimized comptime flag for slightly faster float32 math on the native side.\n\nSo now I can benchmark the heavy-hitter functions and port them to Zig. Zig fits my closure-based, preallocated memory pattern perfectly, and because the mirrored code is identical in logic, order of operations, and memory reads and writes, the AI can port it deterministically with minimal reasoning. The performance boost ranged from 1x to 10x depending on what was being mirrored. Combined with basic parity unit tests, this pattern basically turned the AI into an extra optimizing transpiler in my CI/CD pipeline.\n\nSorry to everyone who builds Zig, but I’ll never need to write your language, because my source of truth already lives in monomorphic TypeScript closures over typed arrays. Lol.\n\nThe TypeScript code is clean, minimal, and easy to prototype with. There’s barely any actual TypeScript syntax; it’s mainly there for linting. I can see changes in real time with HMR, add debug logs, and visualize every scalar and vector on screen instantly. When I’m done tweaking and ready to build for production, I just run the transpile command. It’s easier to read, edit, and prototype for both me *and* the bot. Take this propulsion mechanic, for example:\n\nAfter all the engine upgrades, I went from being capped at 4k particles with heavy bonds and soft-body SDF collisions to running comfortably at 100k on my M4 MacBook Air dev machine. The engine also runs much better on AMD hardware because of how it handles data, CPU cache, and SIMD. On a new Zen 6 chip with more cache and higher clocks, it could maybe hit… millions? I haven’t tried.\n\nYou might also wonder why I didn’t offload some of the compute to the GPU. First, it’s expensive. Second, there’s simply no need. Being able to comfortably run a 10k-unit sim on a $65-a-year server is nice, and it scales well.", "url": "https://wpnews.pro/news/ai-code-mirroring-monomorphic-typescript-into-zig", "canonical_source": "https://lolblob.substack.com/p/ai-code-mirroring-monomorphic-typescript", "published_at": "2026-09-30 08:44:13+00:00", "updated_at": "2026-09-30 08:48:55.671336+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "mlops"], "entities": ["TypeScript", "Zig", "Rust", "V8", "WebAssembly"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/ai-code-mirroring-monomorphic-typescript-into-zig", "markdown": "https://wpnews.pro/news/ai-code-mirroring-monomorphic-typescript-into-zig.md", "text": "https://wpnews.pro/news/ai-code-mirroring-monomorphic-typescript-into-zig.txt", "jsonld": "https://wpnews.pro/news/ai-code-mirroring-monomorphic-typescript-into-zig.jsonld"}}