惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
雷峰网
雷峰网
罗磊的独立博客
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
量子位
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
GbyAI
GbyAI
Cisco Talos Blog
Cisco Talos Blog
Engineering at Meta
Engineering at Meta
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
About on SuperTechFans
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Cloudflare Blog
Know Your Adversary
Know Your Adversary
T
Threat Research - Cisco Blogs
Spread Privacy
Spread Privacy
D
DataBreaches.Net
T
The Exploit Database - CXSecurity.com
K
Kaspersky official blog
Cyberwarzone
Cyberwarzone
爱范儿
爱范儿
U
Unit 42
Security Latest
Security Latest
M
MIT News - Artificial intelligence
月光博客
月光博客
Scott Helme
Scott Helme
G
Google Developers Blog
有赞技术团队
有赞技术团队
T
Tor Project blog
宝玉的分享
宝玉的分享
Y
Y Combinator Blog
博客园 - Franky
H
Hackread – Cybersecurity News, Data Breaches, AI and More
aimingoo的专栏
aimingoo的专栏
The GitHub Blog
The GitHub Blog
V
V2EX
B
Blog
Apple Machine Learning Research
Apple Machine Learning Research
S
Securelist
博客园 - 三生石上(FineUI控件)
Blog — PlanetScale
Blog — PlanetScale
TaoSecurity Blog
TaoSecurity Blog
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
腾讯CDC
D
Docker
Google Online Security Blog
Google Online Security Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Runtime Is Not the Problem
Viktor Lázár · 2026-05-13 · via DEV Community

The most popular story about modern UI frameworks is wonderfully clean. Svelte is small because it is compiled. React is large because it ships a runtime. One moves work to build time; the other carries a machine into the browser. If the question is why a small Svelte app often starts smaller than a small React app, that story is not wrong.

It is only too small.

The important distinction is not compiled vs runtime. The important distinction is specialized output vs packaged capability. A compiler can specialize the program because it sees the component. A runtime can be small if it is packaged as a set of capabilities the application actually uses. The waste appears when a runtime is distributed as a single old monolith: one root API makes the app pay for the whole engine, including paths that only matter to applications much more complex than the one being shipped.

That is not the inevitable cost of React's model. It is the cost of React's packaging shape.

React is not large because runtime frameworks must be large. React is large because the browser-facing React we install today is still assembled like a general-purpose engine rather than a capability graph. If that graph were exposed to bundlers and compilers as static structure, dead-code elimination and tree shaking could do much more of the work people currently credit only to compiled frameworks.

The compiler is not magic. The runtime is not the enemy. The question is where the framework pays for generality, and whether the application is allowed to decline the parts of that generality it does not use.

The Clean Story

Svelte's pitch has always been easy to understand. The official site describes Svelte as a framework that uses a compiler so components do minimal work in the browser. Older Svelte copy made the contrast even sharper: move as much work as possible out of the browser and into the build step. That is a powerful architectural statement because the browser receives code shaped around the application, not a general interpreter for a component model.

React's browser story is different. A React app calls createRoot or hydrateRoot from react-dom/client, and from that moment React owns the tree. The application ships a runtime because the runtime is the thing that keeps React's programming model true after the JavaScript has loaded.

At the scale of a counter, the contrast is almost unfair.

A compiler can look at a tiny counter and emit code that changes the text when the number changes. A runtime framework has to make even that counter an instance of a broader component language. That language is the source of React's power, but it also means the smallest program starts by importing a model built for much larger programs.

This is why small examples make compiled frameworks look so good. They are not paying for the general case before the general case appears.

But the small example also distorts the argument. A real application is not one counter. It is product pressure accumulated over time. Local decisions become global constraints. Dependencies surround the framework. Behavior that began in one place starts to matter somewhere else. At that point, "compiled vs runtime" stops being a binary and becomes a curve.

The Size Curve

The size curve begins with the floor: the amount of JavaScript you ship before the application has done anything interesting. React's floor is visible because react and react-dom are real packages with real client runtime code. Svelte's floor is lower because more of the component model has been consumed by the compiler before the browser ever sees it.

