The evergreen codebase
Okay, let's all admit it. We've all done things at a certain point of time in our lives that we thought was cool, hip, trendy or fashionable. I, for example, once owned a fabulous pair of ADIDAS popper tracksuit bottoms and I was the coolest kid in the playground. That was of course until one of the real "cool" kids would rip the poppers off leaving my poor unfashionable legs to fend off the British weather.
With the web, and especially on the front-end trends come and go. Techniques evolve and new methods become available to us to take advantage of.
We are most fortunate to not only have a say in the direction of the web platform but also to get a huge heads up to upcoming features that we're all itching to take advantage of.
I remember clearly the sheer delight that I felt when I could finally use flexbox on a real production site. No more messing around with JS hacks to get two boxes to have equal heights. It was well worth the wait but I still had half a dozen active projects that were still using with what seemed like archaic methods. They were frozen in time - little time capsules of technical debt never to be unearthed or disturbed again lest we face the wrath of an angry product owner.
The thing is, we knew that flexbox was coming for quite a long time. Yes, we could have used Modernizr or
@supports() but the fact would remain that the old code would still be there, forever bloating the codebase and making it seem stale.
The audience moves on, why shouldn't your code?
Things are better now though, right?
A little, but not really. We're fortunate enough to have slain the vile creature that was Internet Explorer and most browsers automatically keep themselves up to date and they do it well. But a new beast is lurking and unfortunately it's called Safari which still lags behind pulling on the tail of progress (sorry Safari devs - you're doing a fab job).
Right now, I am looking at some excellent codebases constructed 5-6 years ago and I'll make recommendations for them to improve them. Often though, these recommendations are constrained by the limitations of the browser support policy of the organisation that they're for. Which means if we're not careful we're going to replace one time capsule with another.
So what can we do about this?
Well the first step is not to be afraid of the future. Exciting new features such as the popover api, the native
<dialog> element, flex gap are just dying for us to use. But just because we're unable to ship that code quite yet - doesn't mean that we shouldn't write it.
The first step is to make sure a good solid policy is in place to establish what browsers and tools you wish to support. In the case of the front-end you may have a policy where you say that you support the last couple versions of the common browsers.
A manual method
Now, here's the controversial part, write the feature twice. First in the version that you can ship now and then secondly in the more modern, hopefully terser, future proofed version. Then add in a little
@deprecated comment into the code which you have written and put a note to which feature you are waiting on to have support for - ideally cross-referenceable with caniuse.com. You could even write up a little jira/github issue to keep tabs on it.
Then, as a part of your sprint cadence as part of good technical debt hygiene you'd want to get a report of these
@deprecated components or features and address one or two of them when the feature to which they're waiting on is updated in your target platforms.
Additionally, as a little bonus what I'd love to see are expiration dates at the top of components (similar to if you go to an old Guardian article and it warns you that the article is 2 years old). Then, teams can periodically review work, make sure its up-to-date and press the stopclock again.
An idea for a super high tech automatic method
A possible solution that has been buzzing around my head would (and no I've not made it...yet) but it'd look something like this for a Lit web component or a full React component:
- Put in the browser support list inside your
package.jsonyou can use something like (Browserlist)[https://github.com/browserslist] if you like.
- Add in some easy to find comments in your code or if its a full component replacement put it in a file in the root of the components directory. The comments should be machine readable and state that the code will be deprecated and we're just waiting on x feature to be supported by our target browsers.
- Then write some code in github actions (Other CI tools are available!) that utilises the caniuse database to go through the codebase and makes the appropriate change (could be a component swap) and make a PR ready to accept!
That might be a little sci-fi but I'd love to see that in action. You could even just have it generate a static report to review and add to your workload.
Keeping on top of these things could, in my opinion, yield huge dividends and potentially even surpress the urge to do a full rebuild in the future.
The most important part though is that you delete the old code. Remove it, it's old, stale and so passé darling.
I'd love to see codebases where the first commit was 10 years ago but look like they were just made last week.