Man vs Vibes

Yesterday I got nerd sniped into missing a workout. Frankenpenguin | Repository [2:30 PM] I discovered a blog post about vibe coded performance benchmarks for drawing a large number of rectangles on the HTML canvas. It was an interesting read and I was nodding along until I saw that all the Typescript benchmarks were better than the Rust ones. That can’t be right? [3:00 PM] My hunch was that most of the time was spent crossing the boundary between Rust and Javascript. This is something I’ve been burned by in the past. ...

August 22, 2025 3 min

Rust for JavaScript Engineers - Building Connect-4

Connect Four | Repository When I first wanted to learn Rust in 2017, I had no idea where to start. I had written some C starting back in 7th grade, however I wasn’t particularly good at it. The only language I was competent at was JavaScript, and there weren’t a lot of resources that bridged the gap between JavaScript and Rust. My hope with this series is that it’ll allow people familiar with JavaScript to incrementally adopt Rust. ...

August 19, 2025 7 min

Crossing the WASM

Flashlight | Perf comparison I recently talked to a group of engineers about integrating WASM into Javascript projects. I’ve integrated some Rust compiled to WASM into my projects a few times for various reasons ranging from performance to FOMO. I wanted to write down the architecture of a tiny game I wrote recently (with vanilla JS, HTML, and WASM), to demonstrate how to integrate very small parts of Rust using WASM into Javascript/TS projects. And eventually let it consume your entire life. ...

April 27, 2025 8 min

Component Coloring

Full disclosure, I hate frameworks of frameworks. How does a thing become so large that it needs other large things to prop it up? Especially if the scaffolding is opaque, and you can’t fathom why it does what it does. People complain about Webpack, but at least you could reason about the pipeline end-to-end. I’ve written UI apps in React since before the first major version was released. Things like a rich text editor, a photo-editor, some games etc. Back in my day, things had lifecycle methods.. And we injected an instance of V8 inside Laravel to SSR before it was mainstream. ...

January 22, 2025 5 min

Render, dude

Previous post | Photo-editor In the last post I built the UX component, but so far it doesn’t do anything other than being highly entertaining for cats. In this one I’m gonna write a render pipeline and by the end it still won’t makes sense how to connect the *cough* Dots. How old is this browser? In a past life I worked on an extremely cool photo editor that had a ton of features and 100k MAUs. It was built using WebGL, and it works on most browsers and most phones. So naturally I wanted to build this one on WebGPU which is available on less than 50% of the browsers that matter. ...

November 7, 2024 3 min

Monochrome Skittles

Photo-editor | Debugger There hasn’t been a lot of advancement in the ease of use of photo editing tools, and the barrier remains fairly high. Generative AI doesn’t do as much for photo editing as it does for full blown photo generation. So while the new iPhone and iOS launches have all been about Apple Intelligence, the feature that I’ve loved is the new style edit tool in the Photos app. Style edit is the much needed improvement in editing UX. It’s akin to Prometheus making fire accessible to mere mortals.. well mortals who own an iPhone 16. It’s a 2-dimensional slider that combines something they call a palette, and a general 3-channel curves tool. After testing a few styles I’ve concluded that what they call palette is just a look-up-table (LUT). Something colorists have used for decades to create a consistent visual language through color scheme. It’s an incredibly fast way to alter the look and feel of an image, but I digress. ...

October 21, 2024 6 min

No Sharp Corners

Pancakes I recently wrote an algorithm to make rounded rectangles for a grid with “holes”. The goal was to ensure that all the convex corners of the grid sections were rounded. I looked at existing implementations in softwares that I use daily, the most used are code editors. One of my favorite text editors Zed, renders text selections with beautifully rounded convex and concave corners. I couldn’t find a way to add external rounded corners without adding extra blocks at the beginning and end of each row, so decided to focus on internal corners, which led me to a somewhat elegant solution. The algorithm requires that I evaluate for each cell it’s neighboring cells, starting with the one to its left, and going clockwise at 45 degree increments. Here are the directions: [⇐, ⇖, ⇑, ⇗, ⇒, ⇘, ⇓, ⇙] For each corner I had to evaluate the three adjacent cells that it touches. Evaluating each corner cell clockwise staring from left-top makes it awkward as the last corner (left-bottom) requires that I look at the first direction (left) again. This would require array index shenanigans and I wanted to avoid that for the sake of obsession. However, if I duplicate the first direction at the end, it simplifies the code. The final directions array: [⇐, ⇖, ⇑, ⇗, ⇒, ⇘, ⇓, ⇙, ⇐] Now I can implement a sliding window of width three on top of this array which can account for all the corners. ...

August 25, 2024 6 min

Cirque Du Spritesheet

Photo-editor | Repository There isn’t much of a connection between Cirque Du Soleil and circular buffers. However, when I look at an animated gif of circular buffers the motion of the read and write heads reminds me of the wall of death. The write head’s ever advancing march over values that were yet to be read, but might never see I/O. An ongoing video game project of mine is where I experiment with Rust’s features to expand my understanding of the language. When I initially wrote Rasengan, a minimal circular buffer implementation, I had no plans on integrating it into the project. However, recently I wanted to implement a sort of blurred motion streak behind the video game character and Rasengan popped into my brain. ...

April 28, 2024 7 min

Streams of AGI

OpenAI’s SDK currently doesn’t support streaming for models GPT-3.5-Turbo or GPT-4. Yes, very sad, anyway. I decided to DIY this shit. Backend On Node you can use the fetch api and get a ReadableStream of bytes as a response. const openAIReadableTextStream = async (path: string, body: any) => { const response = await fetch(`https://api.openai.com/v1${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, }, body: JSON.stringify({ ...body, stream: true, }), }); if (!response.body) throw new Error('No response body.'); return response.body.pipeThrough(new TextDecoderStream()); }; Here we use the fetch api to make a call to the OpenAI server and get a ReadableStream<UInt8Array> in response. It needs to be decoded into plaintext so we do that with pipeThrough. The OpenAI streaming endpoints return the response as an event stream. ...

May 21, 2023 3 min

Calendar Tetris: Representation Matters

Live | Repository Too many events all at once Let’s assume that we want to stack two calendar blocks, block_1 starts at 12:30 AM and ends at 02:00 AM, and block_2 starts at 01:00 AM and ends at 01:30 AM. To simplify things however, let’s just use their start and end times as minutes i.e. an event that starts at 12:30 AM would just be starting at minute 30. To display the blocks we’re going to use their start time as a top offset. Assuming that the day starts at minute 0, a block that starts at minute 30 will have a 30 px offset from the top. Keeping the page height in sync with the minutes in the day will make the offset math convenient. ...

February 12, 2023 4 min