A picture of me with my dog Tess next to me looking at me

Notes

Friction By Design

Friction, when designed deliberately, serves a different purpose. It introduces a pause. A moment of awareness. A small resistance that asks the user to pay attention to what they’re doing, rather than simply passing through an interface on autopilot.


Minnesota Proved MAGA Wrong

If the Minnesota resistance has an overarching ideology, you could call it “neighborism”—a commitment to protecting the people around you, no matter who they are or where they came from. The contrast with the philosophy guiding the Trump administration couldn’t be more extreme. Vice President Vance has said that “it is totally reasonable and acceptable for American citizens to look at their next-door neighbors and say, ‘I want to live next to people who I have something in common with. I don’t want to live next to four families of strangers.’” Minnesotans are insisting that their neighbors are their neighbors whether they were born in Minneapolis or Mogadishu. That is, arguably, a deeply Christian philosophy, one apparently loathed by some of the most powerful Christians in America.

I was raised Catholic. It amazes me how much the current administration goes against the teachings of Jesus. I just want nice neighbors. I don't care where they're from or what nationality they are.

The federal agents sent to Minnesota wear body armor and masks, and bear long guns and sidearms. But their skittishness and brutality are qualities associated with fear, not resolve. It takes far more courage to stare down the barrel of a gun while you’re armed with only a whistle and a phone than it does to point a gun at an unarmed protester.

Every social theory undergirding Trumpism has been broken on the steel of Minnesotan resolve. The multiracial community in Minneapolis was supposed to shatter. It did not. It held until Bovino was forced out of the Twin Cities with his long coat between his legs.

No matter how many more armed men Trump sends to impose his will on the people of Minnesota, all he can do is accentuate their valor. No application of armed violence can make the men with guns as heroic as the people who choose to stand in their path with empty hands in defense of their neighbors. These agents, and the president who sent them, are no one’s heroes, no one’s saviors—just men with guns who have to hide their faces to shoot a mom in the face, and a nurse in the back.

We should recognize the hardships Minneapolis residents are facing, what they're dealing with, and the bravery they're demonstrating in the face of this. One can only hope that more will follow in their footsteps if and when Trump and his cronies go elsewhere.


Trump's Plan to Tank America

Someday, we will tell our children about this month of January 2026 in world politics. They will not be able to fathom what we chose to do as a country to ourselves. They will never be able to contemplate what the United States once meant to the world beyond, because the relationship of the United States to the rest of the world has been so fundamentally altered by this last year.


Code is Cheap Now, Software Isn't

LLMs have effectively killed the cost of generating lines of code, but they haven’t touched the cost of truly understanding a problem. We’re seeing a flood of "apps built in a weekend," but most of these are just thin wrappers around basic CRUD operations and third-party APIs. They look impressive in a Twitter demo, but they often crumble the moment they hit the friction of the real world.

The real cost of software isn’t the initial write; it’s the maintenance, the edge cases, the mounting UX debt, and the complexities of data ownership. These "fast" solutions are brittle.

Building a quick prototype or proof of concept might be great to start out, but mature, production-level applications are going to be in use for a significant period of time, all the while being enhanced, having bugs fixed, and conflicts about how certain features should work. Being able to look at the different use cases from users to create the best paths is so utterly critical...and time consuming.

Lately, I’ve seen plenty of doomsaying on Hacker News, Reddit, and Twitter about "the end of software engineering." This misses the point entirely. We aren't witnessing the end of the profession; we’re entering a new era of it.

The value of an engineer is shifting away from the "how" of syntax and toward the "what" and "why" of systems. Real engineering lies in the abstractions and the architecture. It’s about knowing how to structure a system that lasts, understanding why a specific rate-limiting strategy is necessary, knowing how to manage a distributed cache, and knowing exactly where not to store your environment variables.

AI often feels powerful because it hides the complexity, but as an engineer, your job is to manage that complexity, not ignore it. The tools have changed, but the fundamental requirement for engineering rigour has never been higher.

Just wait until you start trying to decide how to lay out your project...

While AI is undeniably good at writing code, it remains poor at architecting maintainable, distributable, and scalable systems. This is where non-technical leaders who think they can fire their development teams are making a significant mistake. Until we see the arrival of an artificial intelligence that renders this entire discussion moot, believing that technical expertise can be replaced by a prompt is a strategic error. Building robust software still requires a human who understands the underlying principles of the craft.

The bottom line is that while the tools have changed, the fundamentals of good engineering have not.


The Future of Software Development is Software Developers

The hard part of computer programming isn’t expressing what we want the machine to do in code. The hard part is turning human thinking – with all its wooliness and ambiguity and contradictions – into computational thinking that is logically precise and unambiguous, and that can then be expressed formally in the syntax of a programming language.

As I've been thinking about tools like Claude and CoPilot, they can write code, but it takes someone with experience to be able to tell them what & how to write it. Experience is needed to determine whether the code generated is what is actually needed.

The hard part has always been – and likely will continue to be for many years to come – knowing exactly what to ask for.


So Many Websites

But perhaps the death of search is good for the future of the web. Perhaps websites can be free of dumb rankings and junky ads that are designed to make fractions of a penny at a time. Perhaps the web needs to be released from the burden of this business model. Perhaps mass readership isn’t possible for the vast majority of websites and was never really sustainable in the first place.

And perhaps we should let our websites be small and private things once again.

I know they never went away, but I love seeing the resurgence of personal sites.


