What Makes Minimact Different β
Minimact isn't just another React framework. It represents a fundamental paradigm shift in how we think about server-side rendering, state management, and client-server communication.
The Hydration Problem β
Traditional server-side rendering frameworks face a dilemma:
βββββββββββββββββββββββββββββββββββββββββββ
β Traditional SSR Flow (React) β
βββββββββββββββββββββββββββββββββββββββββββ€
β 1. Server renders HTML β
β 2. Client downloads 45 KB JS bundle β
β 3. Client "hydrates" - replays render β
β 4. Client reconciles every interaction β
β 5. VDOM diff on every state change β
βββββββββββββββββββββββββββββββββββββββββββProblems:
- β Large JavaScript bundles
- β Hydration waterfall delays interactivity
- β CPU overhead from client-side reconciliation
- β Wasted work - server already rendered the HTML!
The Minimact Solution β
Minimact flips the model entirely:
βββββββββββββββββββββββββββββββββββββββββββ
β Minimact Flow β
βββββββββββββββββββββββββββββββββββββββββββ€
β 1. Server renders HTML β
β 2. Client downloads 13.33 KB runtime β
β 3. Server pre-computes state changes β
β 4. Client caches predicted patches β
β 5. User interacts β instant update β
β (patch already in cache!) β
β 6. Server verifies in background β
βββββββββββββββββββββββββββββββββββββββββββBenefits:
- β 13.33 KB client vs 45 KB React (71% smaller)
- β No hydration required
- β Zero client-side reconciliation
- β 2-3ms perceived latency (vs 30-60ms traditional)
- β Instant interactions (cached patches)
Client-Side Stored Procedures β
The core insight: treat UI state transitions like database stored procedures.
Traditional Approach β
// Client downloads logic
// Client executes on every interaction
function handleClick() {
const newState = computeNextState(currentState);
reconcile(vdom, newState); // Expensive!
applyPatches(dom);
}Problem: Client does expensive work every single time.
Minimact Approach β
// Server pre-compiles state transitions
// Client executes pre-computed patches
function handleClick() {
const patch = cache.get(hintId); // Already cached!
applyPatch(dom, patch); // Instant!
}Insight: Just like stored procedures move computation to the database, Minimact moves UI computation to the server and caches the results.
Universal Template Prediction β
The breakthrough: one template handles infinite values.
Before Templates β
State 0 β Prediction: "Count: 0" (150 bytes)
State 1 β Prediction: "Count: 1" (150 bytes)
State 2 β Prediction: "Count: 2" (150 bytes)
...
State 1000 β 150KB of predictions!After Templates (Phase 1-9) β
Any state β Template: "Count: {0}" (200 bytes)
State 0 β Apply template β "Count: 0" β
State 1 β Apply template β "Count: 1" β
State 1000000 β Apply template β "Count: 1000000" β
Result: 750x memory reduction, 100% coverage after first interaction.
React Syntax, .NET Performance β
Write familiar React code:
import { useState } from 'minimact';
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}Babel transpiles to C#:
public class Counter : MinimactComponent
{
[UseState]
private int count = 0;
protected override VNode Render()
{
return new VElement("button",
new { onclick = nameof(Increment) },
new VText($"Count: {count}")
);
}
public void Increment()
{
count++;
TriggerRender();
}
}Rust engine predicts:
- Extracts template:
"Count: {0}" - Pre-computes patch for
count + 1 - Caches patch on client
- Client applies instantly on click
Hybrid State Management β
The best of both worlds:
function SearchBox() {
// Client-only - instant, no network
const [query, setQuery] = useClientState('');
// Server-managed - secure, persistent
const [results, setResults] = useState([]);
return (
<div>
{/* Instant typing feedback */}
<input
value={query}
onInput={e => setQuery(e.target.value)}
/>
{/* Server computation */}
<button onClick={() => setResults(search(query))}>
Search
</button>
{/* Server-rendered results */}
{results.map(r => <Result {...r} />)}
</div>
);
}Key insight: Not everything needs a server round-trip. Use the right tool for the job.
Zero Hydration β
Traditional frameworks ship the framework to the client:
React Client Bundle:
βββ React reconciliation engine
βββ VDOM implementation
βββ Component tree
βββ State management
βββ Event system
Total: 45 KB (gzipped)Minimact ships only what's needed:
Minimact Client Bundle:
βββ SignalM WebSocket client (or SignalR)
βββ DOM patcher
βββ Event delegation
βββ Patch cache
βββ State synchronization
Total: 13.33 KB (gzipped) - 71% smallerWith full SignalR: 25.03 KB (still 44% smaller than React)
Why? The server already has all the logic. Client just needs to:
- Send events to server
- Apply patches from server
- Cache predicted patches
TypeScript β C# Type Safety β
End-to-end type safety:
// TypeScript component
interface User {
name: string;
email: string;
}
export function UserProfile({ user }: { user: User }) {
return <div>{user.name}</div>;
}Babel infers C# types:
public class User
{
public string Name { get; set; }
public string Email { get; set; }
}
public class UserProfile : MinimactComponent<UserProfileProps>
{
public class UserProfileProps
{
public User User { get; set; }
}
// ...
}Result: Refactor-safe, autocomplete everywhere, catch errors at compile time.
Progressive Enhancement β
Works without JavaScript:
<!-- Server renders full HTML -->
<form method="POST" action="/search">
<input name="query" />
<button type="submit">Search</button>
</form>
<!-- JavaScript enhances with SignalR -->
<script>
// Intercepts form, uses SignalR instead
// Falls back to POST if JS disabled
</script>Philosophy: Start with solid HTML, enhance progressively.
Comparison to Alternatives β
vs Next.js/Remix (Client-Side React) β
| Aspect | Minimact | Next.js/Remix |
|---|---|---|
| Client bundle | 13.33 KB (71% smaller) | ~45 KB |
| Hydration | None | Required |
| Interaction latency | 2-3ms | 30-60ms |
| Server language | .NET | Node.js |
| Type safety | TSβC# | TS only |
When to use Minimact: Enterprise .NET apps, strict security requirements, minimal client footprint
When to use Next/Remix: Heavy client interactivity, existing Node.js infrastructure
vs Blazor Server (.NET SSR) β
| Aspect | Minimact | Blazor |
|---|---|---|
| Syntax | React JSX/TSX | Razor C# |
| Learning curve | Low (React) | Medium (Blazor) |
| Prediction | β Rust-powered | β None |
| Template system | β 98% memory reduction | β None |
| Hybrid state | β Built-in | β Manual |
When to use Minimact: React developers, predictive rendering needs, hybrid state
When to use Blazor: Pure .NET teams, existing Blazor experience
vs HTMX (Hypermedia) β
| Aspect | Minimact | HTMX |
|---|---|---|
| Paradigm | Component-based | Hypermedia |
| Bundle size | 13.33 KB | ~14 KB |
| Type safety | β TSβC# | β None |
| Prediction | β Intelligent | β None |
| Complexity | React components | HTML attributes |
When to use Minimact: Complex UIs, type safety, predictive rendering
When to use HTMX: Simple apps, hypermedia architecture, extreme simplicity
The Posthydrationist Philosophy β
The cactus doesn't hydrateβit stores.It doesn't reactβit anticipates.It doesn't reconcileβit persists.
Traditional frameworks are built on hydration - sending code to the client and reconstructing state.
Minimact is built on prediction - knowing what will happen before it does, and having the answer ready.
Like a cactus in the desert:
- Minimal - Only what's needed (~5KB)
- Resilient - Works without JavaScript
- Anticipatory - Pre-computed state changes
- Efficient - No wasted reconciliation
Summary: The Paradigm Shift β
Traditional SSR:
- Ship framework to client
- Hydrate on client
- Reconcile on every interaction
- Compute state changes in real-time
Minimact:
- Keep framework on server
- No hydration needed
- Pre-compute state changes
- Cache predictions on client
- Apply cached patches instantly
Result: Faster, smaller, more secure.
Next Steps β
- Predictive Rendering 101 - Deep dive into prediction
- DOM as Data Source - Extensions ecosystem
- Posthydrationist Manifesto - The philosophy
- Getting Started - Build your first app
