---
title: "09 — Pick a Framework — Where the Reactivity Work Happens"
uid: pick-a-framework
tags: ["solidjs", "svelte", "react", "frameworks", "angular", "vue", "reactivity", "roadmap:frontend"]
excerpt: "Frameworks aren't competing brands — each is a shared way of turning state into UI. The axis that separates them: where the reactivity work actually happens."
date: 2026-08-12T18:35:11+0000
source: https://www.aveshina.my.id/en/blog/pick-a-framework
---

I used to look at frontend frameworks like a wall of rival soda brands. React, Vue, Angular, Svelte, SolidJS — five logos, five websites, five different ways to write the same button. It felt like picking a side, and I had no idea what I was actually choosing between.

Writing these notes finally straightened it out. It turns out all five are doing the exact same job, just in different places. Here's the one idea everything else hangs off: **a framework is an agreement about how to turn your data into what's on the screen, reliably.** You hold some data (developers call this *state*). The framework's job is to make the screen match that data, every time the data changes.

That job has a name: **reactive UI**. Instead of writing code that reaches into the page by hand and changes things — "set this text, update that number" — you just describe *how the screen should look for a given set of data*, and let the framework do the updating for you [1]. All five frameworks do this. The only thing that actually separates them is one question I couldn't see until I wrote it down: **where does the updating work happen?**

```figure
<svg viewBox="0 0 740 320" xmlns="http://www.w3.org/2000/svg" class="my-6 w-full max-w-2xl" role="img" aria-label="One shared node (your data) feeds three strategies for keeping the screen in sync. Left column In the browser: the framework draws a draft copy of the page, compares old vs new, and fixes only what changed. React and Vue sit here. Middle column Before it ships: the package step reads the code and writes update instructions wired straight to each piece of data, nothing to compare later. Svelte and SolidJS sit here. Right column Whole toolkit: one all-in-one package bundles navigation, forms, HTTP, and state together. Angular sits here.">
  <defs>
    <marker id="farrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
      <path d="M0,0 L10,5 L0,10 z" fill="#64748b"/>
    </marker>
  </defs>
  <g font-family="ui-sans-serif, system-ui, sans-serif" text-rendering="geometricPrecision">

    <!-- shared state node -->
    <rect x="290" y="14" width="160" height="46" rx="8" fill="#e0e7ff" stroke="#6366f1" stroke-width="1.5"/>
    <text x="370" y="36" font-size="13" font-weight="700" fill="#1e1b4b" text-anchor="middle">your data (state)</text>
    <text x="370" y="51" font-size="10" fill="#475569" text-anchor="middle">describe the screen from it</text>

    <!-- three columns -->
    <!-- In the browser -->
    <rect x="30" y="86" width="200" height="210" rx="10" fill="#eef2ff" stroke="#6366f1" stroke-width="1.5"/>
    <text x="130" y="108" font-size="12" font-weight="700" fill="#1e1b4b" text-anchor="middle">In the browser</text>
    <text x="130" y="124" font-size="10" fill="#475569" text-anchor="middle">compare &amp; fix</text>
    <text x="130" y="144" font-size="10" fill="#475569" text-anchor="middle">draw a draft of the page</text>
    <text x="130" y="158" font-size="10" fill="#475569" text-anchor="middle">spot the difference:</text>
    <text x="130" y="172" font-size="10" fill="#475569" text-anchor="middle">old vs new draft</text>
    <text x="130" y="186" font-size="10" fill="#475569" text-anchor="middle">fix only what changed</text>
    <rect x="55" y="232" width="150" height="44" rx="6" fill="#ffffff" stroke="#6366f1" stroke-width="1.2"/>
    <text x="130" y="259" font-size="12" font-weight="700" fill="#1e1b4b" text-anchor="middle">React · Vue</text>

    <!-- Before it ships -->
    <rect x="270" y="86" width="200" height="210" rx="10" fill="#ccfbf1" stroke="#0d9488" stroke-width="1.5"/>
    <text x="370" y="108" font-size="12" font-weight="700" fill="#134e4a" text-anchor="middle">Before it ships</text>
    <text x="370" y="124" font-size="10" fill="#475569" text-anchor="middle">pre-wired updates</text>
    <text x="370" y="144" font-size="10" fill="#475569" text-anchor="middle">package step reads the code</text>
    <text x="370" y="158" font-size="10" fill="#475569" text-anchor="middle">writes update instructions</text>
    <text x="370" y="172" font-size="10" fill="#475569" text-anchor="middle">wired to each piece of data</text>
    <text x="370" y="186" font-size="10" fill="#475569" text-anchor="middle">nothing to compare later</text>
    <rect x="295" y="232" width="150" height="44" rx="6" fill="#ffffff" stroke="#0d9488" stroke-width="1.2"/>
    <text x="370" y="259" font-size="12" font-weight="700" fill="#134e4a" text-anchor="middle">Svelte · SolidJS</text>

    <!-- Whole toolkit -->
    <rect x="510" y="86" width="200" height="210" rx="10" fill="#fef3c7" stroke="#ca8a04" stroke-width="1.5"/>
    <text x="610" y="108" font-size="12" font-weight="700" fill="#422006" text-anchor="middle">Whole toolkit</text>
    <text x="610" y="124" font-size="10" fill="#475569" text-anchor="middle">all-in-one</text>
    <text x="610" y="144" font-size="10" fill="#475569" text-anchor="middle">navigation, forms,</text>
    <text x="610" y="158" font-size="10" fill="#475569" text-anchor="middle">talking to a server, data</text>
    <text x="610" y="172" font-size="10" fill="#475569" text-anchor="middle">all bundled together</text>
    <text x="610" y="186" font-size="10" fill="#475569" text-anchor="middle">one official way to work</text>
    <rect x="535" y="232" width="150" height="44" rx="6" fill="#ffffff" stroke="#ca8a04" stroke-width="1.2"/>
    <text x="610" y="259" font-size="12" font-weight="700" fill="#422006" text-anchor="middle">Angular</text>

    <!-- arrows from state to each column -->
    <path d="M320,60 C250,72 180,76 130,86" fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#farrow)"/>
    <path d="M370,60 L370,86" fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#farrow)"/>
    <path d="M420,60 C490,72 560,76 610,86" fill="none" stroke="#64748b" stroke-width="1.5" marker-end="url(#farrow)"/>
  </g>
</svg>
```

