Hi! I'm Jeremiah
a web developer turned systems programmer
I'm looking for work. In a hurry? See my resume. Want my full story? Read on.
Google hired me when I was nineteen. I got into programming early because I loved video games and wanted to make them. It so captivated me that by my high-school graduation, I wanted to do it full-time. So instead of college, I took a chance on a faster path. I attended a coding bootcamp called App Academy. They filled gaps in my knowledge and prepared me for technical interviews. Then came months of job searching. I won't forget the tension answering the recruiter's phone call after my Google interviews. To my delight, they made an offer.
For the next four years, I worked at Google Pittsburgh making UIs for Vertex AI products. I had fun, met incredible people, and learned to work within and across teams. It was my dream job. But eventually, I would dream bigger.
Before, I didn't see much point in low-level systems knowledge except for curiosity's sake. I thought myself pragmatic—I'll take the shortest path to my goal. I thought myself humble—the authors of popular libraries and frameworks are better than me. If I can get better results faster using code I don't fully understand, I'd be foolish not to. Now I realize, that's an awfully big if.
One day I saw a talk on YouTube, "Making Game Programming Less Terrible" by Jonathan Blow. He criticized Photoshop's "New Document" menu taking one second to load. Was this really noteworthy? I encountered larger delays often, many in the product I worked on.
"Imagine if the people who programmed this were trying to make VR games. Like, everybody would be vomiting everywhere all the time." Jon Blow joked. His computer could render a pretty 3D environment from two different perspectives in eleven milliseconds. Why then did it take a thousand to display that "New Document" menu?
I thought "It's market-driven." Programmer time is expensive, and it usually takes more to achieve high performance. Is the extra cost worth it? You would refund a VR game that made you vomit, but few Photoshop subscribers will cancel when the "New Document" menu takes a second. Maybe it's just good economics to prioritize other things. [1]
My opinion changed when Jon compiled his game in under a second. This was already impressive at the time, but it gets more so if we jump forward to May 2025 when his game was 300k lines of code and compiled in 2.3 seconds. In an interview Jon said, "It's big. So far I think it's a reasonable estimation that if the average person wants to 100% the game, it's probably over 500 hours of play time."
The demonstration threw me. I completely reassessed how we did things at Google. The "market-driven" argument doesn't excuse slow compilation. You can't save programmer time with shortcuts that bog down compilation. A slow build consumes the resource you claimed to be saving. So why did it take 30 minutes to start my project's development server? Why did it take 5 minutes to compile unit tests for a single UI component? Jon's game was staggeringly more complex than that UI component. He compiled on a single computer. I used a server farm.
The talk inspired me to learn systems programming to get control of my software's compilation and runtime performance. I read the classic C Programming Language by Brian Kernighan and Dennis Ritchie. I took some courses at Carnegie Mellon as a non-degree student:
- 18-213 Introduction to Computer Systems
- 15-411 Compiler Design
Compiler Design was difficult to balance with my job. I had no time for friends and family. After it finished, I left my job at Google to focus full-time on education. I took a third course at Carnegie:
- 15-410 Operating System Design and Implementation
Large programming projects were 90%+ of the workload for those courses. I can't post the code publicly, but I can share it privately.
Then I took Casey Muratori's Substack course, Performance-Aware Programming. It's ongoing, but I watched and did the homework for all episodes released at time of writing (October 8th, 2025).
Casey's an endearing teacher. His passion for the subject bleeds through as he patiently explains things step by step. His knowledge was earned from a career of curiosity and preference for writing things from scratch, rarely depending on someone else's code. He has his students learn in the same way. You don't just learn to read assembly. You write an 8086 simulator. You don't just learn to use a profiler. You write your own. It's impossible to do the coursework and not come away with a deep understanding of the subject matter.
Next, I wanted a project to show publicly that demonstrates systems programming knowledge, so I wrote a chess application from scratch in C. It supports three platforms: Windows, macOS, and the web. Try the web version below or download native executables on the GitHub Releases page. I'll discuss technical details below. But first, try it out!
Okay, I hope you think that's neat. I had fun making it! Now let's go behind the scenes.
At runtime, the Windows and macOS ports depend on only the C standard library and APIs provided by their respective operating systems. The web version doesn't even depend on a C standard library implementation, so none of the platform-independent code can use it either. This took me down some fun rabbit holes.
For floating-point rounding and square root, I used x86 intrinsics when compiling with MSVC and builtins when using Clang or GCC. There weren't such intrinsics, however, for sine and arccosine. Instead, I used Mathematica to compute constants for polynomial approximations.
I also wrote a printf replacement. The most interesting part was the function that converts a floating-point number to a string, accurate to about eight decimal places.
The app is resolution-independent. I wrote a vector graphics rasterizer to draw the chess pieces and text. For the chess pieces, I parse a subset of the SVG path format. For the text, I use stb_truetype to to extract data from a font file and convert it to the format my rasterizer understands, but I do that in a separate program that runs as a build step. The executable does not contain any stb_truetype code.
Still, much credit to Sean Barrett, author of the stb libraries. His writeup on the stb_truetype anti-aliasing algorithm taught me enough about vector graphics rasterization to write it myself.
The next most interesting part of the project was the AI. As a challenge to myself, I did not read up on how to write a chess bot. I wanted to see how far I would get "on my own steam." I'm reasonably happy with the result. It's better than I am at chess, though I can still eke out a win against it occasionally.
Still, now that I've made the AI about as good as I can on my own, I'm looking forward to reading up on state-of-the-art techniques and implementing some to see if I can't write an AI that I will never checkmate.
During this time I also learned things unrelated to programming. I self-studied math. I read and did odd-numbered exercises in Mathematical Proofs: A Transition to Advanced Mathematics by Gary Chartrand, Albert D. Polimeni, and Ping Zhang. I'm currently working through Linear Algebra Done Right by Sheldon Axler. If it interests you, check out my exercise solutions for the first three chapters. I also spent ~400 hours learning Chinese.
That catches us up to the present (October 8th, 2025). It's neat to look back and see how far I've come. Not long ago I was writing code with the vaguest notion of how the computer ran it. I didn't even know how my data was laid out in memory. Now I've written a compiler, custom allocators, and kernel code to manage virtual address spaces.
Whew, that's enough talking about myself. If you read all that, I'm pleasantly surprised. Thank you for your interest! If you'd like to contact me for any reason (especially if you'd like to hire me), email jeremiah@jeremiahkellick.com
Footnotes
- ↑ A case has been made that performance improvements affect revenue more than you might expect, but this was my thought at the time.