There's no build like #nobuild.

When I started out with web development back in the late 90‘s, I did so with a program called Microsoft Frontpage Express. It was a WYSIWYG (What you see is what you get) editor, not unlike other authoring solutions like office word processors etc. it let you create your content (in this case a website) visually. It was quite empowering back then and it didn‘t even occur to me that there could be people who would want to write HTML by hand.

When switching to the HTML view, I was presented with a weird mix of tag salad. Who would want to deal with that mess? When editing files in a visual manner, only the visual cleanliness becomes important, the structure below is secondary.

In another context, I saw many rich text office documents over the years that looked perfectly fine on first glance, but taking a closer look revealed a complete lack of structure. No style definitions were made, like a consistent formatting for heading, lists and paragraphs. Changing the style of a heading later became a real pain, since it meant going through the whole document, changing text sizes and other properties in dozens of places. With consistent use of formatting styles, changing style properties for the whole document can be done in seconds and with confidence.

It's the same with properly structured HTML - maintenance gets way easier and debugging as well. Consistent formatting requires a minimal structure of human-readable, semantic code. This is pretty much common knowledge among frontend developers these days. Few people still use HTML-generating tools and don't care about the output.

But I only recently realized, that the same principle can also be applied to Javascript and CSS code.

In the world of frontend development, more and more tooling has been created over the years, dealing with dependency management, asset compilation and minification that produces a completely unreadable and often bloated mess.
To debug this output we had to produce even more output in the form of sourcemaps, which map locations of code in the unreadable output to their original place in our written code. Some frameworks even come with their own browser extensions to help us make sense of what goes on behind the scenes.

In a project a couple of years ago, I was tasked with writing a small to medium-size frontend application for a high-security environment. Malicious NPM package updates were in the news back then and the decision was made to drop NPM completely. I had dabbled with Vanilla JS for a while and took the opportunity to go "nobuild" on this project and scratch even jQuery or any other 3rd party code from the list. It was just gonna be me, my editor and the MDN documentation.

It was just gonna be me, my editor and the MDN documentation.

To my surprise, the experience turned out to be quite magical. I could make changes to the JS file and promptly reload the changes in the browser. Any error popping up was correctly displayed in the developer tools in my browser in my own code, exactly as I had written it. Performance was a blast, as I could make DOM updates as fast as technically possible, without jumping through any hurdles or dealing with any kind of overhead.

Same with CSS. Since the Internet Explorer was retired officially and people are now using mostly modern browsers with regular automatic updates, the need for polyfills decreased dramatically. I didn't even deploy a CSS-reset of any kind, wich are CSS declarations meant to "normalize" browser behaviour around certain default properties, like margins and paddings, etc.

The amount of CSS needed to implement the application layout, forms and typography was tiny. For previous projects, I had often used Bootstrap for grids and layout, so instead of reinventing the wheel there, I just cherry-picked that part of Bootstrap into my project, saving me from the bloat of the whole framework. [1]

I recently came back to that project and did a rewrite in modern ESM based JS and found the experience even increased further, learning about import maps, web components and tagged template literals, but more about those in another post.

Today, it's hard for me to imagine going back to the world of build tools and complex compilation, seeing all the little quality of life improvements in my day-to-day work and I can only encourage other frontend-developers to experiment with current standards, it might surprise them how little code is actually needed to replace much more complex solutions.

Thanks for reading! Want to add something or stay up-to-date with new articles? Please subscribe to leave comments and get my newsletter.


  1. That being said, nowadays I'm growing very fond of Tailwind CSS, which gives me the same usability like Bootstrap, namely semantic classes inside HTML, but compiles down to a very small footprint. It is a compilation step, yes, but for more elaborate projects I think it's worth the abstraction, CSS compilation artifacts are usually still quite accessible and the Tailwind tooling allows for usage without NPM, through a standalone binary. ↩︎

Discussion