Three lanes, not five rival teams. Once that clicks, "which framework?" stops being brand loyalty and becomes a practical question: *where do I want the work to live, and how much do I want the framework to decide for me?*

## The one thing they all share

Before we split into lanes, let's look at what all five have in common.

Picture a simple counter on a page. With plain JavaScript, every time the number changes you'd have to remember to reach into the page and update that number yourself — find the right element, set its text, again and again. On a real app with hundreds of moving parts, that's a nightmare to maintain: forget one place, or do them in the wrong order, and the screen drifts out of sync with your data.

A framework takes that whole chore off your hands. You *declare* "the counter shows count," and *something else* takes responsibility for keeping that true whenever count changes. That "something else" is the **reactivity system** — the part of the framework that watches your data and updates the screen for you [1][2].

That's the whole trick. Components, props, hooks, stores, templates — all the vocabulary people throw around — is just scaffolding built around this one promise. Understand the promise, and the three lanes below fall out naturally.

## Lane 1 — update in the browser: React and Vue

React and Vue do their reactivity work **in the browser, while the app is running** [2][3].

Here's the picture that made it stick for me. Imagine your component as a little recipe: you hand it some data, and it hands back a *description* of what the screen should look like. React and Vue don't write that description straight onto the page, though. They first write it onto a lightweight copy of the page kept in memory, called the **virtual DOM** — think of it as a draft sketch of the real page. When your data changes, the component draws a new draft, the framework plays **"spot the difference"** between the old draft and the new one, figures out the smallest set of changes, and applies just those changes to the real page.

