mission brief (the research question)
The thesis asked a focused question: what is it actually like to build a Progressive Web App in Blazor versus the JavaScript mainstream? Blazor lets you write front-end code in C# and run it in the browser via WebAssembly — but does it hold up against an established framework for the things a PWA has to do?
To answer it fairly, I built the same application twice — once in Blazor WebAssembly (.NET 8), once in Vue.js (Vue 3.4.29 + Vite) — with identical functionality and a shared backend. With the design held constant, any difference that surfaced could be attributed to the framework itself, not to how the app was designed. Vue served as the widely-adopted benchmark; Blazor was the system under evaluation.
the testbed (DartPointTracker)
The shared application is DartPointTracker, a darts scorekeeper. Players reduce a starting score (301 / 501) to exactly zero; the app records every throw, computes the remaining points in real time, and presents final standings — removing the mental arithmetic from the game. On top of scorekeeping it runs an Elo ranking: every player starts at 1000, and results shift the ranking up or down after each match.
- setup
StartGame
Pick a game mode (301/501), add existing players, or create new profiles — via the ChoosePlayer and CreateNewPlayer modals.
- play
PlayGame
Per-throw score entry (ChoosePoint), live remaining scores, turn management, and a GameSummary with final standings.
- rank
PlayerRanking
The Elo leaderboard — current standings, updated from completed games sent back to the server.
- pwa
Installable & offline
A Web App Manifest makes it installable to the home screen; a service worker handles offline scorekeeping and asset caching, with background sync for results.
trajectory (shared architecture)
Both front-ends sit on one identical backbone: a web server with a REST API over HTTPS and a database for player and Elo data. The two clients are component-based and structurally mirror each other (App → MainLayout → NavMenu → views), so the comparison stays honest.
- client A
Blazor WebAssembly
C# in the browser via WebAssembly, scaffolded with
dotnet new blazorwasm --pwa— manifest and service worker pre-configured out of the box. - client B
Vue 3 + Vite
The benchmark client, with PWA support added manually through
vite-plugin-pwa(service worker, caching strategy, and manifest configured invite.config.js). - shared
API + database
One backend behind both: processes game results, manages players, and computes Elo. The single source of truth that keeps both clients comparable.
findings (what the data showed)
The verdict. Blazor fully meets every PWA requirement — installability, offline support, background sync — and produces a noticeably smaller, more maintainable codebase. The cost is weight and speed: a multi-megabyte runtime and the constant tax of crossing the WebAssembly–JavaScript boundary for DOM updates and network calls. Interestingly, for pure computation at scale (sorting 5,000 players) WebAssembly pulled ahead of JavaScript.
Conclusion: Blazor WebAssembly is a sound choice for PWAs where raw performance isn't the priority — especially for .NET-experienced teams and in-house tools, where development speed and long-term maintainability matter more than shaving milliseconds.