Building Modern Web Apps Without Heavy Frameworks
Are you still using extensive frameworks and component libraries for your web applications? It’s time to take a look at the current possibilities offered by modern Web APIs. With Web Components, Custom Elements, Shadow DOM, and HTML Templates, you can now create high-performance, maintainable, and reusable UI components—completely framework-free.
A Journey Through Web Development Tools
Over the years, I’ve used countless tools to build web applications. Here’s an unsorted list of what I remember: jQuery, Backbone.js, Knockout, Angular, React, Vue, Svelte, Bootstrap, Foundation, Vuetify, and Material UI. These were often combined with languages like CoffeeScript, TypeScript, SCSS, and LESS, and build tools like Gulp, Grunt, Webpack, Rollup, and Vite.
And of course, let’s not forget the countless NPM packages required to extend functionality. Modularizing complex web apps was always a particular challenge. Code splitting was often cumbersome, and there were different ways to define modules. While ES Modules are standard today, it took a while to get there, with AMD, CommonJS, and UMD preceding them. And these are just the things that come to mind spontaneously.
The Shift to Modern Web Standards
In recent years, I’ve moved away from frameworks and libraries. Instead, I now rely on modern Web APIs and standards. The result is lean, performant, and maintainable applications that manage without extensive frameworks.
Here are some of the key technologies I use:
- Bun as a runtime and build tool
- TypeScript for type safety
- ES Modules for native code organization
- Web Components (specifically Lit)
- Custom Elements
- SCSS for styling
Web technologies have evolved enormously over the past 30 years. HTML started out simple and static. CSS added design, and JavaScript enabled interactivity. But it’s only in the last few years that we’ve truly gained powerful, native APIs and standards that allow us to build complex applications directly in the browser—without frameworks.
To be clear, all the frameworks and libraries I’ve used did a fantastic job. They solved many problems and accelerated development. But they also added complexity and dependencies. Today, we can solve many of these problems directly with the Web APIs provided by the browser. However, this requires a shift in mindset and a willingness to engage with the new technologies.
My Modern Development Blueprint
Here’s a brief sketch of how I build web applications today:
First, I use Bun as my build tool. It’s fast, easy to configure, and has native support for TypeScript. TypeScript is indispensable to me for its type safety and improved code maintainability.
However, I no longer build SPAs (Single-Page Applications) with it. Instead, I focus on MPAs (Multi-Page Applications). This means each page is its own HTML file, delivered by the server. The advantage is that pages load quickly and are self-contained. SPAs solved a problem that is largely irrelevant today thanks to modern browsers and Web APIs. With Web Workers and the Transition API, we can now create highly performant applications without relying on the SPA model.
I create my components using Web Components and Custom Elements. This allows me to define my own HTML tags that can be used across my pages. These components are reusable, encapsulate their own style and logic, and can be easily integrated into different projects. For styling, I use SCSS because it allows me to write modular and maintainable CSS.
The Benefits of a Custom Approach
It’s important to note that I don’t use pre-built component libraries. Instead, I create my own components, tailored precisely to my needs. The advantage is that I avoid unnecessary complexity and dependencies. Plus, my applications become very lean and performant.
Admittedly, writing everything yourself can be tedious. But it’s worth it, as the possibilities with modern CSS and Web APIs are enormous. And it’s fun to have full control over the code. I primarily use AI to generate the initial HTML and SCSS for me. This saves an enormous amount of time and allows me to focus on the logic. The results are surprisingly good, and I can still adjust the code if something isn’t quite right.
Conclusion: Lean, Performant, and Under Control
Overall, I am very satisfied with my current setup. It is lean, performant, and maintainable. And I have full control over the code. It certainly requires a rethink and a willingness to engage with new technologies. But it’s worth it because the possibilities are immense.