But the floor is only the beginning. The slope matters just as much, because the application does not stay at its starter size. A framework that starts tiny can grow quickly if its compiled output repeats itself. A framework with a higher floor can become relatively cheaper if its runtime amortizes shared behavior well.

Compiled frameworks often have a low floor because they emit specialized code. But specialized code can repeat. If every component carries its own little version of a pattern, the app may pay the same idea many times. Good compilers avoid this by sharing helpers and by lowering common patterns into reusable runtime pieces, which is another way of saying that compiled frameworks also have runtimes. The difference is that those runtimes have already been filtered through the compiler's view of the app.

Runtime frameworks often have a higher floor because they ship the general machine once. But after that first payment, repeated components can be cheap because they are data for the same machine. The runtime does not need a new implementation of the update model for every component. The application describes the tree; the runtime interprets the description.

So the size question should not be "which framework is smaller?" That question hides the shape of the payment. A framework has an initial fixed cost, and it has a growth rate as features are added. The architecture is healthy when the route mostly pays for what it uses. Repeated behavior should be amortized. Absent capability should remain absent from the output.

Tiny islands usually favor the compiler. Larger applications make the answer depend on the curve rather than the category. Once product dependencies dominate the bundle, the framework tax may look smaller in percentage terms, but it has become more architectural: it follows the application into every place that wanted to stay small.

The useful measurement is not the total size of node_modules. It is not even the total output directory. It is the JavaScript on the critical path for a user action. The important bytes are the ones that stand between the user and the first interactive route. After that, the question is whether new code arrives only when the user moves into new behavior, or whether the framework has forced unrelated capability onto the path.

That last question is where React becomes interesting.

React's Monolith Problem

React's public model is beautifully small. Its user-facing idea is compact enough that it survived a decade of ecosystem churn: components make UI feel like ordinary program structure.

The shipped runtime is not compact in the same way.

That is not a criticism of the React team's engineering discipline. React carries a lot because React does a lot. It has to keep a very broad rendering contract true across browsers, across rendering modes, and across years of ecosystem assumptions. The weight is not accidental. The question is whether all of that weight belongs on every route.

The problem is that the browser package is arranged around the general product, not around the current application's capability set.

A simple client-rendered widget does not ask the same question as a server-rendered application that hydrates, streams, recovers from errors, and coordinates work across a large tree. A tiny island with one click handler should be allowed to stay tiny. A component that only needs local interaction should not inherit the full mental weight of an application root.

Today, those distinctions are mostly semantic. They matter to the developer. They matter to the runtime once the app is running. But they are not exposed as a clean static import graph that a bundler can prune aggressively.

The package boundary says: this is React DOM for the client.

It does not say: this route needs the small DOM-and-state subset, while the machinery for richer rendering modes can stay out of the bundle.

That second sentence is what a capability-shaped React would need to make visible.

The Host Is Part of the Cost

There is another asymmetry hidden inside the usual Svelte-vs-React comparison. Svelte's mainstream target is the web DOM. That focus is part of why the compiler can be so effective. It knows the host it is lowering into. It can turn a component into browser-shaped code because the browser is the world the component is meant to inhabit.

That is not an insult. It is a strength. A compiler gains power when the target is narrow enough to make strong decisions.

React's abstraction boundary is different. React DOM is not React; it is one renderer for React. The component model sits above the host. PDF and canvas renderers make the point clearly: React's component approach is not inherently a DOM approach. Those targets do not make the browser bundle smaller. But they do explain why React wants to be a component model before it is a DOM compiler.

This matters because some of React's weight is the price of that separation. A framework tied closely to the DOM can specialize earlier. A framework that treats the DOM as one host among several has to preserve a more abstract contract. That contract is valuable. It lets the same mental model cross output targets in a way a DOM-first compiler does not naturally promise.

But the conclusion should not be that every DOM app must carry the full cost of host-agnostic generality. The renderer boundary is exactly where capability packaging should help. If an application is only using React as a small DOM island, it should not pay as if it were exercising the entire host-independent model. React's multi-target nature explains the need for abstraction. It does not justify an undifferentiated browser bundle.

Tree Shaking Needs Shape

