| name | reactivity |
| description | Compile-time JS philosophy |
Rich Harris JavaScript Philosophy
Applying Rich Harris' "compile-time over runtime" philosophy from Svelte and Rollup. The best runtime code is no runtime code.
Core Philosophy
Shift Work to Compile Time
"Frameworks are not tools for organizing your code. They're tools for organizing your mind."
The virtual DOM was a necessary hack, not a permanent solution. Compile-time analysis can eliminate runtime overhead entirely.
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
<script>
let count = 0;
</script>
<button on:click={() => count++}>{count}</button>
Ship Less JavaScript
Every byte of JavaScript has a cost:
- Download time
- Parse time
- Compile time
- Execute time
The fastest JavaScript is JavaScript you don't ship.
Reactivity Should Be Automatic
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
$: document.title = `Count: ${count}`;
Bundling Philosophy (Rollup)
Tree Shaking Done Right
export function used() { return 'used'; }
export function unused() { return 'unused'; }
import { used } from './utils.js';
console.log(used());
Why Rollup is better at tree-shaking:
- ES modules only (no CommonJS ambiguity)
- Static analysis of imports/exports
- No side-effect assumptions unless marked
Code Splitting Philosophy
const routes = {
'/dashboard': () => import('./routes/Dashboard.svelte'),
'/settings': () => import('./routes/Settings.svelte'),
};
Framework Trade-offs
Virtual DOM Costs
| Operation | Virtual DOM | Compiled (Svelte) |
|---|
| Create element | Create VDOM node + diff + create real | Create real element |
| Update text | Create VDOM + diff + update real | Update real element |
| Memory | VDOM tree + real DOM | Real DOM only |
| Bundle size | Framework runtime + app | App only |
When Virtual DOM Makes Sense
- Highly dynamic UIs where everything changes constantly
- When developer experience outweighs performance
- When team already knows React/Vue
When Compile-Time Wins
- Performance-critical applications
- Bandwidth-constrained environments
- Simple to moderate interactivity
- When bundle size matters
Svelte Patterns
Component Design
<!-- Props with defaults -->
<script>
export let name = 'World';
export let count = 0;
</script>
<!-- Reactive declarations -->
<script>
let a = 1;
let b = 2;
$: sum = a + b; // Automatically updates
$: console.log(`Sum is ${sum}`); // Reactive statement
</script>
<!-- Direct DOM binding -->
<input bind:value={name}>
<input type="number" bind:value={count}>
Stores for Shared State
import { writable, derived } from 'svelte/store';
export const count = writable(0);
export const doubled = derived(count, $count => $count * 2);
<script>
import { count, doubled } from './stores.js';
</script>
<button on:click={() => $count++}>
{$count} × 2 = {$doubled}
</button>
Build Optimization Rules
1. Analyze Before Optimizing
npx rollup-plugin-visualizer
npx source-map-explorer bundle.js
2. Question Every Dependency
import { debounce } from 'lodash';
function debounce(fn, ms) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), ms);
};
}
3. Prefer Native Over Polyfill
When to Apply
| Scenario | Apply Harris Philosophy |
|---|
| New project, performance matters | Yes - consider Svelte |
| Bundle size optimization | Yes - tree-shaking analysis |
| Framework selection | Yes - evaluate compile-time options |
| Existing React codebase | Partially - bundling insights |
| Server-side rendering | Yes - SvelteKit considerations |
Source Material
- "Rethinking Reactivity" (talk)
- "The Truth About Virtual DOM" (blog)
- Svelte documentation and tutorials
- Rollup documentation
- Rich Harris on Twitter/talks