Systematic exploration of 14+ modern frameworks and runtimes across web, mobile, desktop, and server

Most developers learn a new framework when a job or project requires it. A contract arrives, the tech stack is set, and you learn just enough to ship. That is a reasonable strategy — it keeps learning tethered to necessity. It is also reactive, which means your mental model of the landscape is always shaped by whoever last hired you, not by your own evaluation of the tools. You accumulate options, but you default to whatever is familiar because you have no firsthand basis for comparison.
I started this sandbox in 2022 with a different premise: evaluate frameworks before I need them, so that when a real technical decision arrives — for a client project, for one of my own products, for a team — I am choosing from evidence rather than habit. Every framework went past hello-world to something functional: real routing, real state, real persistence, something that pushed against the framework's opinions hard enough to feel where the friction lives. Not enough to ship a production app, but enough to understand the argument the framework is making and whether that argument is right for a given context.
Over four years (2022–2026) that added up to 14+ frameworks across every surface: web (Astro, Remix, SolidJS, SvelteKit, TanStack Start, Vue, Nuxt), mobile (Expo, Flutter), desktop (Tauri, Electron), server and edge runtimes (Elysia, Hono, Bun, Deno, NestJS), and build infrastructure (Turborepo, Nx, Electric SQL). The goal was never uniform depth. It was a firsthand read on each one — enough to know where it wins, where it struggles, and when I would reach for it versus something else.
The most valuable distinction the sandbox surfaced was not syntax — it was the fundamental question of where computation belongs.
The server-first camp — Remix, Astro, Hono, Elysia — forced a reexamination of defaults I had inherited from the React SPA era. Working in Remix for several months made the cost of client-side data fetching visceral: two round trips, loading states, skeleton screens, hydration overhead — all of it exists because data fetching was moved out of the right place. Astro's islands architecture made the inverse case: ship no JavaScript unless the page actually needs it. Once you have felt both models from the inside, "server-first vs client-first" stops being a talking point and becomes a question you ask about every new project.
The reactive programming camp — SolidJS, SvelteKit, Vue — taught the difference between a framework that layers reactivity on top of a rendering model and one that is built on it. SolidJS signals do not re-render components; they update the exact DOM node that subscribed to the signal. Once you understand why that matters, you cannot look at React's reconciler the same way. The insight is not "React is bad" — it is that the virtual DOM is a tradeoff, and knowing what you are trading is what makes you a better architect of component systems.
The cross-platform camp — Expo, Flutter, Tauri, Electron — was the most humbling. Flutter's widget tree composes differently enough from the web that it required genuine re-orientation, not just new syntax. Tauri showed what is possible when you bundle a Rust backend with a web frontend instead of shipping a 120MB Chromium binary. These are not tools I use daily, but knowing their actual tradeoffs means I can have an honest conversation about mobile or desktop scope without guessing at costs.
The sandbox paid for itself concretely.
When building Sangam, I needed a TypeScript server framework. The habitual choice would have been Express or Fastify — well-documented, battle-tested, the defaults. But I had already built a functional API with Elysia and understood that its treaty system delivers end-to-end type safety between the server and the client with zero code generation. That is not a feature you discover from a README; it is one you feel when a client call is wrong and TypeScript surfaces the error before the request fires. Elysia won on that evidence, not on reputation.
For the Karmpath monorepo, I evaluated both Turborepo and Nx with real projects under each. Turborepo is simpler to configure. Nx has affected task detection — it builds only the packages that changed and everything that depends on them. At 21 packages in the Karmpath workspace, the difference was measurable in CI minutes. I knew to look for that specific capability because I had already run both tools past the point where the distinction mattered.
For Karmpath's auth layer, the requirement was seven distinct roles with permissions that compose differently across the app. Better Auth's first-class RBAC plugin handles that model without building custom middleware chains. I had evaluated Better Auth in the sandbox when it launched, so when the requirement arrived the decision was already made.
Breadth without depth is a liability. A developer who has installed fourteen frameworks but shipped nothing seriously in any of them is not more capable — they are just more opinionated. This sandbox was always paired with deep production use of a subset: Next.js across multiple shipped products, Elysia in a production API, Drizzle and PostgreSQL on every data layer I own. The depth is where real judgment lives. The breadth is what makes the depth more deliberate — I know why I chose Next.js over Remix for the portfolio, not just that I chose it, and I can defend that trade-off in a technical conversation without hedging.
Did this resonate?