Tree shaking is often described as if it were a magic vacuum that removes whatever code the app does not use. It is less magical than that. Bundlers need static structure. Webpack's own guide is blunt about the ingredients: ES module syntax, production optimizations, and accurate side-effect information are what let unused exports and whole modules disappear.

This is why library shape matters so much.

If a package exposes independent modules with pure exports, the bundler has something to understand. If a package exposes one entry point whose evaluation may affect the whole runtime, the bundler has to be conservative. In JavaScript, conservatism means bytes. If evaluating a module might matter, the module stays.

React is especially difficult here because many capabilities are not normal userland functions. They are semantics inside the renderer. The app imports the renderer, not a set of isolated implementations the bundler can reason about one by one.

That is the old monolith shape.

Not old because the code is bad. Old because the distribution model assumes that the framework is one coherent runtime and the application either uses that runtime or it does not. That assumption made sense when coarse package boundaries were normal and framework competition was mostly about programming model rather than transferred JavaScript. It makes less sense now that applications are expected to move through finer-grained delivery paths, and when build tools care deeply about static structure.

Dead-code elimination cannot remove a capability it cannot see.

What a Capability Graph Would Mean

Imagine React distributed less like a runtime blob and more like a set of capabilities.

The application root would not mean "give me the whole browser renderer." It would declare a rendering mode, and that mode would imply the runtime capabilities needed to preserve React's semantics for that part of the app.

Hooks would not be one undifferentiated runtime assumption. The common local primitives would form the base layer; coordination primitives would be added only when the app uses them. Some of that machinery would still be shared, and some of it would be impossible to remove in practice because the component model depends on it. But the graph would at least describe the difference between "this app uses local state" and "this app uses the full coordination model React exposes."

The DOM event system would follow the same rule. A form route should not pay for event families it never uses. A static island with one button should not inherit the same event surface as a canvas-heavy editor.

Hydration would be a capability, not a tax hidden behind the same import shape as client rendering. The richer runtime features would be visible in the graph instead of being treated as ambient facts of the renderer. Development diagnostics would remain development-only with a boundary that production bundlers can see without heroic inference.

The compiler would participate, but it would not replace the runtime. JSX compilation and React Compiler output could describe what the app actually uses. Framework and bundler layers could then carry that information into the package graph. This is the shape of the missing information: the app already contains the answer, but the framework does not package itself in a way that lets the build pipeline use the answer fully.

In that world, React would still be a runtime framework. It would still provide the live component semantics people choose React for. But a small app would no longer pay for the whole semantic universe before it had earned it.

That is the part the compiled-vs-runtime argument misses. A runtime can be tree-shaken if it is designed as something tree-shakable.

Compilation Is a Form of Packaging

The word "compiled" makes Svelte sound like it lives in a different category, but compilation is also a packaging strategy.

The compiler looks at the application and decides what code to emit. Its real advantage is that it filters the runtime surface through what the program can prove at build time. The result is not "no runtime." The result is a runtime surface that has already been filtered through the program.

That filtering is the real advantage.

A compiler gets to ask: what does this component actually do?

A capability-shaped runtime gets to ask almost the same question: what capabilities does this application actually use?

Those two approaches are closer than the marketing categories suggest. The best future is probably not compiled frameworks on one side and runtime frameworks on the other. It is compiler-assisted runtimes with small, explicit capability graphs. It is frameworks whose core semantics can remain general while their shipped code becomes specific.

Svelte starts from specialization and adds shared machinery when specialization would repeat too much. React starts from shared machinery and could recover specialization by making the machinery divisible. The direction is different. The destination is similar: the browser should receive the smallest faithful implementation of the app's semantics.

The App Size Conversation We Should Have

When people compare Svelte and React bundle sizes, they often compare starter apps. Starter apps are useful because they reveal the floor. They are also dangerous because they make the floor feel like the whole building.

A better comparison would walk the same frameworks through a growth path. It would start with a tiny island and keep adding the kinds of pressure real products accumulate. The point would not be to make the examples impressive. The point would be to see how the framework's fixed cost behaves as the application stops being a toy.

