console.log()

The Problem of JavaScript Code Delivery

Share via Twitter Share via Facebook Share via Linkedin Share via Reddit

Big changes are happening in JavaScript code delivery, and developers are taking notice. If the enthusiasm of ReactConf attendees around the newly open sourced React Compiler is any metric, there is tremendous community demand to optimize tooling and standards for shipping code for the web. But improved solutions to the client-side code delivery problem address not only the compiling of code; they are also revolutionizing how code is bundled, minified, split, shook, transpiled, and modularized. Sound complicated? It is, but even if you don’t necessarily understand how it all works, what is important to know is that these sophisticated translators and optimizers are all meant to improve the client-side experience both for end users through faster loading times in the browser, and developers through simplified and rapid builds.

Because the ecosystem for delivering code (HTML, CSS, and JavaScript) and assets (images, fonts, and videos) to the browser is evolving quickly it is worthwhile to pause and take stock. The repercussions of recent events in the space, inclusive of controversies and launches, are affecting not only developers in the trenches but also vendors and, relatedly, the VC funding landscape. There is a lot to say about this domain, so I won’t attempt to condense it into a single post. Instead, let me open what will inevitably be a multipart series by laying out what makes the build step for JavaScript projects and code delivery to the browser such a compelling area of innovation and investment.

 

Why Compile or Optimize?

Code compiling, meaning the process of translating human-readable code into machine-readable code, and optimization, processes such as generating several image sizes and formats for different devices, are standard in most web development. However, this build step is evolving, or sometimes just returning to earlier, less complicated, modalities.

Ryan Dahl‘s OSS runtime Node.js (2009) is in large part responsible for heralding our build-heavy present. Rather than simply adding script code to the index.html file, as was the norm in prior eras, Node enabled developers to write JavaScript for servers and backends. While revolutionary, this change added layers of complexity to web development.

But developer reliance on Node is in large part a symptom of the larger trend in the frontend space that has normalized the onerous builds required by JavaScript-heavy Single Page Applications (SPAs) like React, Vue, and Angular. It also reflects an over-rotation in web development that preferences developer experience above user experience. Long build times often correlate to happier developers because they crave high level abstractions requiring a build step to make machine readable. Unfortunately, in this case happy developers come at the expense of laggy website experiences for end users, and especially those with older devices and suboptimal networks.

Beginning in the 2010s, the need to make server-side JavaScript function in the browser spurred a wave of developer tools intended to bundle Node/npm for the browser including Browserify (2011), Grunt (2012), Gulp (2013), Babel (2014), Webpack (2014), Rollup (2015), SWC (2019), Vite (2020), ESBuild (2020), and Rspack (2022), to name a few popular bundlers. Today many lights from the frontend community, and VC backed companies building either drop-in replacements or at least backward compatible alternatives to Node such as Deno (Series A, Shasta Ventures, Sequoia Capital, and others) and Bun (Seed, Y Combinator and Kleiner Perkins), are debating the question of whether web development should eschew compilers, bundlers, optimizers, etcetera, often by way of returning to the basics of HTML, CSS, and JS. In 2021, for instance, David Heinemeier Hansson (DHH) published a post entitled “Modern web apps without JavaScript bundling or transpiling” in which he argues against complicated builds. He explains:

Transpiling with Babel ushered in the era of horrendously complicated transpiling pipelines and tooling. Writing the JavaScript of the future wasn’t free. The price was an ever expanding web of complexity. This clearly wasn’t the finish line.

While DHH cites a number of specific innovations with ending the need for bundling and compiling including ES6, HTML2, import maps, the larger development he identifies is improvements with the browser which make a build step less and less necessary. Thanks to improved engines and standards developers are now able to accomplish all kinds of tasks natively in the browser. Without compiling, frontend engineers can now write nested CSS (goodby Sass) and execute code using WebAssembly.

Developers have taken note of these expanded capabilities and are already speculating about what they mean for the future of web development. As alternatives become more mainstream software engineers like Prahlad Yeri have begun to ask questions like “Does Node.js Have a Future?” A recent episode of JSParty also addresses the question of “Should web development need a build step?” Although the consensus among JSParty panelists, unsurprisingly, comes down to “it depends,” co-host Kevin Ball suggests that the crux of this issue lies in:

identifying the business problem we’re trying to solve, and doing the minimum possible things – having the minimum set of things under our control to solve that, and shifting as much of the rest of it as you can into tooling, platform etc.

 

Beyond The KISS Principle

This less-is-more philosophy has resonated with the software engineering community, and especially those following web development and the JavaScript ecosystem. Everyone seems to agree that the current level of complexity is unsustainable and largely unnecessary. Earlier this month I spoke with Todd Gardner, CEO of Request Metrics and TrackJS, at RenderATL about what he’s seeing in the JavaScript build space. While commiserating about the complexity problem he reflected:

There are some really smart people in the frontend engineering community. But sometimes smart people need to be challenged, and invent new problems for themselves.

Calls for the KISS principle’s observation among JavaScript developers has becomes cacophonous, and yet the number of compilers and bundlers available is only increasing. In fact, the web build tool Farm drew a huge discussion on Hacker News when it was introduced 3 days ago. Something needs to change in the JavaScript build space, but what? How might developers strike a balance between performance and simplicity? What factors most advantageously position products in the market today to take advantage of the browser’s capabilities for client-side compute and interaction? And, finally, what are the less obvious reasons that everything is written in Rust?

This series will address trends I am following, where there is factional disagreement, and what all of this reveals about the state of software development more broadly. There’s a lot to cover on this subject so look for my future posts, and, as always, if there’s something I should know for my research on the JavaScript build space please reach out through LinkedIn, Twitter/X, or here in the comments.

No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *