There was a time when building a website felt straightforward. You'd write some HTML, add PHP for dynamic content, sprinkle in jQuery for interactions, upload it to your server, and you were done. No package managers, no build processes, no debates about hydration strategies. Today, creating even a simple webpage often involves configuring multiple tools, managing dependencies, and navigating complex development workflows. How we got here? What did we lose along the way?
I recently tried to revive a simple React project from 2015. What should have been a quick update became a multi-day archaeology expedition:
- Running
npm install
revealed dozens of security warnings - Half the dependencies were no longer maintained
- The React version was so old it predated the current documentation
- Updating React required rewriting significant portions of the codebase
The solution? I converted it to static HTML and CSS. The entire process took about an hour, the site loads instantly, and it will run unchanged for years.
The Era of Simplicity: PHP, jQuery, and Getting Things Done
I don't want to romanticize the past, but building small projects required less effort. Sure we have AI to build boilerplate code, but PHP and jQuery were the pragmatic workhorses of the early web. They prioritized solving problems over perfect architecture.
When PHP 7 was released, Rasmus Lerdorf joke that even your bad code is fast now. That's because the goal wasn't to make a perfect tool for programmers, instead it was to make tools for people to build websites.
PHP was refreshingly straightforward. Need to display database content? Write a query, loop through results, and output HTML. Want to handle form submissions? Process $_POST
data directly. You can build a quick, reliable, and secure website without including a single dependency.
jQuery solved the browser compatibility nightmare that plagued early JavaScript development. Instead of writing different code for Internet Explorer, Firefox, and Chrome, you could write $('#element').fadeIn()
and trust it would work everywhere. It made JavaScript accessible to developers who just wanted to add some interactivity without becoming browser compatibility experts. In fact, it was very popular in our marketing department.
Modern Development: Powerful but Complex
Today's web development tools are undeniably more powerful, but they've also introduced significant complexity:
The Modern Stack Requirements:
- HTML becomes JSX with component hierarchies and prop validation
- CSS evolves into CSS-in-JS, utility frameworks, or sophisticated design systems
- JavaScript requires transpilation, bundling, tree-shaking, and often a full build pipeline
- Development involves package managers, linters, test runners, and deployment workflows
Modern projects often include dozens or hundreds of dependencies. Each brings its own maintenance burden: security updates, version conflicts, and the inevitable deprecation cycle. A simple button component might pull in multiple libraries, each with their own dependencies.
The Reinvention Cycle
Interestingly, many modern solutions solve problems we've solved before, just with additional layers:
- Server-side includes (
<?php include 'header.php'; ?>
) become component imports with build-time processing - jQuery's
$.ajax()
becomesfetch()
wrapped in state management libraries - Simple CSS becomes processed through multiple build steps to achieve similar results
We're not necessarily solving new problems. We're solving old problems with new constraints and capabilities.
Along the way, we started paying the cost:
- Higher barrier to entry for new developers
- Increased project setup time and complexity
- More moving parts that can break
- Dependency management overhead
- The paradox of choice among competing tools
- After a few years, you can't deploy your code unchanged
The web development community has gained incredible capabilities, but we've also made simple things more complicated than they need to be. There's value in remembering that sometimes the straightforward solution. PHP processing a form, jQuery handling a click event, or even plain HTML and CSS. This might be all you need.
The best tool is the one that solves your problem efficiently without creating new problems. Whether that's a modern React application or a PHP script from 2010 depends entirely on what you're trying to accomplish.
The web became amazing because it was accessible to anyone willing to learn HTML and try things out. As we build increasingly sophisticated tools, we should remember to keep that accessibility and experimental spirit alive.
Comments(5)
Guido :
I agree with your general idea, that complex javascript code (and complex javascript frameworks and setups) make web development too complex for most use cases.
Sloppy one-page-apps in general make sites to large (in traffic volume), too slow and they circumvent several browser features (such as the back-button). Sure, they can be re-implemented in javascript, but that is re-inventing the wheel and most programmers don't do it. Same for JS size. You can try to keep it small, but few developers care about it (a former colleague in my project did, and I was happy that he always had an eye on it).
In my opinion, a static site is great for many use cases, server-side rendering handles a lot of other use cases and some sprinkles of javscript can make a site more convenient to use (as long as it is still usable without it). There are also cases where you can't get around heavy use of javascript (maybe even with the aid of webassembly), for example when you are trying to build something interactive such as a web app for video conferences.
I do, however, strongly disagree with the nostalgia about PHP and jQuery.
PHP is a deeply flawed language, and the perceived ease of use made sure that a typical PHP website was riddled with security holes (such as XSS vulnerabilities, SQL injections and even code execution). There are exceptions, of course, but that requires skill because it was (is?) easy to shoot yourself in the foot with pure PHP. Some frameworks helped to mitigate that, but then again, that meant you had another layer of complexity again.
jQuery may have been really useful in the past, when the browser's JS APIs were not as sophisticated as they are now. Nowadays, you do not lose much comfort when you just use vanilla javascript, compared to jQuery. So for that reason alone I'm not sad about its drop in usage. jQuery was also a pain to update. I had to maintain a software that used jQuery here and there. It had an old version of jQuery, which had some known security issues. The site was large, it was hard to find out whether the security issues were relevant to us, and since jQuery expressions where sprinkled over a dozen JS files and hundreds of template files, it was even harder to update it and check if everything still worked.
We eventually managed to get rid of it, but it was a pain and I have seen this pattern on other websites as well. jQuery may have been useful once, but its downsides are bigger than the advantages it has over modern vanilla javascript.
Ibrahim author :
Guido I don't disagree, which is why I added the disclaimer "I don't want to romanticize php and jquery." However my point is that these tools emphasized solving problems, and tried to take complexity out of user's hands. As opposed to current tools that by default are complexe.
Guido :
As I said, I mostly agree with you. Specifically with jQuery though, we have not really lost much. If anything, by using vanilla JS instead of jQuery, we reduce complexity.
This is, if we use vanilla JS (or no JS at all). The complexity of current JS frameworks such as React, in combination with all the tools you need to get it running (npm, webpack, babel, you name it), broken/outdated dependencies, etc is where the problems lie. I very much agree on that part.
Unrelated to your article, the dependency hell is not a problem limited to javascript. For example: I used to use ruby on rails for my private blog. I started with it in 2012. By 2020, there were several major version updates for Rails, each of them with breaking changes. The HTML sanitizer I used had a known security issue and needed to be updated. The updated version required a newer version of Ruby, the old version of Rails did not work with the new Ruby… long story short, I replaced the rails software with a static site generator with a lot fewer dependencies in 2020. Almost five years later, the site generator is still fine, still maintainable and a lot more fun to work with.
I've also come across dependency hells at my job. I had to update an old Java web-application that did not use a dependency manager. Ancient versions of spring, ancient versions of some libraries and each library I updated brought another transitive dependency to light. It was very much not fun.
In another project, we used React (here it comes full circle with your experience). We using React in 2016 and maintained it until 2020, then we handed over the software to our client's team. I was lucky here, because we had a JS enthusiast in the team (the guy I mentioned who also made sure the JS files stayed somewhat small). This guy took care of the dependency updates and everything. Keeping everything up to date was a pain for him, but we knew if we stayed with a version, every update further in the future would become harder and harder. And eventually, there would be a reason why we had to update.
I assume you have made similar experiences (not only with the React app from 2015 you mentioned in the beginning). I like your solution: Make it as simple as possible. Throw away the unnecessary parts, keep what you need.
But I also assume that you too have worked with clients who just wanted more and more features in a piece of software. “The competition added a new feature? We need that as well!” or “We need to get ahead the competition, so we need to add more features before they do!”.
Sorry, I was going off topic a bit (a lot). What I want to say is: Yes, I want to have simpler software, too. And I'm happy that you managed to turn that fossil of a React app into something much more simple.
Ibrahim author :
Funny enough, something very similar to your experience with ruby just happened to me this week. Heroku dropped support for the version of Ruby that one of my clients is using. Which means we can't do deployments anymore without updating ruby and the rails version. They are 2 versions behind, so this requires major rewrite.
And of course, they have an older version of React for the client side 😅.
Thank you for contributing your insight.
Walt :
That's exactly how I feel about .NET. You used to be able to render a data table and style it with CSS in like 15 minutes. Then EF came out, and LINQ replaced queries. And doing a few subqueries with an aggregate function and a grouping took weeks to figure out 😅 I still haven't figured it out.
Let's hear your thoughts