How BaseNative compares
An honest look at BaseNative alongside React, Angular, and Svelte. Where it wins, where it doesn't, and why that matters.
Bundle size
BaseNative ships raw ES modules. No bundler, no tree-shaking needed — what you import is what runs. The entire runtime is readable in one sitting.
| BaseNative | React 19 | Angular 19 | Svelte 5 | |
|---|---|---|---|---|
| Runtime size (min+gz) | ~5 KB | ~44 KB | ~130 KB | ~5 KB |
| Production deps | 0 | 2 (react, react-dom) | 6+ (zone.js, rxjs, ...) | 0 |
| Build step | None | Required (JSX) | Required (TS + AOT) | Required (compiler) |
| Source you can read | ~700 lines | ~80K lines | ~300K+ lines | ~15K lines |
API surface
Fewer primitives means less to learn, less to break, and less for AI tools to hallucinate. BaseNative's entire reactivity model fits on a whiteboard.
| BaseNative | React 19 | Angular 19 | Svelte 5 | |
|---|---|---|---|---|
| Core concepts to learn | 6 | 15+ hooks | 30+ concepts | ~8 runes |
| Reactivity model | Signals (push) | Virtual DOM (pull) | Signals (push) | Runes/compiler (push) |
| Template syntax | Valid HTML | JSX (not HTML) | Extended HTML | Custom (.svelte) |
| TypeScript | Optional | Optional | Required | Optional |
Counter: the same app, four ways
A reactive counter shows each framework's mental model. BaseNative uses plain HTML with signal expressions — no compilation, no special file format.
<div :data="{ count: 0 }">
<p>Count: {{ count }}</p>
<button @click="count++">+1</button>
</div>
<script type="module">
import { hydrate } from './signals.js';
hydrate();
</script>
Valid HTML. No build. Drop a script tag and go.
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>
+1
</button>
</div>
);
}
Requires JSX transpilation, a bundler, and react + react-dom installed.
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<p>Count: {{ count() }}</p>
<button (click)="count.set(count() + 1)">
+1
</button>
`,
})
export class CounterComponent {
count = signal(0);
}
Requires TypeScript, Angular CLI, AOT compilation, and the full Angular runtime.
<script>
let count = $state(0);
</script>
<p>Count: {count}</p>
<button onclick={() => count++}>+1</button>
Concise, but requires the Svelte compiler — no .svelte files run natively in browsers.
SSR and hydration
BaseNative includes server rendering and four built-in lazy hydration strategies out of the box. Most frameworks require extra packages or custom implementations for selective hydration.
| BaseNative | React 19 | Angular 19 | Svelte 5 | |
|---|---|---|---|---|
| SSR built-in | Yes | Via Next.js / manual | Yes (Universal) | Via SvelteKit |
| Lazy hydration | 4 strategies built-in | Manual / React.lazy | @defer (partial) | Manual |
| Hydration strategies | idle, interaction, media, viewport | N/A | @defer on viewport | N/A |
| CSP-safe expressions | Yes (no eval/Function) | Yes (JSX compiled) | Yes (AOT compiled) | Yes (compiled) |
Developer experience
| BaseNative | React 19 | Angular 19 | Svelte 5 | |
|---|---|---|---|---|
| Time to first render | Open HTML file | npx create-react-app | ng new + ng serve | npx sv create |
| Hot reload | Browser refresh | Fast Refresh | HMR | HMR |
| Ecosystem packages | Growing | Massive | Large | Moderate |
| Component model | None (vanilla DOM) | Components + hooks | Components + DI | Components |
| Community size | Solo project | Millions | Millions | Hundreds of thousands |
Honest tradeoffs
BaseNative isn't trying to replace React or Angular for every use case. Here's where it genuinely excels and where you should think twice.
Where BaseNative wins
- Zero build, zero deps — ship an HTML file
- Entire runtime is auditable in minutes
- 4 built-in lazy hydration strategies
- CSP-safe without compilation
- Valid HTML templates that work without JS
- 9x smaller than React, 26x smaller than Angular
- AI-friendly: 6 primitives, not 30
Where others win
- No component model — composition is vanilla DOM
- Ecosystem of one — no third-party component libs
- No HMR — manual browser refresh during dev
- Runtime expression parsing has overhead vs compiled output
- Svelte matches on size and exceeds on DX polish
- No React DevTools, no Angular CLI, no Svelte inspector
- Solo-maintained — bus factor of one
When to choose BaseNative
Good fit
- Content sites that need light interactivity
- Projects where you want to own every line
- Edge-deployed apps on Cloudflare Workers
- Teams tired of build tool churn
- Prototypes that need to ship in minutes
- Embedded widgets in existing pages
Probably not
- Large team apps that need enforced architecture
- Projects requiring deep third-party integrations
- Apps where HMR and devtools are critical workflow
- Enterprise apps with strict hiring pool requirements
- Complex SPAs with hundreds of components
Try it
The entire reactivity system is 122 lines. Read it, understand it, then decide.