Code Stories

Four eras of the web: How to survive the next

We wrote Theseus for a company that sells seminars, and the list of what it does reads as a description of that business: the seminars, from the calendar down to who is in the room; the sales floor working the phones, with the calls logged and the meetings booked against the client they belong to; stock and inventory behind it; then invoicing, and the chasing of the invoices that go unpaid. It is not a tool the company uses. It is the software the company is run on, it went into production in 2003, and it is still in production today.

We have been working on that company’s software since 1999, which is longer than Theseus has existed — because the first version of it was not Theseus, was not PHP, and was not on the web at all.

1999 — a contact book on a shared drive

What existed in 1999 was not the business — it was the sales floor’s contact book: clients, calls, who to ring back and when. It was Microsoft Access — a database file with forms drawn on top of it, sitting on a shared drive. For one office and the people working the phones in it, that is a perfectly sensible answer, and for a while it was the right one.

Then it ran into the requirement that ends every desktop application: the company had branches across the country, and all of them needed the same data, at the same time.

Access could not offer that. What it could offer was a copy per branch and the hope that the copies would synchronize afterwards — which comes back to you as conflicts, two offices having edited the same record and somebody deciding after the fact which of them was right. The platform was not weak. It was built for one building and one drive, and we no longer had one building.

2000 — the web, because nothing else reached the branches

So it was rewritten, in PHP, and by 2000 it was a web application. That rewrite is where Theseus begins — and where it stopped being only the sales floor’s. It kept growing: the seminars themselves, then stock, then invoicing and the receivables behind it, until it covered most of what the business did in a day. It went production-ready in 2003.

It is easy to be condescending about the choice of tool with twenty-six years of hindsight. Around 2000, PHP was the modern answer — PHP 4 arrived in May of that year, and the LAMP stack was fast to write, cheap to run, and deployable by copying files onto a server. It was not the legacy option. It was the option people chose in order to escape legacy.

What it bought was precisely the thing Access could not do: nothing to install anywhere, exactly one copy of the data, and a branch office in another city looking at the same screen as head office by typing in an address.

And this is the part worth sitting with, because it is the first of the two stone ages in this story. The browser of 2000 could not do anything. There was no Ajax — the word did not exist yet and would not until 2005. There was no meaningful JavaScript library, no state in the client worth the name, and nothing resembling an application running in a page. The entire application lived on the server: it received a request, decided everything, produced HTML, and the browser drew it. Click a link, the server builds a whole new page, the browser displays it, repeat.

That was not a constraint we cleverly worked around. It was the architecture, and it is why the thing was ever able to reach the branches at all.

2007 — the application moves into the browser

On 2 April 2007 I registered on a forum for a JavaScript library that most people had never heard of. It was called Ext back then — a little earlier, yui-ext — and it would later become ExtJS and then Sencha. I signed up as jsakalos, linked my site extjs.eu, and started asking questions.

Ext proposed something outrageous: that you could build an application — grids you could sort and edit like a spreadsheet, trees, windows, forms that submitted in the background — inside a browser, and have it feel like desktop software. Coming from seven years of server-rendered pages, it required throwing out almost everything I thought I knew. I wrote about exactly that shock at the time, in Changing the viewpoint to Ext — a post from 2008 that still holds up as a description of the mental leap.

To appreciate why that leap was worth making, and why it hurt, you have to remember what building an application in a browser actually involved in 2007. This is the second stone age, and it is the one people forget.

  • Internet Explorer 6 was still everywhere, and IE7 was the exciting new one. You wrote your code once, then wrote it again for whatever IE decided box models and events meant that day.
  • There was no “framework” in the modern sense. No React, no Angular, no Vue — none of them existed. You had a browser, a bag of quirks, and if you were lucky, a library that papered over the worst of them.
  • “Ajax” was barely two years old as a word. The idea that a page could talk to the server without reloading was still genuinely new, and most of the web still worked the way our PHP application did.
  • Layout was tables. Or floats, if you were brave. CSS as we know it was a dream nobody dared to dream.
  • Tooling did not exist. No npm, no bundlers, no package managers, no build step. You downloaded a .js file, put it in a folder, and included it with a <script> tag. That was the pipeline.

2007–2015 — eight and a half years on a forum

I did not stop for eight and a half years. 27,664 posts. That is an average of 3.92 posts every single day — weekends, holidays, Christmases — until my last one on 21 November 2015. Somewhere along the way the badge under my name changed to Sencha Community Support Team — the vendor’s own way of conceding that its users’ hardest questions were being answered by someone who did not work there. That is still the job description.

Sencha forum member profile for jsakalos — joined 2 April 2007, Sencha Community Support Team, 27,664 total posts at 3.92 per day, home page extjs.eu.
The profile behind those numbers: joined 2 April 2007, 27,664 posts at 3.92 a day, the Community Support Team badge. (Date of birth and Skype handle blanked out.)

