Code is a craft, and I'm a craftsperson

Like many people in my circles, I recently read Nolan Lawson's We mourn our craft.

And I just want to say I am not ready to mourn.

The long arc from hobbyist and back again

I have been programming since I was five years old. Like a number of kids my age, my parents bought me a home computer—a TI-99/4A, in my case. We got a handful of cartridges for it with games; Parsec is the one I really remember.

But to do something with that computer, I really had to write software. And I found I loved it. My mother still clearly remembers one thing I proudly showed her in those first years.

Working with that computer wasn't just about making something appear on the screen in the quickest way I could. It was about learning the machine. It was about creating, through software, machines of my own.

There was never just one way to do it. I'd argue, with many years now behind me, that there wasn't even one good way to do it. Oh, sure, there were plenty of bad ways—but I believe code is not just a means to an end, but an expressive medium.

In the decades that followed, I got paid to do something I love. I've been so ridiculously fortunate to be able to find lots of projects to get paid for, projects that people needed done, but also projects that were often interesting in unique ways. And I'd create my own machines out of the medium of code to make those things happen—in a way that was uniquely my own.

One of the highest compliments I ever got in my job was from the lead of the next team who took over another round on a client's project after I was on something else. I had built carefully-crafted layers to control a system with a bespoke network protocol.

Bespoke protocols are wild. It should have been very complicated to work with. But I'd built something that was approachable and readily understandable—they appreciated that. I created a talk about it and brought it to several local and regional groups—and people loved it.

I was proud of having not just solved a problem in a way that people loved to work with, but crafted something whose very implementation reflected what was important to me.

Not everything I've done has given me that kind of opportunity, and it's felt like less as time has rolled on. The sameness of many modern projects in general led to them being built on massive, complicated frameworks. (And those frameworks, that rarely have their hoods lifted, have the parts that they're built on fall to attacks).

I'd honestly been feeling pretty down about the whole thing.

So… I did something about it. A few years ago, I decided I would pick up programming for myself again.

Some of what I've built has been tools I've needed. Some of it was for fun. Some of it was stuff I'd build a long time ago, but decided to finally bring out. All of it was built for me. I can trace every line and see soft machines that I've built according to things that are important to me.

And then, there's dye.

What's important to me

I'm a little surprised at myself, that I haven't blogged about dye in this space yet. It might be because I figured I'd already talked about its predecessor years ago and elsewhere. But the software continues to be useful to me, and how I make it continues to be important to me, and so it's (as of this writing) been lovingly maintained, line-by-line, ever since I wrote its first function.

dye is a prime example, I think, of how I express myself through code. On its surface, it looks like just another way to colorize the output of shell scripts. People are doing this all the time by jamming ANSI control codes into shell variables and spitting them back out in the middle of their "echo" commands. It's just another thing they want to solve quickly and move on from.

dye, though, accomplishes the "colorize" goal in ways that are important to me. I like to say it's portable and respectful. Both of these sound nice, to be sure. But what they really are is a reflection of my experiences, of what I've come to consider important.

Let's break down "portable" first.

I wrote dye so that it could run it anywhere I could think of. In the many years since I first installed Slackware on my computer, I've explored many different Unixes and related systems, like all the BSDs and Solaris. I still use OpenBSD to host my original website (and maybe soon, this blog.

I also connected to those systems in many ways. PC consoles in text mode. xterm. Old computers connected with null modems and terminal emulation software. I even had an old green screen terminal—I don't remember which one—just to see how it would work. Whatever I could get my hands on.

Because of those experiences and what they meant to me, I wanted to build something that could run on nearly anything I've ever used, as well as today's new stuff. I knew if I'd just written my scripts in Bash and threw ANSI codes at the wall, it would fall apart in many of these environments—even some of modern ones!

So I built dye around the POSIX shell specification and tput. I not only tried it out in unique environments like the stripped-down Alpine Linux that backs so many Docker images and my OpenBSD system, but also leveraged shellcheck to ensure maximum portability.

During the development, I dug deep into things like terminfo definitions for terminals old and new. When I discovered that my trusty old xterm actually had a really interesting terminal definition that left it officially only supporting eight colors, I wrote a system called "color synthesis" that took the bright variants of colors and rendered them as bold instead there—an older scheme terminal emulators once respected.

The "respectful" part of dye is considerably simpler to describe even if it was still work to implement. I have seen too many programs decide to use color when it's not wanted. At best, it's annoying. At worst, it breaks the display. So I researched existing standards and made sure my script followed them—building a massive shellspec matrix to make sure it behaved exactly how I wanted it to.

Goals set and the implements of this codebase selected, I worked hard on every feature until it not just worked, but reflected my own sensibilities as far as implementation. Most recently, I even built a template parser in pure POSIX shell to simplify printing.

Some of these goals are, of course, expressible as requirements. But what I wrote was yet another program that I can look over and see, line-by-line, has been built in exactly a way that is important to me. I voluntarily imposed constraints on myself and had a hell of a lot of fun doing it. Every line is something that is an expression of my experience, of what's important to me, of the way I do this.

Things die only when we let them

Rewinding back to Nolan Lawson's post, the post that kicked me to finally put words down about this topic—I think it deserves an honest and sympathetic read. Even if I come to a different conclusion.

In fact, I think Nolan could be right about where paid software development is headed. I think it has already been heading this way long before generation by language models became the hot new way to build on the cheap.

For a long time now, economic pressures have been tearing us from the details of building software. We've been pushed out of the tiny corners where we've practiced our craft, the lines of code where we express ourselves and our long lives of experience.

A comment on Nolan's post from someone who still uses Pinafore has a response which I think starts to tell a story similar to what I've been talking about:

Pinafore was an experiment at building the perfect web application – no compromises on performance, accessibility, security, etc. This is part of the reason that I didn’t want to hand it off to someone else–I was afraid that they would compromise on any one of these things and ruin my vision. Of course this is the exact opposite of how most software is written today (especially in the AI age): everything is disposable, “good enough,” etc.

But then he continues, and I can feel the defeat:

I think we will see more of this, but I also see the potential of someone building a Pinafore by siccing enough AI agents on a small enough codebase, giving them a benchmark harness, etc.

I diverge here. It is one thing for me to say to someone or some program "I want a shell color library that runs on any OS and any terminal and is good at respecting the user's wishes for color settings". Even if whoever or whatever writes the code doesn't care about my goal or share my experience, I may even get something that sorta meets the criteria.

But looking at Pinafore, looking at dye, looking at so many of my other projects—including the bespoke network app I built for a client… I see pure expression of what we as programmers, craftspeople of code, set out to create. I see attention to detail and decisions made conveying feeling and experience in every line—not just something cranked out to meet a spec.

We may not win in the economic sphere. We are already spending so much of our own personal capital to try to express what's important to us, what we know makes our code good, when money is on the line. There's only so much of that capital to spend.

The value is very hard to demonstrate to the people holding the purse strings. I think that really, only other programmers can see it—and even then, only if they have had the fortune to develop a keen enough eye for it. If you just run code, you miss out on fully appreciating it.

But we can still fire up an editor and a command line (or, build them!) We can build anything we want, however we want! We don't have to give up expressing ourselves through our code. In fact, I'm really interested to see what a scene without the money from big business could look like.

Maybe it'd look a bit like it did when we were all people exploring computers for our passion, rather than a paycheck.

I am, personally, looking forward to continuing to hand-write my own software. And to continue to hand-write my own posts talking about it.

I am looking forward to more of the joy I've been experiencing, in the strangest of places, because those places are the ones where I've been able to fully express myself.


You'll only receive email when they publish something new.

More from Mattie
All posts