Making Websites is More Complicated These Days - And That's a Good Thing

Today I managed to fetch authenticated data from an AT Protocol PDS by following the OAuth flow to sign a user in.

The rumors are true — it was a pain in the butt.

It seems like building websites is more complicated than they used to be. It's popular to complain about all the tooling ceremony around building and deploying websites these days. "Back in my day, you could just put HTML on a server with FTP!"

So... why don't we just do that anymore? It's not like you can't — and it's a fabulous way to make a certain style of website. But expectations are rising, both of users, product designers, and developers.

Users want accessible, interactive websites that load quickly and respond to their actions immediately.

Product designers want to give their users all the features they want, and then some. Websites and the services they provide have the potential to be much more capable now than they've ever been.

All of this makes things harder for developers, and being the most lazy profession, they'll do everything they can to make their lives easier in the long run, even if it means some pain in the short run. Refactors are inevitable. Adding new features is inevitable. Scale... isn't inevitable, but we like to imagine that it is.

All of this means more complication and complexity. Everybody with me, to the tune of "We Didn't Start the Fire:"

TypeScript, serverless, lint rules, frameworks, realtime, local-first, concurrent features. ShadCN makes things look nice, Claude Code Agents roll the dice, SSG, SSR, I CAN'T TAKE IT ANYMORE!

Typically it gets really complicated suddenly, and then as new, better methods of accomplishing the same goals are discovered, it tapers off a bit.

In many ways, web development is in the tapering off phase. Lots of turnkey packages, like the TanStack suite. New frameworks building off the good ideas of the past, like Remix v3 and SolidJS and TanStack Start. Fast tooling, like Biome and oxlint and TypeScript v7.

And even CSS, bringing preprocessor features — like nesting, variables, mixins, color mixing — to the engine. Plus anchor positioning. And don't forget popover, dialog, and the command API in HTML. Things are getting good.

Which brings me back to ATProto's frustrating OAuth setup. ATProto is distributed — each user's data might be stored on an entirely different PDS instead of centralized within a walled garden. Each app might pull from the same bucket of data — I'm sure Bluesky's profile data is pretty popular — or they might have their own data model that they use (which means they have to write and publish the lexicon for their specific data, meaning more complexity).

And all of this is actually pretty cool. In my opinion, these are improvements over the status quo. Distributed data means users aren't tied to any one app, and other apps can piggyback on each other. Lexicons make sure you aren't surprised by the shape when you pull data from a PDS.

All of it, every bit of added complexity, is extra work. But it pays off eventually. The new platform features are evidence of this.

So if it feels complicated right now, just wait. It will get worse... and then better.