And note that word: answered. Those 27,664 posts were not 27,664 questions — it was closer to 26,000 answers. I was not the one stuck; I was the one other people came to when they were.

A number like that looks like an addiction, and maybe it partly was. But mostly it was the only way to learn, and the mechanism matters, because it is the opposite of what people assume.

Here is how almost every one of those answers actually happened. Someone would turn up with a problem — they wanted something: a grid that did this, a form that behaved like that, a layout that survived IE. Nine times out of ten I had never done that exact thing either, so I would go and build it — a little test, broken and fixed until it worked on my own screen. Then I would come back and answer. Every answer was a small research project I did first and reported second.

There was no shortcut available even if I had wanted one. Stack Overflow did not exist yet (it launched in 2008). There was no documentation worth the name, no tutorials, no courses. There was a forum, a handful of people trying to make the same impossible thing work, and a lot of trial and error done in public.

Do that ~26,000 times and something happens that no course can reproduce: you have personally hit, and solved, nearly every way the thing can break — because someone, somewhere, needed each one. That is not a comment count. It is a decade-long apprenticeship where the curriculum was other people’s problems.

Some of it got written down while it was still happening. Writing a Big Application in Ext — Part 1, Part 2, Part 3 — took a year to finish, and is that apprenticeship trying to turn itself into a method: how to structure an application once it has outgrown a single file, worked out in public by someone who was still finding out.

The forum stopped in 2015. The work did not. The decade since has been client work in the modern frameworks: large applications built for other people’s businesses, reviews of codebases we did not write, and being called in when something is wrong and nobody can say why. It is still other people’s problems, and that is still the fastest way to learn.

Today — the pendulum

Put the four eras next to each other and you can see that the industry did not move in one direction. It swung back and forth.

  • 1999 — Access. The program runs on your machine, the data sits on a drive you can reach. Fine until the people who need it are not in the building.
  • 2000 — server-rendered HTML. Everything moves to the server. The browser is given a page and displays it. One copy of the data, nothing installed, every branch equal.
  • 2007 — Ext. The swing goes back the other way, hard. State moves into the browser, the page stops reloading, the server is demoted to a JSON pipe. It felt like the future, and for a decade nearly everyone agreed it was.
  • Today. Server components, streaming, HTML rendered on the server again — and the interactivity kept. The site you are reading this on is built exactly that way.

So the Theseus of 2000 and the page you are reading have more in common architecturally than either has with the single-page orthodoxy of 2012. That is not irony. It is what happens when an industry rediscovers a constraint it had been able to ignore for a few years: the person reading the page is on a mid-range phone on mobile data, not on the fast machine the page was built on, and every kilobyte of JavaScript has to arrive and run there before anything works.

The frameworks changed, then changed back, and will change again. What did not expire is the set of questions underneath all four eras — where does state actually live, what is the server for, what happens when two people edit the same row, what will this look like to whoever opens it in ten years. Those are the same questions in Access, in PHP, in Ext and in React, and answering them carefully is the entire reason a codebase from 2000 can still be read in 2026.

Which is not a figure of speech. Theseus is still in production, and still being worked on — the most recent change went in a few weeks ago. For software of this kind that is not a sentimental detail: on a morning it is down, nobody ships an order or sends an invoice. It has grown to some quarter of a million lines across thirteen hundred files, and it long ago outgrew the company it was written for: it now runs businesses that deliver goods, service printers and supply building materials — and it runs ours.

We went back and read that code not long ago, braced to wince at our younger selves, and mostly did not have to. Not because the language was special — it was not, and there is plenty in the tree we would not write that way now — but because the boring decisions had been made carefully. The data access sat in one place. The logic was not woven through the markup. Nothing depended on a global that could be set from anywhere. Two decades later that is still the difference between code you can change and code you can only replace.

It runs on modern PHP. Code from the PHP 4 era had to survive register_globals being taken away, magic quotes going with it, the entire mysql_* extension being deleted in PHP 7, and the strictness that arrived with PHP 8. Those are the gates that killed most of a generation of applications: the ones leaning on globals that anything could set, or with mysql_query() woven through every page, did not walk through them. Getting through them was not luck. It was the bill for the boring decisions, and it came back paid.

So here is the answer to the question in the title, and it is not a framework: you survive the next era by writing quality code in this one. The four questions above only got written down much later, as the nine qualities of quality code — nobody had formulated them in 2000 and we could not have named them then, but that is how we worked anyway, because there was no other way we wanted to work: quality before speed, before cleverness, before whatever the fashion of the year was asking for. More than twenty years in production is what that buys you, and nothing else buys it.

That is what is on offer here. Not a list of frameworks — the one you are using now will be replaced too — but us: we have kept companies running on software since 1999, through four eras of the web, and we would make the same boring decisions on your codebase tomorrow. Theseus is still running, and somebody is invoicing on it this morning.

saki
Follow me:
Latest posts by saki (see all)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Enter your username and password to log into your account. Don't have an account? Sign up.

Want to collaborate on an upcoming project?