I have strong opinions about the web: server rendering beats loading spinners, semantic HTML is most of accessibility, and every page deserves a good URL. I picked these up over 27 years of tinkering. Here’s how I got there.
Table of Contents
1999
In 1999 the game RollerCoaster Tycoon was released. I very much enjoyed this game, and became a mild roller coaster enthusiast. This was also the year we got 56k dial-up internet at home. RollerCoaster Tycoon allowed you to save your roller coaster designs to a file, and also import designs from a file to use in your park. This gave birth to many websites of people sharing their designs.
Our ISP (Breathe) offered 5MB of Free web hosting (I don’t know how I came to learn this; not sure my parents had any idea). Of course, my roller coaster designs were amazing, so naturally I had to take advantage of this web hosting to share them with the world.
I obviously didn’t know how to actually make a webpage, but did have access to Microsoft Publisher 97. This gave me a WYSIWYG interface for my page, and an FTP client for getting it online to the world. It was super popular:
(not)
It didn’t take long before I hit the limits of Microsoft Publisher’s WYSIWYG editor and I wanted some more control on certain aspects. A slightly bigger font here, a bit more spacing there, and before long I was reaching into the HTML tab to see what I could change. CSS was technically released in 1996, but it wasn’t so widely supported or in common use. HTML consisted of many <font> tags, which actually made it easy to find exactly what raw code needed to change based on what you could see on the page. Just look for the heading Epic Rollercoaster 1 in the code, see that it’s surrounded by <font color="black"> and change that to <font color="red">.
Before long I was searching (Lycos-ing / Yahoo-ing / AskJeeves-ing) for ways to have even more control, learning all about <table> for layout or <frame> to have persistent navigation. I graduated from Microsoft Publisher to plain old Notepad with raw HTML.
I seem to remember around this time obtaining a copy of Paint Shop Pro 6, so a lot of animated GIFs of 3D text started to show up on my webpages for some time.
Alton Towers
Phone at the time: Nokia 3210 - ★★★★★
(first phone of my own)
Whassup 2001! My interest in roller coasters thanks to RollerCoaster Tycoon progressed to being interested in Alton Towers and the new roller coaster they were building, codenamed Secret Weapon 5. Being hyped up in the community I launched a website to host pictures of the construction site (may have involved a little trespassing). http://sw.at was launched (Secret Weapon / Alton Towers - backronymed from one of the available free domains in the dotcom boom era).

https://web.archive.org/web/20010424171011fw_/http://users.breathemail.net/d-marland/
Complete with <marquee> element and “Best viewed” statement. Sadly the Internet Archive didn’t save the animated gif masthead or psychedelic background tiles.
It even had a Guestbook - I don’t recall any messages ever being added.
After a little while the site was updated to use frames for persistent navigation:

Notice “If you get lost just click the spinning logo to come back here.”
- a) spinning logo
- b) getting lost was a inherent problem of
<frame>websites; it was too easy to accidentally end up on an individual frame outside the<frameset>, losing your navigation. Plus the URL didn’t change. Frames were bad.
JavaScript starts to appear on more and more websites and I found myself an almost daily visitor to javascriptsource.com to see what cool things could be done.

Who doesn’t want trailing mouse cursors as they move around the webpage? Pretty sure I found on there a totally secure method of protecting the photos I’d taken from being stolen via right-click:

Little scripts like this were my first exposure to a programming language, with variables, loops etc (beyond the Valiant Roamer/Turtle). Wanting to slightly tinker with the behaviour of the pre-written widgets was how I built up to writing full scripts from scratch.
Alton Towers Database
Phone at the time: Sony J6 ★★★★☆
(my first phone with WAP internet)
As Alton Towers released their Secret Weapon as Air (later Galactica), I turned my attention to the rest of the park. I wanted a website that documented every single attraction, with photos and stats. In 2002 I released the Alton Towers Database:
(look at those lovely swirls)
Even though the name contains the word “database” there was no actual database involved. There was no dynamic rendering. The server just contained HTML files for every page. One saving grace was my hosting supported Server Side Includes (SSIs), which had the benefit of being able to build small chunks of HTML into their own file and then include them into many pages, such as the Masthead and Footer. This was my first foray into componentisation / code reuse, and allowed me to avoid the use of frames for a consistent navigation - as frames were just terrible.
I remember somebody once emailing me offering to rebuild the site in PHP. Not having a clue about programming languages and still not understanding after trying to research what it even was; I declined.
In building the site I had to decide how the content would be laid out. I wanted a page for every attraction, and they were grouped by areas of the park, offering hierarchical navigation with breadcrumbs. Every attraction page had the same structure for title, description, statistics and photos.
Unknowingly, I had stumbled into Information Architecture.
As I learned more about HTML I wanted the page to be the best it could be. It used “web safe” colours and fonts, and was actually a fluid design (albeit still table layout).