AI Can Write Your Code. It Can’t Do Your Job.

Programming is a task. It’s one of many things you do as part of your work. But if you’re a software engineer, your actual job is more than typing code into an editor.

The mistake people make is conflating the task with the role. It’s like saying calculators replaced accountants. Calculators automated arithmetic, but arithmetic was never the job. The job was understanding financials, advising clients, making judgment calls, etc. The calculator just made accountants faster at the mechanical part.

You mean I'm not an astronaut because I played Kerbal Space Program? Tools are good an all, but you need the knowledge to wield the tools.

the one who figures out what they actually need. You look at a codebase and decide which parts to change and which to leave alone. You push back on a feature request because you know it’ll create technical debt that’ll haunt the team for years. You review a colleague’s PR and catch a subtle bug that would’ve broken production. You make a call on whether to ship now or wait for more testing.

None of that is programming, but it’s all your job.

Knowing how the code of large projects all works together is something that is so hard to fully grasp. Things that might seem simple or even unrelated can be so easily missed, the experience we have as developers to consider how software should function is so incredibly important.

But different isn’t dead. The engineers who will thrive understand that their value was never in the typing, but in the thinking, in knowing which problems to solve, in making the right trade-offs, in shipping software that actually helps people.


The Web Runs On Tolerance

You can be crap at coding and the web still works. Yes, it takes an awful lot of effort from browser manufacturers to make "do what I mean, not what I say" a reality. But the world is better for it.

It amazes me how much the browser can figure out and handle.

How do you acknowledge that the father of the computer was a homosexual, brutally bullied by the state into suicide, and then fund groups that want to deny gay people fundamental human rights?

The ARM processor which powers the modern world was co-designed by a trans woman. When you throw slurs and denigrate people's pronouns, your ignorance and hatred does a disservice to history and drives away the next generation of talent.

History shows us that all progress comes from the meeting of diverse people, with different ideas, and different backgrounds. The notion that only a pure ethnostate can prosper is simply historically illiterate

Amen.


A Comic on the Modern World and Conservatism

And this is why it doesn't help to simply tell people you can keep doing the thing you were doing. No one's stopping you from drinking your coffee because it's not about the coffee. It's the fear that if everybody else stops drinking coffee the way I drink it, then I will become an outcast. And that is scary to someone who suddenly is remembering how they have always treated outcasts.


Apple's Assault on Standards

Apple has deftly used a false cloak of security and privacy to move the internet, and web in particular, toward enclosure and irrelevance. This post makes the case for why Apple should be considered a corrupted, and indeed incompetent, autocrat in our digital lives. It abuses a unique form of monopoly to extract rents, including on the last remnants of open ecosystems it tolerates.

Worse, Apple's centralisation through the App Store entrenches the positions of peer big tech firms, harming the prospects of competitors in turn. Apple have been, over the course of many years, poisonous to internet standards and the moral commitments of that grand project.

Sometimes apps are nice, but I'd still much rather see all the functionality browsers allow into iOS/iPadOS. Safari is holding it back.

Developers are forced into the App Store by missing web capabilities, ensuring an advantage for Apple's proprietary ecosystem. This induces wealthy and influential users to default to the App Store for software, further damping the competitiveness of open platforms.

Yup...PWAs are handicapped, instead of having one app for the web, now devs and companies need to develop the web app, an iPhone app, and an Android app.

So long as competing vendors are forced into the App Store and required to use Apple's engine, Cupertino owes much more when it comes to completeness and quality. So long as Cupertino compels use of WebKit, the demand should be echoed back: parity with browser features on other Operating Systems is the minimum bar.

Fundamentally, the web and internet community must stop accepting the premise that Apple should benefit from the protections and privileges of voluntary feature adoption while denying it to others.

Just open up iOS to different browser engines already...sigh.


Dear Mozilla, I don't want an “Al kill switch”, I want a more responsible approach for all

I understand the backlash Mozilla faced after announcing more AI in the browser, scepticism about the product direction is warranted for many reasons. At the same time, I see how some of the features could be useful, and that other big tech companies are less responsible about it. Mozilla tries to be responsible and my hope is for more of that, it's the reason I and many others choose Mozilla products.

I hope Mozilla succeeds in their aim to do AI “right”, adhering to the manifesto, and inspires others to do the same. It's very much needed too, as at this rate our industry is on the way to beat big tobacco and big oil in breaking things.

I share this hope too, I just want this to be all opt-in rather than opt-out. I want Firefox to remain viable, but fully understand how this can erode trust very quickly.


Vibe Engineering

One of the lesser spoken truths of working productively with LLMs as a software engineer on non-toy-projects is that it’s difficult. There’s a lot of depth to understanding how to use the tools, there are plenty of traps to avoid, and the pace at which they can churn out working code raises the bar for what the human participant can and should be contributing.

It can be so easy to see code and think hey! this works! But code that works is only half of what it means to develop software. Can the code scale at all? Can it be maintained? Is it efficient? For a little tool you're building to help you with something, maybe none of that matters. But for anything more extensive than that, you bet it does.

If you’re going to really exploit the capabilities of these new tools, you need to be operating at the top of your game. You’re not just responsible for writing the code—you’re researching approaches, deciding on high-level architecture, writing specifications, defining success criteria, designing agentic loops, planning QA, managing a growing army of weird digital interns who will absolutely cheat if you give them a chance, and spending so much time on code review.

Almost all of these are characteristics of senior software engineers already!


Older Notes →