Both work this way; the day-to-day feel just differs a little. **React** stays close to plain JavaScript — you describe the screen with code, and "the screen is a function of your data" is taken quite literally [2]. Your data lives in little containers called *hooks*, and the component re-draws when you tell it the data changed. **Vue** leans on HTML templates plus a smart tracking layer: you assign a value, and Vue quietly remembers exactly which parts of the template care about that value [3]. Vue tracks dependencies more precisely than React, but it still reconciles against a virtual DOM, so it lives in the same lane.

The cost of this lane: the browser has to carry a bit of extra machinery, and every update pays a small "compare and patch" fee. The upside is flexibility — you can build the screen from any code you like, and the same idea ports to other targets (React Native uses it for mobile). It's also, not coincidentally, the most popular lane in the industry, which matters for jobs and tutorials whether we like it or not.

## Lane 2 — update before it ships: Svelte and SolidJS

Svelte and SolidJS move the reactivity work **out of the browser and into the packaging step** — the moment when your app is built, before anyone opens it [4][5].

Think of it this way: in React and Vue, the component is alive in the browser, drawing drafts and playing spot-the-difference. In Svelte and SolidJS, the component is more like *source code that gets read during the build.* While packaging the app, the builder looks at which parts of the page depend on which pieces of data, and it **writes plain JavaScript that connects each part directly to the data it cares about.** No draft, no spot-the-difference, nothing extra to carry into the browser — just the exact instructions the page needs.

The two differ in *how* you express that reactivity. **Svelte** puts HTML, JavaScript, and CSS together in a single file and figures out the connections from your assignments — then generates the update instructions for you [4]. **SolidJS** keeps React-style syntax so it *looks* familiar, but underneath it uses something called **signals**: each piece of data is its own little signal, and the build step connects each part of the page to exactly the signals it reads [5]. So changing one value updates one spot — not a whole section of the page.

The cost: the packaging step is mandatory. A Svelte or Solid component isn't runnable JavaScript until it's been built, so you can't just drop it into a page and go. The win: speed and a smaller download — there's no extra framework machinery to carry, and updates skip the compare step entirely. This is the lane I'd reach for when how fast the page feels, or how much data it has to download, matters more than a huge ecosystem.

## Lane 3 — the whole toolkit: Angular

Angular sits in its own lane because it isn't just a way to draw the screen — it's an **all-in-one toolkit with a strong opinion about how to build an entire application** [6].

It still does reactive UI: your component renders from your data, and a change-detection system keeps the page in sync. But on top of that, it bundles in everything a big app tends to need, all made by the same team and designed to fit together: a router (for moving between pages), dependency injection (a way to hand each component the things it needs), a forms system, an HTTP client (for talking to a server), a way to manage data, a command-line tool, and a testing setup.

The cost is weight and opinion. Angular pushes you to use TypeScript and tells you *how* to structure things, so the learning curve is steeper and there's more boilerplate up front. The payoff is that on a large team, those shared rules end a hundred "but how do *we* do X?" arguments — the framework already decided. That's why Angular's reputation lives in **large enterprise** codebases: the "everything included, one way to do things" bet pays off when the project is big enough that the shared rules save more time than they cost [6]. It's the lane I'd pick when "one official way to do everything" beats "we want to choose our own pieces."

## How the lanes actually differ

The one question is the headline; the day-to-day consequences are where it shows up. Here's the whole thing in one table:

A few of those worth spelling out:

- **What the browser carries.** React and Vue ship some extra machinery. Svelte and SolidJS ship plain generated JavaScript, nothing extra. Angular ships the machinery *and* its toolkit.
- **What runs on each update.** React and Vue compare and patch. Svelte and SolidJS run instructions that go straight to the changed spot. Angular checks for changes across the screen, tuned by its OnPush optimization.
- **Who decides structure.** React and Vue give you components and leave the architecture to you. Svelte and SolidJS are similar but lighter. Angular decides the architecture for you.
- **Ecosystem and jobs.** React's is the biggest by a wide margin [2]; Vue is strong, especially in certain markets; Angular owns the enterprise niche; Svelte and SolidJS are smaller but growing.