Best practice didn’t necessarily stretch to my design skills:
Thank you Internet Archive for saving this abomination.
At the time, Alton Towers’ official website was so poor - it was all Flash - that a Google search for “Alton Towers” would have me at the top of the results for a little while. This gained some attention:
"Thought you knew everything there was to know about Britain's number one theme park? Well, think again. Alton Towers Database is a redefinition of the word exhaustive, and there's more photos than you could ever imagine."
- PC Format Magazine: February 2002
I started to receive genuine enquiries from potential park visitors. One person asked me about accessibility on some rides; after which I took it upon myself to visit the park and document the access situation for every ride and put it on the website.

This exposure to user needs is something that sticks with me today.
Within the online community there were many other enthusiasts of the park. I was able to enlist some of them to help add data to the site and even write some articles. Eventually I found I didn’t have a lot of time to maintain the site and I handed over the site and domain to my co-webmasters in 2003.
Phone at the time: Nokia 7210 ★★★★☆
(first camera phone)
CSS
I couldn’t put this hobby down however. I always had to be building something.
In 2003 Opera started to use the Presto rendering engine:

This was actually very good for web standards, and particularly CSS. I’d used bits of CSS for basic colours before, but layout was still tables.
I started to pick up some side-projects around this time for local clubs, and built them using CSS. This is a tiny screenshot I’ve been able to find of a website I built for a local band:

It made use of the amazing technology of floats (https://alistapart.com/article/practicalcss/) and to get nice multi-column layouts it was all about the Faux Columns https://alistapart.com/article/fauxcolumns/. I used this technique in every project around this time, as well as Sprite sheets to get fancy font headers as this was well before @font-face (again demonstrating my questionable graphic design skills).
As I was now building websites for other people I needed a way that they could update the contents themselves, otherwise I’d be the bottleneck for changes. WordPress ended up being the obvious choice, mainly because a lot of web hosting providers had easy one-click install for it. Of course, Wordpress is written in PHP so in order to tinker with the designs I started to learn PHP. It was very much at the level of hacking things apart rather than software engineering. Nothing object-oriented was to be found. As Wordpress uses MySQL I also got used to working with databases (via PHPMyAdmin https://www.phpmyadmin.net/)
Phone at the time: XDA II ★★★☆☆
(first “smart” phone)
Southampton Hospital Radio
I joined Southampton Hospital Radio https://sohba.org as a volunteer in 2007 and offered to rebuild their website, which hadn’t had much of an update for years. One of the main goals of the website was to display the monthly schedule, as programmes could be disrupted due to live Cricket, Football & Concerts.
At first I was essentially emailed a Word Document every month that I had to meticulously convert to HTML and FTP to the server. This was too much of a burden, so I had to update it. I convinced the charity to move to web hosting which supported PHP and MySQL and got to work building a custom CMS and webpage from scratch in PHP. The frontend looked fairly decent:

Every programme had its own page, and every day got its own schedule, so I could always show what is on live.

The backend of course was an abomination (but that doesn’t matter to the user). Still not properly understanding application structure or object-oriented development the PHP code for this was a horrendous mess of procedural code:
Snippet of PHP code from my early coding days (trimmed for brevity). I've added indents for "ease" of reading. The source code has none.
<?php require_once ("../shared.php"); ?>
<?php require_once ("../dbOpen.php"); ?>
<?php
// Page Functions
if (isset($_POST['saveShow'])) {
// Get Variables and check them
$theForm['title'] = html_entity_decode(stp($_POST['editshowTitle']), ENT_QUOTES);
$theForm['tagLine'] = html_entity_decode(stp($_POST['editshowTagline']), ENT_QUOTES);
$theShow = getShow($theForm['showID']);
$theForm['image'] = $theShow['image'];
if (!$theShow['found']) {$msg='No Such Show';} else {
$theForm['showID'] = $theShow['id'];
if (!$_POST['editshowTitle'] || (!$_POST['editshowDetail'] && $_POST['editShowType'] == 0) ) {$msg='Please complete required fields';} else {
mysql_query('UPDATE tblShows SET showsTitle="' . cleanMySql($theForm['title']) . '", showsTagline="' . cleanMySql($theForm['tagLine']) . '", showsDetail="' . cleanMySql($theForm['detail']) . '", showsType="' . cleanMySql($theForm['type']) . '" WHERE showsPKID="' . cleanMySql($theForm['showID']) . '"') or die('Database Failure');
$msg='Show Details updated Succesfully';
}
}
}
else {
$theForm['showID'] = (isset($_GET['showID'])) ? mysql_real_escape_string($_GET['showID']) : 0;
$theShow = getShow($theForm['showID']);
if (!$theShow['found']) {header('Location: index.php');}
$theForm['title'] = html_entity_decode($theShow['title'], ENT_QUOTES);
$theForm['tagLine'] = html_entity_decode($theShow['tagLine'], ENT_QUOTES);
}
require_once ("header.php"); ?>
<div style="width: 49%; float: left;">
<form id="editShowForm" action="admin-editshow.php" method="post">
<fieldset>
<legend>Edit Show Details <a href="admin-deleteshow.php?showID=<?php print $theShow['id']; ?>"><img
src="design/button-delete.png" alt="Delete Show"/></a></legend>
<div class="formArea">
<?php (strlen($msg) > 1) ? print '<p class="msg">' . htmlentities($msg, ENT_QUOTES) . '</p>' : ''; ?>
<p><label for="showTitle">Title:<span class="red">*</span></label><br/><input type="text" id="showTitle"
name="editshowTitle"
value="<?php print htmlentities($theForm['title'], ENT_QUOTES) ?>"
class="full"/></p>
<p><label for="showTagline">Tagline:<span class="red"></span></label><br/><textarea id="showTagline"
name="editshowTagline"
rows="2" cols="50"
class="full"><?php print htmlentities($theForm['tagLine'], ENT_QUOTES) ?></textarea>
</p>
<p id="fullCopyP"><label for="showDetail">Full Copy:<span class="red">*</span></label><br/><textarea
id="showDetail" name="editshowDetail" rows="6" cols="50"
class="full"><?php print htmlentities($theForm['detail'], ENT_QUOTES) ?></textarea></p>
<p class="right"><input type="hidden" name="editshowID" id="editShowID"
value="<?php print $theForm['showID'];?>"/><input type="submit"
class="submitBtn"
name="saveShow" id="saveShow"
value="Save"/></p>
</div>
</fieldset>
</form>
</div>
<div style="width: 49%; float:right">
<fieldset>
<legend>Select Show Image</legend>
<p class="right"><img src="design/ajax.gif" class="ajaxSpinner" alt="Loading" id="ajaxSpinImage"/><span
id="ajaxImageMsg" class="ajaxMessage">Show Updated</span><input type="hidden" id="selectedImageValue"
value="<?php print $theShow['image']; ?>"/>
<input type="button" id="clearImageButton" value="Detach image from show"/></p>
<div id="smallGallery">
<?php
$result = mysql_query('SELECT imgPKID, imgSize FROM tblImages ORDER BY REPLACE(imgTitle, "The ", "")') or die('Failed to get shows list');
$num=mysql_numrows($result);
if ($num == 0) {print "<p>There are no images in the gallery</p>";} else {
for ($i = 0; $i < $num; $i++) {
$theImage = calculateImage(mysql_result($result,$i,"imgSize"), 58, 58);
$topPadding = (60 - $theImage['smallHeight'])/2;
$imgID = mysql_result($result,$i,"imgPKID");
print '
<div class="gallerySquareSmall"><a href="javascript:updateimg(' . $imgID . ');">';
$imgClass = ($theForm['image'] == $imgID) ? 'imgSel' : 'imgDeSel';
print displayImage($imgID, 'margin-top:' . $topPadding . 'px;" id="gImg' . $imgID, 58, 58, $imgClass);
print '</a></div>
';
}
}
?>
</div>
</fieldset>
</div>
<div style="clear:both;"></div>
</fieldset>
</div>
<div style="clear:both; margin-bottom: 10px;"></div>
<script type="text/javascript">
<!--
function updateimg(imgID) {
$("#ajaxSpinImage").show();
$.post("ajax-attachimage.php", {dowhat: "add", show: <?php
print
$theShow['id'];
?
>,
image: imgID
},
function (data) {
var oldSel = $("#selectedImageValue").val();
$("#gImg" + oldSel).removeClass("imgSel").addClass("imgDeSel");
$("#ajaxSpinImage").fadeOut(250, function () {
$("#ajaxImageMsg").fadeIn(250, function () {
$("#ajaxImageMsg").fadeOut(2000)
})
});
$("#gImg" + imgID).removeClass("imgDeSel").addClass("imgSel");
$("#selectedImageValue").val(imgID)
}
)
;
}
$("#clearImageButton").click(function () {
$("#ajaxSpinImage").show();
$.post("ajax-attachimage.php", {dowhat: "remove", show: <?php
print
$theShow['id'];
?
>
},
function (data) {
$("#ajaxSpinImage").fadeOut(250, function () {
$("#ajaxImageMsg").fadeIn(250, function () {
$("#ajaxImageMsg").fadeOut(2000)
})
});
var oldSel = $("#selectedImageValue").val();
$("#gImg" + oldSel).removeClass("imgSel").addClass("imgDeSel");
}
)
;
});
$(document).ready(checkCopyShow);
-->
</script>
<?php require_once ("footer.php"); ?>
This was all written by hand in Notepad++. Notice a complete lack of structure, indenting, jQuery tacked on the end and inline SQL queries. All bad practices today. Though I will maintain that this was super-fast. The HTML streamed to the browser as it was generated, so parts of the page would be readable, while the later parts of the page were still making database queries. I feel like we’ve lost this “optimisation” in today’s frameworks.
<years-later>
Eventually, once I had learnt how better to build applications I came back and rebuilt this application using Symfony for the app, and React for the CMS. I was considering handing the maintenance of the site over to somebody else and couldn’t bear to have somebody else witness that mess (even though it did work just fine for many years).


React was a good choice for the CMS due to its interactivity. But the frontend didn’t need that complexity so it remained a simple PHP template. This meant the performance for public users was instant - always prefer server rendering.
I am no longer involved in this website and it has since been moved to using a commercial radio scheduling product. Maybe I should have commercialised mine. 🤔
</years-later>
Southampton City Council
In 2007 I started work at Southampton City Council as a web developer on https://www.southampton.gov.uk/, https://www.investinsouthampton.co.uk/ and various internal apps. I appeared to get the job thanks to my PHP “skills” but upon arriving, I discovered it was a Microsoft shop and there wasn’t any PHP in sight 🤷.
Thankfully (classic) ASP https://en.wikipedia.org/wiki/Active_Server_Pages is practically the same as PHP just with a different syntax, so I didn’t take long to get my head around it.

Accessibility
Every month a third-party company (I forget who) would run an accessibility audit on all the council websites in the UK and release a leader-board of scores. When I joined, Southampton was ranking in the lower half of the ~300 councils, and it became a bit of a personal mission to improve this. I meticulously pored over the results and explanations, learning a lot about website accessibility and how to improve it. The vast majority of it boils down to just using semantic markup correctly and ensuring a proper document outline. Wherever I could I fixed the issues page by page, and by the time I left I think we had just breached the top 10. This “gamification” is what embedded my sense of semantics and accessibility on websites to this day.
As well as maintaining the public-facing webpage, I was tasked with building a web-based CMS for all the City libraries (in Classic ASP) - to replace the ageing Microsoft Access database they had been using. This went very well and was highly praised by the users of it. I wish I had kept some screenshots (but I remember I made it dark purple).
After this I was tasked with building a similar CMS for the city parks. But this time it was to be in ASP.NET https://en.wikipedia.org/wiki/ASP.NET as the platform was modernising. This I did not enjoy as much. Partly due to the concept of object oriented programming not quite clicking with me yet, but mostly due to ASP.NET being an abomination of a system for creating webpages (at the time - I haven’t even glanced at it since). It tried to bring the Windows app drag-and-drop interface to webpages, and it created some awful HTML. Not to mention the curse that is the “postBack”. Who needs links, when everything can be a JavaScript onclick with a huge state variable that makes a client-side POST to the next page 🤦. Forget any sense of sensible URLs, or opening things in new tabs. It was diabolical and against everything I stood for in building webpages. I left in 2008 just as I finished the project and I apologise to whomever had to pick up the pieces after me.
Phone at the time: Nokia 6500 Classic ★★★★★
(something simple after the headache of the XDA)
BBC
I joined BBC Future Media (Radio) in October 2008 as a web developer, right as they were beginning to transition from FTP-based HTML/SSI pages to a PHP platform. In the early days I did manage to take down this platform entirely when I built a widget for the 5Live homepage that would show live text messages after they came in (moderated). In order for them to show up immediately I built it using long-polling https://en.wikipedia.org/wiki/Push_technology#Long_polling so all visitors had a constantly open connection to the server. This pretty much immediately saturated all available connections and took down the platform for the whole BBC. Oops. Thankfully, since the platform was new not many of the BBC’s apps were on it yet.
I was tasked with building the BBC’s Podcast directory https://www.bbc.co.uk/podcasts on the new platform in PHP. This was when Object-Oriented Programming started to click for me and the code was of a much better quality than what I had written before. Though still not good. Years later I chose to rewrite the application again myself because handing it over would have been embarrassing. If you’re not embarrassed by code you wrote just last year, then are you really growing?
This managed to launch without issue:


Notice all the rounded corners, drop-shadows and gradients. These features were not available in CSS at the time, so this website was a smorgasbord of sprite-sheets and background images. I did have the benefit of an actual designer this time.
/programmes
After working on podcasts I was tasked with leading the team for bbc.co.uk/programmes, which has the goal of providing a URL for every episode of every programme the BBC broadcasts across TV and Radio including full credits and broadcast history. This is considered a public service and active archive.
When I joined, the information architecture for the project had already been done to a very high standard and the very large footprint was well defined. Everything had a stable URL intended to be permanent. My task was to migrate this onto the new PHP platform (/programmes v2).
Designing a URL structure for BBC programmes
I learned a lot about information architecture during this project and became a big advocate for good URL structure and building a real web of linkages.
Over time we added features that allowed custom branding, episode guides, editorial articles, character bios, polls and much more.
Marion from the BBC Three show Mongrels looking at his own character profile page.
Giving every programme a presence meant that it was very cheap to support everybody. We had a philosophy that no feature was ever built for one specific show. It would always work for anybody. This empowered even the smallest local radio shows to have really rich webpages. You could tell which shows had passionate producers by how active their pages were.
Phone at the time: iPhone 4 ★★★★★
(first true smart phone)
The /programmes website was server-rendered in PHP Zend 1 and the client-side interactions were initially using the BBC’s Glow JavaScript library due to the BBC still needing to support Internet Explorer 5.5 at this time. Once that requirement was dropped the BBC as a whole transitioned to jQuery.
/programmes did have a cache in front of it but had such a long tail of requests we could only really rely on about 20% of requests coming from said cache. We had to try and be fast without the cache. Our success on this was hit and miss in the early days due to the availability of data access within the BBC’s network.
One particularly hairy moment was when the votes for Strictly Come Dancing were to be possible online for the first time. The audience was to visit the Strictly homepage to cast their vote, and that was the /programmes page. This should have been all caught by the cache (the vote itself was client-side). Well, on the first night the site crashed. After an intense week of investigation and patching we realised that our “Vary” header included “accept-language” even though our pages were only ever in a single language. Users browser and operating system preferences can create a really large set of unique combinations for this header and we just missed the cache too often, saturating the backend. Thankfully after a full crisis-mode week the online vote the following Saturday was a success and has been ever since (at least until I left - do Strictly still do votes online?).
Responsive Design
While working on /programmes the BBC did offer some mobile-friendly pages via the common method of the “mdot” site (m.bbc.co.uk) which would essentially render an entirely different website for mobile devices, essentially meaning you had to do the work twice.
But then the concept of Responsive Web Design started to gain traction in the industry. I, and some colleagues pitched the concept to upper management about how we could support mobile, desktop and these new “iPads” with just one codebase. At first we considered radical differences in layout when you switch from portrait to landscape, such as making it more app-like. But eventually as it matured, it became more about being fluid and just rearranging, rather than a totally different experience. We relaunched the responsive version of /programmes in 2014 (Launch blogpost - sadly the BBC have now broken the original link)
I also wrote up a case study for Smashing Magazine
Phone at the time: Firefox Phone ★★☆☆☆
First Firefox Phone [2013]. I won this developer edition in a competition. Didn’t realistically use it for very long as the web just wasn’t ready enough for small screens.
Design systems
The BBC introduced the GEL design system and this was my first introduction to the concept of design systems, which I find fascinating.

Having a coherent set of design rules is very empowering for developers as they can get started building and know that their site will match the standards.
Even something as simple as saying “all spacing is a multiple of 8/16px” goes a long way to making your website look professional straight off the bat.
With the rules in place we could receive “designs” from our designers that say: “use the GEL H2 heading and then GEL cards in a GEL grid that is 2 across until breakpoint X and then becomes 4 across” just via text in an email, not requiring full high fidelity mock-ups and sparing the designer tedious work on the simpler pages.
To me, a design system is an important part of building a website, especially for corporations who need coherent branding when multiple teams are involved. I am a big advocate for design systems, and even have one for this dinky little blog.
Phone at the time Nokia Lumia 920 ★★★☆☆
(first windows phone. good camera. The software was interesting with a unique take on visuals. But it lacked some basic staples of a smartphone and Windows Phone didn’t receive feature parity anywhere near quickly enough https://youtu.be/XQcBI5SKJgU?si=zanSwPQ2r4dU8Bp1&t=9)
Move to AWS
Eventually the BBC’s PHP architecture was becoming dated (having a shared version of PHP for everyone made it impossible to manage upgrades). The BBC started to move to AWS. This gave me a lot more exposure to infrastructure than I had previously had to worry about.
Since the application was to be rebuilt we could consider any language for /programmes v3 but ultimately we decided that sticking with PHP was a good choice. After a period of stagnation in the language, PHP 7 was finally available and offered significant performance improvements and type safety. And since PHP is a language specifically built for websites and the request/response cycle it was just a good fit to stick with it - albeit now better architected. Symfony + Twig was a good, modern choice for this version.
The Cloud is a great paradigm for managing web servers. Add monitoring to everything and if a server loses its way, just terminate it and a new one takes its place. If Strictly is coming up this weekend, just spin up an extra 10 or 100 servers in advance and shut them down afterwards.
After struggling with fetching programme data in real-time and suffering from poor performance we eventually switched to using AWS Aurora and pulling the data into our own /programmes relational database out-of-band, then serving from that. Essentially this made /programmes a good ol’ LAMP stack, and that is super fast. The BBC One schedule page loads instantly to this day on this same stack and I use it as an example of how simple Server Rendering beats modern over-complex frameworks any day.
Phone at the time: Sony Xperia Z1 ★★★★☆
(first Android phone)
Post-BBC
I left the BBC in 2017 as the AWS migration was nearing its end, seeking a new challenge.
I am quite saddened to see the BBC not investing in the /programmes platform as much as it once was. As it is a simple public service and not a flagship product it never received huge amounts of attention, but in general it saved the BBC money as every programme didn’t need to commission their own team/vendor to build a site for them. It appears from the outside that the site continues to run, essentially untouched, on this same stack to this day. This is a testament to it having been built rather well but also a worrying sign that this living archive’s days are numbered. I will be especially sad if one day I visit the BBC One schedule page and am greeted by a loading spinner.
Bloomberg
In 2017 I joined Bloomberg to work on the bnef.com website (paywalled). I've brought much of my learnings and actively push for best practices, accessibility and server-rendering within the company. I've become more interested in CSS all the time as it gets better and better every year. I am also actively involved in Bloomberg’s Web Design system and still believe it helps empower developers across the company.
Phone at the time: iPhone X ★★★★★
(I’ve just stayed on iPhones since this. As you get older your tolerance for experimentation and change decreases)
I am still at Bloomberg to this day and still learning. Plus, with the advent of AI the landscape is changing significantly so I cannot reflect further at this time.
Bloomberg have kindly allowed me to join the W3C CSS Working Group and while I am still finding my feet, I hope to become more actively involved in time.
Side Projects
Even though I still believe a modern Symfony application with a relational database is about as fast as you can get for read-only text-based websites (most of them), there are many frameworks for when things get more interactive. I have most experience with using React (and NextJS) as it works well on both server & client (though it could certainly be trimmed of bloat).
Even while working on React in the day job I like to make sure that I have at least an informed opinion on other frameworks, so occasionally I spin up side projects to try them out.
TubeAlert is the one that has lasted the longest and is still going. So many native Tube status apps were too noisy or had too many clicks to just tell you the Tube status. Some offered notifications but they wouldn’t be time or line windowed. When I heard that the web was about to enable Push Notifications I had to build a web app for it.
This has been rearchitected many times (the first such time documented in detail on this blog) as my canary for trying new frameworks so I can at least get how things work. Currently it is written with Solid and Tailwind (for which I have non-flattering opinions and must do a write-up soon).
Today
It's been a roller coaster. I’ve grown up with the Web as it matured and having been through all these eras has given me a clear perspective on how I think the Web should be done and I hope to continue to be an advocate for such best practices.
I do however still follow the philosophy of “strong opinions, weakly held”. With good evidence and argument my opinion can be changed. At which point I will adopt that position and willingly advocate for it.
