Jeff Levin
AI-generated portrait of Jeff working on a laptop in a spacesuit

I'm Jeff, a software engineer writing about developer tools, AI, and making work better. → About me

A little bit of polish

An agent helped me discover zsh named directories and fix a tiny annoyance I'd tolerated for years. A few seconds to add a little bit of polish.

Keep fighting the good fight

A Christmas card in July, a birthday card six months late. To everyone still writing handwritten notes: keep fighting the good fight.

Reclaim Focus

I wrote about being more productive than ever and also exhausted. The answer wasn't better tooling or more agents. It was fewer projects, one focused task, and learning to be bored again.

The Intention Problem

Every time you describe what you want an LLM to build, something is lost. Not because the LLM is dumb—because English is vague by design and code is precise by necessity. That gap is where AI coding breaks down at scale.

I'm More Productive Than Ever. I'm Also Tired.

Context switching used to kill productivity and make me feel drained. 2pm would arrive for me to muster the energy to build context and start on deep work for the day. Now I'm managing a fleet of agents across 10-15 projects a day, learning faster than ever, and I'm exhausted.

Waterfall development is back (and it's how I ship with AI)

In college they taught us waterfall was dead and agile was the future. Now I practice waterfall daily. Research and planning phases measured in hours instead of months. The highest leverage activity isn't writing code anymore—it's planning and context management.

My environment is a playground again

When I started programming, learning my environment WAS the thing. Somewhere along the line, improving my dev environment felt like toil- wrestling with configs and bash scripts while juggling deadlines. Sometimes it was fun, often it was not. AI has completely changed that. My dev environment has become the playground for my imagination.

Use golangci-lint with your lsp in neovim

Setting up gopls and golangci-lint together in Neovim with Mason. You want both - gopls for language features and golangci-lint for comprehensive linting.

Like base training, but for your career

Why sustained effort beats sprinting, but all progress requires the occasional maximal effort. Ambitious people who are goal oriented often end up in a trap of constant sprinting without time for recovery or a body of sustained effort to build upon. In cycling we know this doesn't work. That's why we have a base phase.

Interesting behavior comparing structs in testify

When comparing structs in Go tests, testify offers ObjectsAreEqual and ObjectsAreEqualValues. Figuring out which one you need isn't obvious, and both have surprising quirks.