Skip to content eckertalex.dev

Don't Just Ship. Practice

Lately, I’ve been thinking about how to get better at programming. By programming more often, more deliberately, and in ways that are uncomfortable. Sometimes that means practicing fundamentals until they become effortless. Sometimes it means building something I don’t know how to build yet.

Either way, it means writing code that’s not just for work or about shipping features. Side projects, exercises, rewrites—whatever helps me stay sharp. It builds fluency, reduces friction, and keeps me from atrophy.

This kind of practice reminds me of running. Consistently training with variety—easy runs, intervals, long runs, and even cross-training. Building endurance and muscle memory, until running feels effortless. That’s when you can enter the flow.

That’s what I want in code.

Flow doesn’t come from repetition alone. First you have to push yourself past the comfortable and build mastery and intuition through consistent practice. It’s when everything clicks, and solving problems feels effortless. But that effortlessness doesn’t come out of nowhere. It comes from understanding the basics so deeply that you no longer have to think about them. That’s where fluency comes in.

AI can do a lot now, but it doesn’t replace fluency. If you aren’t fluent, how would you know if it’s right? How would you know if it’s almost right? Understanding the basics deeply enough that you don’t have to second-guess yourself every few lines. When the easy parts aren’t effortless through practice, the harder parts become that much harder too. Without fluency, you’re not solving problems—you’re just vibe coding.

How I practice

I just code. I build small tools. I rewrite them. Or I learn a new programming language or paradigm. I don’t usually have a plan, I follow where my curiosity leads me.

I enjoy Advent of Code. Sometimes I do a LeetCode problem for fun. However, most of my practice happens in side projects. Most of them I will never finish—as is the first law of side projects. Often I rewrite a big part of them. Not for performance, but to develop better taste and intuition. To refine my sense of what makes a solution elegant, simple, or robust.

A few months ago, I tried building a clone of ed, the classic Unix line editor, in Go. It sounds simple enough—the original was built over 50 years ago under tight constraints. It should have been simple with today’s quality-of-life tooling—syntax highlighting, language servers, linters, fast compiler, and an abundance of memory and CPU. The experience was humbling and made me appreciate the original even more, especially given the limitations of the time it was written. I also followed along with Writing an Interpreter by Thorsten Ball. Another project that wasn’t about shipping, but deepening my understanding.

I don’t use most of the side projects. They aren’t about the end result—they’re about learning, practicing my craft, and stepping outside of my comfort zone. It’s about doing the kind of programming that challenges me. Because when things get too easy, I stop growing.