For each one, the measurement should separate framework cost from app cost and route cost from total build output. A framework that looks expensive at the beginning may disappear behind the product later. A framework that looks tiny at the beginning may duplicate enough specialized output to make the curve less obvious. A framework that lazy-loads well may win on the first route even if its total app output is larger.

The point of this exercise is not to crown a universal winner. The point is to see the shape of payment.

Svelte's bet is that many UI programs are better served by paying at build time and shipping specialized code. React's bet has been that many UI programs are better served by a stable runtime model that can express a very wide range of behavior. Both bets are legitimate. The problem is when React's bet is implemented as if every page needs the full runtime model up front.

That is where React's size becomes less philosophical and more mechanical.

The Smaller React That Could Exist

There is a smaller React hiding inside React.

Not Preact. Not a compatibility clone. Not a new framework with React-like syntax. React itself, if its distribution model matched the way modern applications are built.

That React would have a small root for client-only islands. Server-rendered roots would opt into hydration as a visible capability. More advanced rendering behavior would be added by use, not smuggled in as part of the default client entry point. The important change would be static structure: bundlers would be able to remove entire subtrees without understanding React's internals, and framework adapters could declare the rendering mode they need per route.

This would not be easy. React's internal semantics are deeply connected. Splitting a renderer after years of integrated design is harder than designing a small library from scratch. Some capabilities that look optional from the outside may share invariants that make them hard to separate safely. The compatibility contract is enormous, and every new boundary is another place where bugs can hide.

But difficulty is not impossibility, and it is not a rebuttal to the architectural point.

The React programming model does not require the browser bundle to be a monolith. It requires a runtime capable of preserving React's semantics for the capabilities the application uses. Those are different requirements. One is historical packaging. The other is the actual product.

If React were designed today for the way applications are delivered now, it is hard to imagine it would expose the same coarse client runtime as the only normal path. It would be capability-first from the beginning because the web now punishes undifferentiated JavaScript more visibly than it did when React's package shape hardened.

Runtime Is Still Valuable

It is tempting, after all of this, to conclude that runtimes are a regrettable compromise. They are not.

Runtimes buy consistency. They make dynamic behavior composable across the lifetime of an app and across code-splitting boundaries. They can also see more of the live application than any one compiled component can, which makes the runtime behavior richer than a pile of emitted code.

Those are real advantages. They are why React won so much mindshare in the first place.

The mistake is treating runtime value and runtime size as inseparable. A runtime is not a single object by nature. It can be layered, declared, and assisted by a compiler that proves which layers are needed. A framework can keep a high-level programming model without forcing every route to ship every lower-level mechanism.

The right criticism of React is not "React has a runtime."

The right criticism is "React's runtime is not packaged according to the capabilities of the app."

That is a much more useful criticism because it points toward a better React rather than toward a world where every framework has to become Svelte.

The Real Divide

The real divide is not compiled vs runtime.

The real divide is specific vs undifferentiated.

Specific means the browser receives code shaped around the current program. For a compiled framework, that shape comes from emitted output. For a runtime framework, it has to come from capability boundaries. Undifferentiated means the framework ships its generality before the app has asked for it.

This is the lens that makes the argument clearer.

Svelte is not small because compilers are holy. It is small because the compiler gives the package manager and bundler a more app-shaped output. React is not large because runtimes are doomed. It is large because the output is still too framework-shaped.

The browser does not care whether a byte came from a compiler or a runtime package. It cares whether the byte is necessary for the current experience. Users do not reward architectural purity. They reward pages that load quickly, become interactive quickly, and stay responsive under real product pressure.

So the question for any framework should be simple:

Can the smallest app receive the smallest faithful version of your model?

If the answer is yes, the framework scales downward. It can start small without being a toy. If the answer is no, the framework may still be powerful, mature, and worth choosing, but its size problem is not a law of nature. It is a distribution problem.

React could be small. Not by becoming Svelte. Not by abandoning runtime semantics. By admitting, in its package shape, that applications do not use frameworks all at once.

They use capabilities.

And capabilities are exactly the kind of thing a modern build pipeline can remove when they are absent, if only the framework is built to let them be absent.