None of these is "the best." They're trade-offs along the one axis that matters: work in the browser vs. work during packaging, freedom vs. opinion, ecosystem vs. efficiency.

## How I use this

The practical payoff is that "which framework?" becomes a calm question instead of a religious one. When someone asks, I don't reach for a brand anymore — I ask *which lane fits the constraints.*

- Small app, want to move fast, ecosystem matters? React or Vue.
- Care about speed or download size, and a build step is fine? Svelte or SolidJS.
- Large team that needs shared rules and a full toolkit? Angular.

The brand is downstream of the lane; the lane is downstream of the problem. That ordering is the whole reason I wrote these notes down.

## References

[1] roadmap.sh, "Frontend Beginner — Pick a Framework," 2024. [Online]. Available: [https://roadmap.sh/frontend/learn-a-framework](https://roadmap.sh/frontend/learn-a-framework)

[2] React Team, "Quick Start — Thinking in React," react.dev, 2024. [Online]. Available: [https://react.dev/learn](https://react.dev/learn)

[3] Vue.js Team, "Reactivity in Depth," vuejs.org, 2024. [Online]. Available: [https://vuejs.org/guide/extras/reactivity-in-depth.html](https://vuejs.org/guide/extras/reactivity-in-depth.html)

[4] R. Harris, "Virtual DOM is pure overhead," svelte.dev, 2018. [Online]. Available: [https://svelte.dev/blog/virtual-dom-is-pure-overhead](https://svelte.dev/blog/virtual-dom-is-pure-overhead)

[5] SolidJS Team, "Reactivity — SolidJS Documentation," solidjs.com, 2024. [Online]. Available: [https://www.solidjs.com/docs/latest#reactivity](https://www.solidjs.com/docs/latest#reactivity)

[6] Angular Team, "Introduction to the Angular docs," angular.dev, 2024. [Online]. Available: [https://angular.dev/overview](https://angular.dev/overview)

```quiz
Q: What is the one job all five frameworks share?
- Paint pixels directly to the screen
- Turn your data into what's on the screen, and keep the screen in sync when the data changes
- Replace HTML and CSS entirely
correct: 1
explain: Every framework is an agreement about reactive UI — you describe how the screen should look for a given set of data, and the framework handles the updating when that data changes.

Q: What single question best separates React/Vue from Svelte/SolidJS from Angular?
- The programming language they use
- Where the updating work happens — in the browser, during packaging, or inside a bundled toolkit
- Whether they use components
correct: 1
explain: React and Vue compare a draft in the browser; Svelte and SolidJS write update instructions during packaging; Angular bundles a full toolkit on top.

Q: Why do Svelte and SolidJS produce smaller downloads with no extra machinery?
- They compress the code harder
- A packaging step turns each component into plain JS wired directly to its data
- They rely on the browser's built-in updating
correct: 1
explain: The build step reads the component and writes instructions that update only the parts tied to each piece of data. No draft and no extra machinery need to be sent to the browser.

Q: A large enterprise team wants "one official way to do navigation, forms, HTTP, and DI." Which lane fits?
- Svelte / SolidJS
- The all-in-one toolkit lane (Angular)
- React / Vue
correct: 1
explain: Angular is the everything-included toolkit — it ships navigation, dependency injection, forms, HTTP, and data handling with shared rules, which is why it owns the large-enterprise niche.

Q: Vue uses a virtual DOM but tracks dependencies more precisely than React. Which lane does it belong in?
- The packaging-step lane
- The in-the-browser lane
- The all-in-one toolkit lane
correct: 1
explain: Despite its smarter tracking, Vue still reconciles against a virtual DOM in the browser, so it shares React's in-the-browser lane.
```
