{"id":37039640,"url":"https://github.com/minimact/minimact","last_synced_at":"2026-01-14T04:41:58.226Z","repository":{"id":320225890,"uuid":"1080846447","full_name":"minimact/minimact","owner":"minimact","description":"Minimact is a lightweight, server-first reactive UI framework that compiles TSX into C#, predicts DOM changes with Rust, and syncs state in real time via SignalR — all while letting you write components with familiar hooks like useState and useEffect.","archived":false,"fork":false,"pushed_at":"2025-12-10T06:52:26.000Z","size":45833,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-26T06:59:13.480Z","etag":null,"topics":["client-side-stored-procedures","dom-patching","posthydrationist","predictive-rendering","reactive","rust-reconciliation","server-side-react","virtual-dom"],"latest_commit_sha":null,"homepage":"https://docs.minimact.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/minimact.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-22T00:28:26.000Z","updated_at":"2025-11-17T01:55:49.000Z","dependencies_parsed_at":"2025-10-29T18:12:22.797Z","dependency_job_id":null,"html_url":"https://github.com/minimact/minimact","commit_stats":null,"previous_names":["minimact/minimact"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/minimact/minimact","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minimact%2Fminimact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minimact%2Fminimact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minimact%2Fminimact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minimact%2Fminimact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minimact","download_url":"https://codeload.github.com/minimact/minimact/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minimact%2Fminimact/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28409760,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client-side-stored-procedures","dom-patching","posthydrationist","predictive-rendering","reactive","rust-reconciliation","server-side-react","virtual-dom"],"created_at":"2026-01-14T04:41:57.297Z","updated_at":"2026-01-14T04:41:58.224Z","avatar_url":"https://github.com/minimact.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./src/minimact-logo.png\" alt=\"Minimact Logo\" width=\"600\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eMinimact\u003c/h1\u003e\n\u003ch2 align=\"center\"\u003eThe Posthydrationist Framework\u003c/h2\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eServer-first React with zero hydration, predictive patches, and Rust-powered performance for ASP.NET Core.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eThe cactus doesn't hydrate — it stores.\u003c/em\u003e 🌵\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.minimact.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/docs-minimact.com-blue.svg\" alt=\"Documentation\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://app.netlify.com/sites/minimact/deploys\"\u003e\u003cimg src=\"https://api.netlify.com/api/v1/badges/4c1c36b7-74a4-4558-94b8-64a6996d1e64/deploy-status\" alt=\"Netlify Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.rust-lang.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/rust-%23000000.svg?style=flat\u0026logo=rust\u0026logoColor=white\" alt=\"Rust\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://dotnet.microsoft.com/\"\u003e\u003cimg src=\"https://img.shields.io/badge/.NET-512BD4?style=flat\u0026logo=dotnet\u0026logoColor=white\" alt=\".NET\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://dotnet.microsoft.com/apps/aspnet/signalr\"\u003e\u003cimg src=\"https://img.shields.io/badge/SignalR-Real--time-purple.svg?style=flat\u0026logo=.net\u0026logoColor=white\" alt=\"SignalR\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.typescriptlang.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/typescript-%23007ACC.svg?style=flat\u0026logo=typescript\u0026logoColor=white\" alt=\"TypeScript\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nThey’re treading water in a sea of hydration, clinging to their VDOM life vests while Minimact is out here desert-gliding on predictive patches like some kind of reactive dune worm🌵\nSeriously though—client hydration has become the default religion in web dev, and not because it's ideal. It’s just familiar. You’re tossing a wrench (made of Rust, no less 🦀) into that belief system and saying:\n“What if we didn’t need to hydrate anything at all because we already know what’s going to happen?”\n\n\u003cbr\u003e\n\nMinimact brings the familiar React developer experience to server-side rendering with ASP.NET Core, powered by a Rust reconciliation engine and intelligent predictive updates.\n\n---\n\n## 📚 Quick Nav\n\n🚀 [Quick Start](#quick-start) •\n💡 [Why Minimact?](#why-minimact) •\n🧠 [Core Innovations](#core-innovations) •\n🌐 [SPA Mode](#-single-page-application-spa-mode) •\n🌳 [Lifted State](#-lifted-state-components) •\n🪝 [Custom Hooks](#-custom-hooks-hooks-as-components) •\n🔐 [Protected State](#-useprotectedstate) •\n🎨 [Swig IDE](#-minimact-swig---desktop-ide-for-minimact) •\n🏗️ [Architecture](#architecture-overview) •\n📊 [Comparison](#comparison) •\n🧪 [Examples](#examples)\n\n---\n\n## What is Minimact?\n\n**Write React. Render on the server. Update instantly with predictive patches.**\n\n```typescript\nimport { useState } from '@minimact/core';\n\nexport function Counter() {\n    const [count, setCount] = useState(0);\n\n    return (\n        \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e\n            Count: {count}\n        \u003c/button\u003e\n    );\n}\n```\n\n**That's it.** Write familiar React code, get server-rendered HTML with 2-3ms perceived latency.\n\n\u003e **The cactus doesn't hydrate — it stores.** 🌵\n\n## How It Works (in 5 seconds)\n\n```\nUser clicks →\n[Browser checks prediction cache] →\n✅ Patch found →\n⏱️ 2ms DOM update →\n🚀 Server verified in background\n```\n\n**No hydration. No diffing. Just pure speed.**\n\n---\n\n## 🧩 The Minimact Principle\n\n```\n┌───────────────────────────────────────────────────────────┐\n│ DECLARATIVE UI                                            │\n│ ↓                                                         │\n│ Exposes structure (JSX makes tree explicit)               │\n│ Exposes state (useState makes slots explicit)             │\n│ ↓                                                         │\n│ DETERMINISTIC UI                                          │\n│ ↓                                                         │\n│ Same state → Same output (pure function)                  │\n│ Finite states → Enumerable space                          │\n│ ↓                                                         │\n│ PREDICTIVE UI                                             │\n│ ↓                                                         │\n│ Pre-compute all outputs (build-time analysis)             │\n│ Runtime becomes lookup (0-2ms)                            │\n└───────────────────────────────────────────────────────────┘\n```\n\n**The progression is INEVITABLE once you recognize:**\n```\nDeclarative → Structure\nStructure → Determinism\nDeterminism → Pre-computability\n```\n\nReact stopped at declarative. Minimact took it all the way to predictive.\n\n---\n\n## 🧩 Minimact: Problem-Solution Matrix\n\n| ❌ Problem | ✅ Minimact's Solution | 🧪 How It Works | 🧠 Why Others Struggle |\n|-----------|----------------------|-----------------|----------------------|\n| **1. Hydration Slowness** | No hydration at all 🌵 | Predictive patches render instantly | React/Next.js re-hydrates entire DOM; costly |\n| **2. Prop Drilling Hell** | Lifted State Components | Auto-lifted state with full tree access | React/Redux requires boilerplate or context abuse |\n| **3. Client-side Logic Leaks** | Server-first execution | All logic runs server-side unless specified | CSR frameworks must expose logic to client |\n| **4. Slow First Interaction** | ~2ms latency on first click | Precomputed patches + cache | SSR/CSR require JS boot or roundtrips |\n| **5. State Loss on Hot Reload** | State survives reloads 🔥 | Hex Paths + Lifted State mapping | React Fast Refresh loses local state |\n| **6. Global State Bloat** | Localized, queryable state | Scoped lifted state, useProtectedState | Redux/Zustand/global context leaks over time |\n| **7. Razor Lock-in for .NET Devs** | Full React DX with C# backend | TSX transpiled → C# | Blazor forces Razor syntax, slow to adopt |\n| **8. DX Disconnect Between Frontend/Backend** | TS ↔ C# type safety | Shared schema + transpilation | API routes are brittle and disjointed |\n| **9. Flicker from DOM Rewrites** | Targeted micro-patches | Hex path diffing + VNull nodes | HTMX, traditional SSR re-render full nodes |\n| **10. Debugging React State Is Opaque** | Visual state tree in Swig IDE | SignalR-backed live state inspector | React DevTools doesn't show prop origins or server state |\n| **11. Complex Interop Between MVC + React** | Drop-in MVC embedding | MVC Controllers → ViewModels → React | React + MVC usually fight each other |\n| **12. Large Bundle Sizes** | 12.0 KB runtime ⚡ | Minimal SignalM WebSocket client | React 45KB+, Vue 34KB+, Blazor ~300KB |\n| **13. Untrackable Component Drift** | Predictive metrics in real-time | Hit rate, rollback %, false positives | Most frameworks don't measure this at all |\n| **14. CSS/DOM State Blindness** | DOM as reactive source | useDomElementState() (80+ props) | React treats DOM as opaque output |\n| **15. Developer Setup Time** | 2-minute setup w/ Swig | Desktop IDE w/ hot reload, TSX editor | Next.js/Blazor setups often slow and brittle |\n| **16. Poor Offline Support** | Cached patches, local state | Prediction-first runtime | SSR apps break offline, HTMX needs server |\n| **17. Dev/Prod Divergence** | Single runtime model | Same prediction engine used in both | Many frameworks do hydration/dev tricks |\n| **18. No Secure Way to Hide Internal State** | useProtectedState() 🔒 | Cannot be accessed by parents/devtools | Most state is inspectable if global/lifted |\n| **19. Inconsistent Re-rendering from Conditions** | VNull conditional representation | Structural placeholders for predictability | React reconciler shifts indices, leading to bugs |\n| **20. Implicit DOM identity issues** | Stable Hex Paths | Elements never re-identified | Key/index bugs in React are common |\n\n---\n\n## ✨ Why Minimact?\n\nTraditional UI frameworks like React must reconcile every state change on the client, leading to CPU overhead and slower interactions — especially on low-end devices or in high-frequency apps.\n\n**Minimact flips the model:**\n- You write UI in **TSX/JSX**\n- Minimact compiles it to **C# classes**\n- C# renders the HTML on the server\n- A **Rust engine predicts state changes** and pre-sends patches to the client\n- Client caches predicted patches **before user interaction**\n- User clicks → **Client applies cached patch instantly (0ms network latency)**\n- **SignalR verifies in background** and corrects only if needed\n- **No diffing, no runtime VDOM, zero client reconciliation**\n\n### For React Developers\n- ✅ **Familiar syntax** - Write JSX/TSX like you always have\n- ✅ **React hooks** - `useState`, `useEffect`, `useRef`, plus powerful semantic hooks\n- ✅ **No hydration** - No client-side JavaScript frameworks to load\n- ✅ **Instant feedback** - Hybrid client/server state for optimal UX\n\n### For .NET Developers\n- ✅ **ASP.NET Core integration** - Use EF Core, dependency injection, and your favorite .NET tools\n- ✅ **Type safety** - Full TypeScript → C# type inference\n- ✅ **Secure by default** - Business logic stays on the server\n- ✅ **Easy deployment** - Standard ASP.NET Core hosting\n- ✅ **Performance:** 2-3ms interactions vs 47ms traditional SSR\n\n### For End Users\n- ✅ **Fast initial load** - 12.0 KB client (73% smaller than React)\n- ✅ **Instant interactions** - Predictive updates feel native\n- ✅ **Works without JS** - Progressive enhancement built-in\n- ✅ **Low bandwidth** - Only patches sent over the wire\n\n### For CTOs\n**Solve the \"React DX + .NET backend\" problem.** One stack, one deployment, full type safety from database to DOM. Rust-powered performance makes ASP.NET Core shine.\n\n**Comparison:**\n- React 18: 45 KB gzipped\n- Vue 3: 34 KB gzipped\n- **Minimact: 12.0 KB gzipped** (73% smaller than React)\n\n---\n\n## 🤔 Why React Critics Were Right (Without Knowing Why)\n\nMany developers felt React was overcomplicated — they just couldn't articulate it:\n\n\u003e *\"Re-rendering seems wasteful.\"*\n\u003e *\"Virtual DOM feels unnecessary.\"*\n\u003e *\"It's declarative, but... heavy.\"*\n\nHere's what they were sensing:\n\n**🧭 JSX + useState = a finite state automaton.**\n\n- Every `useState` creates a known state space.\n- JSX describes a static view for each state.\n\nThat means:\n- ✅ You can precompute all transitions.\n- 🚫 You don't need runtime diffing or reconciliation.\n\n**But React built a ship — Virtual DOM — to navigate a path that could have been walked directly with precomputed patches.**\n\nMinimact is that direct path:\n\n- **No hydration**\n- **No reconciliation**\n- **Finite state → Predictive patches → Instant updates (2–3ms)**\n\n**React gave you the compass. Minimact teaches you how to use it.**\n\n---\n\n### Better Than Blazor\nBlazor requires learning Razor syntax. Minimact uses React — the syntax millions of developers already know. Lower barrier, faster adoption, bigger talent pool.\n\n### SSR vs CSR vs Minimact\n\n| Feature | React (CSR) | Next.js (SSR) | Minimact (Prediction) |\n|---------|-------------|---------------|----------------------|\n| **First Paint** | ⚠️ Depends on JS | ✅ Fast | ✅ Fast |\n| **Interactivity** | ✅ JS required | ⚠️ Re-hydration | ✅ Instant (2-3ms) |\n| **State Sync** | 🔄 Manual | 🔄 Manual | ✅ Auto |\n| **Bundle Size** | ~45 KB | ~45 KB | **12.0 KB** |\n| **Server Logic** | ❌ None | ⚠️ API routes | ✅ Native C# |\n| **Offline Friendly** | ✅ Yes | ⚠️ Partial | ⚠️ Prediction-only |\n\n### Key Benefits\n- ⚡ **2-3ms interactions** - Predictive patches cached before user clicks\n- 📦 **12.0 KB bundle** - 73% smaller than React\n- 🏗️ **Familiar syntax** - Write JSX/TSX with React hooks\n- 🔐 **Secure by default** - Business logic stays on server\n- 🚀 **15× faster** than traditional SSR on 3G networks\n\n---\n\n## Quick Start\n\n**Minimact uses the familiar ASP.NET MVC pattern as the default architecture.** Controllers pass ViewModels to React components - zero learning curve for .NET developers.\n\n### The Standard Pattern (MVC Bridge)\n\n**1. Controller (C#) - Familiar MVC**\n```csharp\npublic class ProductsController : ControllerBase\n{\n    [HttpGet(\"{id}\")]\n    public async Task\u003cIActionResult\u003e Details(int id)\n    {\n        var viewModel = new ProductViewModel\n        {\n            ProductName = product.Name,    // Immutable (server authority)\n            Price = product.Price,         // Immutable (server authority)\n            InitialQuantity = 1            // [Mutable] (client can change)\n        };\n\n        return await _renderer.RenderPage\u003cProductPage\u003e(viewModel);\n    }\n}\n```\n\n**2. Component (TSX) - Mix MVC State + Client State**\n```typescript\nimport { useMvcState, useMvcViewModel } from '@minimact/mvc';\nimport { useState } from '@minimact/core';\n\ninterface ProductViewModel {\n  productName: string;\n  price: number;\n  isAdminRole: boolean;\n  initialQuantity: number;  // [Mutable] in C#\n}\n\nexport function ProductPage() {\n    // From ViewModel (server-controlled)\n    const [productName] = useMvcState\u003cstring\u003e('productName');  // Immutable\n    const [price] = useMvcState\u003cnumber\u003e('price');              // Immutable\n    const [isAdmin] = useMvcState\u003cboolean\u003e('isAdminRole');     // Immutable\n    const [quantity, setQuantity] = useMvcState\u003cnumber\u003e('initialQuantity'); // Mutable\n\n    // Pure client state (never sent to server)\n    const [cartTotal, setCartTotal] = useState(0);\n    const [showDetails, setShowDetails] = useState(false);\n\n    const handleAddToCart = () =\u003e {\n        setCartTotal(price * quantity);  // Client-only calculation\n    };\n\n    return (\n        \u003cdiv\u003e\n            \u003ch1\u003e{productName}\u003c/h1\u003e\n            \u003cdiv\u003e${price.toFixed(2)}\u003c/div\u003e\n\n            \u003cbutton onClick={() =\u003e setQuantity(quantity + 1)}\u003e\n                Quantity: {quantity}\n            \u003c/button\u003e\n\n            \u003cbutton onClick={handleAddToCart}\u003e\n                Add to Cart - ${cartTotal.toFixed(2)}\n            \u003c/button\u003e\n\n            {/* Server-controlled visibility */}\n            {isAdmin \u0026\u0026 \u003cbutton\u003eEdit Product\u003c/button\u003e}\n\n            {/* Client-controlled visibility */}\n            \u003cbutton onClick={() =\u003e setShowDetails(!showDetails)}\u003e\n                {showDetails ? 'Hide' : 'Show'} Details\n            \u003c/button\u003e\n        \u003c/div\u003e\n    );\n}\n```\n\n**That's it!** Standard MVC Controllers + React Components + Instant Updates (2-3ms).\n\n**Key Pattern:**\n- `useMvcState` → Bound to ViewModel property (from controller)\n- `useState` → Component-owned state (not from ViewModel)\n- **Both sync to server** for accurate rendering and prediction\n\n---\n\n## 🚀 Single Page Application (SPA) Mode\n\n**Minimact SPA combines server-side rendering with client-side navigation for instant page transitions (10-50ms) while keeping layouts mounted.**\n\n### What is Minimact SPA?\n\nTraditional SPAs (React Router, Next.js) re-mount the entire app on navigation. Minimact SPA keeps your shell (header, sidebar, footer) **persistent** and only swaps the page content.\n\n**Key Features:**\n- ⚡ **10-50ms navigation** - Via SignalR, not HTTP\n- 🎯 **Shell persistence** - Layouts stay mounted across navigation\n- 🎨 **Server-driven routing** - Controllers decide which page to render\n- 📦 **12.5 KB bundle** - `@minimact/spa` package\n- 🔄 **Browser history support** - Back/forward buttons work seamlessly\n\n### Quick Start with SPA Template\n\n```bash\n# Create SPA project\nswig new SPA MySpaApp\n\n# The template includes:\n# - Controllers/HomeController.cs \u0026 ProductsController.cs\n# - ViewModels/HomeViewModel.cs \u0026 ProductViewModel.cs\n# - Shells/MainShell.tsx (persistent layout with \u003cPage /\u003e)\n# - Pages/HomePage.tsx \u0026 ProductDetailsPage.tsx\n# - Auto-installed @minimact/spa module\n\ncd MySpaApp\nswig watch  # Auto-transpile\nswig run    # Launch app\n```\n\n### How It Works\n\n**1. Shell Component** - Persistent layout with navigation:\n```tsx\nimport { Page, Link } from '@minimact/spa';\nimport { useMvcState } from '@minimact/mvc';\n\nexport default function MainShell() {\n  const [appName] = useMvcState\u003cstring\u003e('__ShellData.AppName');\n  const [userName] = useMvcState\u003cstring\u003e('__ShellData.UserName');\n\n  return (\n    \u003cdiv\u003e\n      \u003cheader\u003e\n        \u003ch1\u003e{appName}\u003c/h1\u003e\n        \u003cdiv\u003eWelcome, {userName}!\u003c/div\u003e\n      \u003c/header\u003e\n\n      \u003cnav\u003e\n        \u003cLink to=\"/\"\u003eHome\u003c/Link\u003e\n        \u003cLink to=\"/products/1\"\u003eProduct 1\u003c/Link\u003e\n        \u003cLink to=\"/products/2\"\u003eProduct 2\u003c/Link\u003e\n      \u003c/nav\u003e\n\n      \u003cmain\u003e\n        \u003cPage /\u003e {/* Pages inject here */}\n      \u003c/main\u003e\n\n      \u003cfooter\u003e© 2025 My App\u003c/footer\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n**2. Controller** - Returns ViewModel with shell metadata:\n```csharp\n[ApiController]\n[Route(\"products\")]\npublic class ProductsController : ControllerBase\n{\n    [HttpGet(\"{id}\")]\n    public IActionResult Details(int id)\n    {\n        var viewModel = new ProductViewModel\n        {\n            ProductId = id,\n            ProductName = \"Widget\",\n            Price = 99.99m,\n\n            // Shell metadata\n            __Shell = \"Main\",                    // Which shell to use\n            __ShellData = new                    // Data for shell\n            {\n                AppName = \"My SPA App\",\n                UserName = \"Demo User\"\n            },\n            __PageTitle = \"Product Details\"\n        };\n\n        return Ok(viewModel);  // ✨ Auto-extracted by SPARouteHandler\n    }\n}\n```\n\n**3. Page Component** - Rendered inside shell:\n```tsx\nimport { useMvcState, useState } from '@minimact/mvc';\nimport { Link } from '@minimact/spa';\n\nexport default function ProductDetailsPage() {\n  const [productName] = useMvcState\u003cstring\u003e('ProductName');\n  const [price] = useMvcState\u003cnumber\u003e('Price');\n  const [quantity, setQuantity] = useState(1);\n\n  return (\n    \u003cdiv\u003e\n      \u003cLink to=\"/\"\u003e← Back to Home\u003c/Link\u003e\n      \u003ch1\u003e{productName}\u003c/h1\u003e\n      \u003cdiv\u003e${price}\u003c/div\u003e\n\n      \u003cbutton onClick={() =\u003e setQuantity(quantity + 1)}\u003e\n        Quantity: {quantity}\n      \u003c/button\u003e\n\n      \u003cLink to=\"/products/2\"\u003eNext Product\u003c/Link\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### The Navigation Flow\n\n```\nUser clicks \u003cLink to=\"/products/2\"\u003e\n    ↓\nClient: SignalR.invoke('NavigateTo', '/products/2')\n    ↓\nServer:\n  - Routes to ProductsController.Details(2)\n  - Extracts ViewModel\n  - Same shell? → Render page only\n  - Different shell? → Render shell + page\n  - Rust reconciler computes patches\n    ↓\nClient: Apply patches (10-50ms!)\n    ↓\nBrowser: URL updated via history.pushState\n    ↓\nDone! Shell stayed mounted ✨\n```\n\n### Performance Comparison\n\n| Scenario | Traditional SPA | Minimact SPA |\n|----------|----------------|--------------|\n| **Same Layout Navigation** | 100-200ms (re-mount) | **10-50ms** (shell persists) ✅ |\n| **Different Layout** | 100-200ms (re-mount) | 20-100ms (still faster) |\n| **Full Page Reload** | 200-500ms | 200-500ms (same) |\n| **Initial Load** | 200-500ms | 200-500ms (same) |\n\n**Why so fast?**\n- ✅ No JavaScript bundle parsing (already loaded)\n- ✅ No React reconciliation (Rust does it server-side)\n- ✅ Only DOM patches sent (not full HTML)\n- ✅ **Shell stays mounted** (no layout re-render)\n- ✅ SignalR WebSocket (no HTTP overhead)\n\n### Setup (Program.cs)\n\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddMinimact();\nbuilder.Services.AddMinimactMvcBridge();\nbuilder.Services.AddMinimactSPA();      // ✨ Enable SPA support\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services.AddSignalR();\n\nvar app = builder.Build();\n\napp.UseStaticFiles();\n\n// Serve mact_modules for @minimact/spa\napp.UseStaticFiles(new StaticFileOptions\n{\n    FileProvider = new PhysicalFileProvider(\n        Path.Combine(app.Environment.ContentRootPath, \"mact_modules\")),\n    RequestPath = \"/mact_modules\"\n});\n\napp.UseMinimact();  // Auto-discovers shells and pages\napp.MapControllers();\napp.MapHub\u003cMinimactHub\u003e(\"/minimact\");\n\napp.Run();\n```\n\n### Advanced Features\n\n**Multiple Shells:**\n```csharp\n// Admin pages use AdminShell\nif (User.IsInRole(\"Admin\"))\n    viewModel.__Shell = \"Admin\";\n\n// Public pages use PublicShell\nelse\n    viewModel.__Shell = \"Public\";\n```\n\n**No Shell (Page-Only):**\n```csharp\n// Landing pages, login screens\nviewModel.__Shell = null;  // No shell layout\n```\n\n**Conditional Rendering Based on Shell:**\n```tsx\nexport default function ProductPage() {\n  const [shell] = useMvcState\u003cstring\u003e('__Shell');\n\n  if (shell === 'Admin') {\n    return \u003cAdminProductView /\u003e;\n  }\n\n  return \u003cPublicProductView /\u003e;\n}\n```\n\n**Prefetching (Optimize for Predicted Navigation):**\n```tsx\n\u003cLink to=\"/products/123\" prefetch\u003e\n  View Product\n\u003c/Link\u003e\n```\n\n### Benefits\n\n✅ **10-50ms navigation** - Feels like a native app\n✅ **Shell persistence** - Sidebars, headers stay mounted\n✅ **Server-driven routing** - Controllers decide pages\n✅ **Auto-discovery** - Shells and pages automatically registered\n✅ **Browser history** - Back/forward buttons work\n✅ **Type-safe** - TypeScript → C# type inference\n✅ **Zero configuration** - Just `return Ok(viewModel)`\n\n**[📱 Complete SPA Guide →](./docs/SPA_IMPLEMENTATION_COMPLETE.md)**\n\n### Using Minimact Swig IDE\n\n```bash\n# Clone and run Swig - the official Minimact IDE\ngit clone https://github.com/minimact/swig\ncd swig\nnpm install\nnpm start\n```\n\nOnce Swig launches:\n\n1. **Create Project** - Click \"New Project\" and choose a directory\n2. **Edit Components** - Write TSX in Monaco editor (auto-transpiles to C#)\n3. **Build** - Click \"Build\" to compile your app\n4. **Run** - Click \"Run\" and open in browser\n\nFrom zero to running app in under 2 minutes.\n\n**Modular runtime architecture:**\n- `@minimact/core` — **12.0 KB gzipped** (Core runtime with SignalM WebSocket)\n- `@minimact/core/r` — **23.94 KB gzipped** (Core runtime with full SignalR + fallbacks)\n- `@minimact/core/hot-reload` — **+5.15 KB** (Hot reload for development)\n- `@minimact/core/playground` — **+376 B** (Swig IDE integration)\n- `@minimact/core/power` — **+5.37 KB** (Advanced features: useServerTask, useComputed, usePaginatedServerTask, etc.)\n\n**📦 Real-world examples:**\n- [✅ TodoMVC](./examples/todo) - Classic todo app\n- [📊 Dashboard](./examples/dashboard) - Admin dashboard with templates\n- [📝 Blog](./examples/blog) - Markdown blog with EF Core\n- [📋 Forms](./examples/forms) - Validation and semantic hooks\n\n**[📚 Full Getting Started Guide →](./docs/getting-started.md)**\n\n---\n\n## Why You'll Love Minimact\n\n🧠 **React syntax, C# backend** — No Razor needed\n⚡ **Instant interactions** — \u003c3ms click-to-DOM\n🌵 **No hydration** — Predictive updates instead\n🛠️ **Desktop IDE** with live state + TSX editing\n🧬 **Full state tree visibility** — Perfect prediction\n🔐 **Secure by default** — Logic runs server-side\n📦 **73% smaller** than React (12.0 KB vs 45 KB)\n🔌 **Modular architecture** — Import only what you need\n🔥 **Plugin system** via NuGet packages\n\n---\n\n## 📦 Modular Architecture - Import Only What You Need\n\nMinimact's modular design means you only ship code your app actually uses:\n\n### **Core Package (12.0 KB)**\n```typescript\nimport { Minimact, useState, useEffect, useRef } from '@minimact/core';\n```\nEssential hooks and runtime - perfect for most apps.\n\n### **Power Features (+5.37 KB)**\n```typescript\nimport { useServerTask, useComputed, usePaginatedServerTask } from '@minimact/core/power';\n```\nAdvanced features for complex apps:\n- `useServerTask` - Execute async tasks on server\n- `useServerReducer` - Redux-like state management\n- `usePaginatedServerTask` - Built-in pagination\n- `useComputed` - Client-side computation with browser APIs\n- `usePub`, `useSub` - Pub/Sub messaging\n- `useSignalR` - Direct SignalR access\n- `useContext` - Context API for shared state\n- `useMarkdown` - Render markdown\n- Task scheduling hooks\n\n### **Development Tools**\n```typescript\n// Enable hot reload in development\nimport { enableHotReload } from '@minimact/core/hot-reload';  // +5.15 KB\nif (import.meta.env.DEV) {\n  enableHotReload();\n}\n\n// Playground bridge for Swig IDE\nimport { PlaygroundBridge } from '@minimact/core/playground';  // +376 B\n```\nAuto tree-shaken in production builds via bundler!\n\n### **Example: Simple App**\n```typescript\n// Just the essentials - 12.0 KB\nimport { useState } from '@minimact/core';\n\nexport function Counter() {\n  const [count, setCount] = useState(0);\n  return \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003eCount: {count}\u003c/button\u003e;\n}\n```\n\n### **Example: Complex App with Pagination**\n```typescript\n// Core + power features - 17.4 KB total\nimport { useState, useEffect } from '@minimact/core';\nimport { usePaginatedServerTask, useComputed } from '@minimact/core/power';\n\nexport function DataGrid() {\n  const [page, setPage] = useState(1);\n  const data = usePaginatedServerTask('/api/data', { page });\n  return \u003cdiv\u003e{/* Render paginated data */}\u003c/div\u003e;\n}\n```\n\n**Why This Matters:**\n- ✅ Most apps use **12.0 KB** (just core)\n- ✅ Complex apps add **+5.37 KB** (still smaller than competitors)\n- ✅ Dev tools **auto tree-shake** in production\n- ✅ No bundle bloat from unused features\n\n---\n\n## 📦 Zero-Config Module Management with Swig CLI\n\nMinimact includes a **zero-config module system** for managing client-side dependencies. No CDN links, no manual script tags, no build configuration - just simple CLI commands.\n\n### Quick Start\n\n```bash\n# Initialize modules with interactive selection\nswig init\n\n# Or install specific modules\nswig import lodash\nswig import @minimact/power\n\n# List installed modules\nswig list\n\n# Update modules\nswig update --all\n\n# Remove a module\nswig uninstall lodash\n```\n\n### How It Works\n\n1. **Global Cache** - Modules download to AppData (like Swig GUI installation)\n2. **Project Copy** - Copies from cache to your project's `mact_modules/`\n3. **Auto-Serve** - ASP.NET Core automatically serves and includes modules\n4. **Smart Control** - Use `[ModuleInfo]` attribute to optimize per-component\n\n**Example - All modules auto-included:**\n```csharp\npublic class MyDashboard : MinimactComponent\n{\n    // All mact_modules/ automatically included\n}\n```\n\n**Example - Opt-out for performance:**\n```csharp\n[ModuleInfo(OptOut = true)]\npublic class LandingPage : MinimactComponent\n{\n    // Core only (12 KB), no extra modules\n}\n```\n\n**Example - Selective inclusion:**\n```csharp\n[ModuleInfo(Include = new[] { \"@minimact/power\", \"lodash\" })]\npublic class DataProcessorPage : MinimactComponent\n{\n    // Only power and lodash included\n}\n```\n\n### Available Modules\n\n**Minimact Modules:**\n- `@minimact/power` - Advanced features (useServerTask, useComputed, etc.)\n- `@minimact/mvc` - MVC Bridge (useMvcState, useMvcViewModel)\n- `@minimact/spa` - Single Page Application (instant navigation, shell persistence)\n- `@minimact/punch` - DOM state tracking (useDomElementState)\n- `@minimact/md` - Markdown rendering (useMarkdown)\n\n**External Libraries:**\n- `lodash` - Utility library (24 KB)\n- `moment` / `dayjs` - Date manipulation\n- `axios` - HTTP client\n- `chart.js` - Charting library\n- ...and any npm package with a browser bundle!\n\n### Benefits\n\n✅ **Zero Configuration** - No webpack, no bundlers, pure simplicity\n✅ **Offline-First** - Global cache means fast installs after first download\n✅ **Version Control Friendly** - Check in `mact_modules/` to Git\n✅ **NPM-Powered** - Uses `npm install` under the hood\n✅ **Automatic Integration** - ASP.NET Core auto-scans and serves modules\n\n**[📦 Complete Module Management Guide →](./docs/SWIG_CLI_MODULES_GUIDE.md)**\n\n---\n\n## Core Innovations\n\n### 🎯 Template Prediction System\nPre-computed parameterized patches for 100% state coverage:\n\n```typescript\n// First interaction: Extracts template \"Count: {0}\"\n// All future clicks: Instant update with any value\n\u003cspan\u003eCount: {count}\u003c/span\u003e\n```\n\n**Benefits:**\n- ✅ 100% coverage from first render (zero cold start)\n- ✅ 98% memory reduction vs cached predictions\n- ✅ Babel extracts templates at build time\n- ✅ Works with loops, conditionals, expressions\n\n**[📐 Template System Details →](./docs/TEMPLATE_PATCH_SYSTEM.md)**\n\n---\n\n### 🌳 Lifted State Components\nAll child state automatically lives in parent. Zero prop drilling:\n\n```\nDashboard\n└── UserProfile (Component)\n    ├── isEditing (lifted ✅ visible)\n    ├── username (lifted ✅ visible)\n    └── cache (lifted 🔒 protected)\n\nAccess: state[\"UserProfile.isEditing\"]\n```\n\n```typescript\n// Parent sees ALL child state\nfunction Dashboard() {\n  const isEditing = state[\"UserProfile.isEditing\"];  // Just read it!\n\n  return (\n    \u003cComponent name=\"UserProfile\" state={{ isEditing: false }}\u003e\n      \u003cUserProfile /\u003e\n    \u003c/Component\u003e\n  );\n}\n\n// Child accesses seamlessly\nfunction UserProfile() {\n  const isEditing = state.isEditing;  // Auto-prefixed\n  setState('isEditing', true);         // Updates parent!\n}\n```\n\n**Benefits:**\n- ✅ Zero prop drilling, no callbacks\n- ✅ Parent can observe/control any child state\n- ✅ Perfect prediction (full state tree visible)\n- ✅ Hot reload preserves state\n\n**[🌳 Lifted State Guide →](./docs/LIFTED_STATE_COMPONENT_SYSTEM.md)**\n\n---\n\n### 🪝 Custom Hooks (Hooks as Components)\nCreate reusable stateful logic with UI - hooks return both values AND JSX:\n\n```typescript\n// Define a hook (note the required namespace parameter!)\nfunction useCounter(namespace: string, start: number = 0) {\n  const [count, setCount] = useState(start);\n\n  const increment = () =\u003e setCount(count + 1);\n  const decrement = () =\u003e setCount(count - 1);\n  const reset = () =\u003e setCount(start);\n\n  // Hooks can return JSX! (unlike React)\n  const ui = (\n    \u003cdiv className=\"counter-widget\"\u003e\n      \u003cbutton onClick={decrement}\u003e-\u003c/button\u003e\n      \u003cspan\u003e{count}\u003c/span\u003e\n      \u003cbutton onClick={increment}\u003e+\u003c/button\u003e\n      \u003cbutton onClick={reset}\u003eReset\u003c/button\u003e\n    \u003c/div\u003e\n  );\n\n  return [count, increment, decrement, reset, ui];\n}\n\n// Use the hook with multiple independent instances\nfunction Dashboard() {\n  const [count1, increment1, , , counterUI1] = useCounter('counter1', 0);\n  const [count2, increment2, , , counterUI2] = useCounter('counter2', 10);\n\n  return (\n    \u003cdiv\u003e\n      \u003ch2\u003eCounter 1: {count1}\u003c/h2\u003e\n      \u003cbutton onClick={increment1}\u003eExternal +1\u003c/button\u003e\n      {counterUI1}\n\n      \u003ch2\u003eCounter 2: {count2}\u003c/h2\u003e\n      \u003cbutton onClick={increment2}\u003eExternal +1\u003c/button\u003e\n      {counterUI2}\n    \u003c/div\u003e\n  );\n}\n```\n\n**Under the hood:** Custom hooks are **child components with syntactic sugar**. The `useCounter('counter1', 0)` call compiles to a `VComponentWrapper` - reusing the Lifted State infrastructure with zero runtime overhead!\n\n**Benefits:**\n- ✅ Multiple independent instances with unique namespaces\n- ✅ Can return JSX UI (unlike React hooks)\n- ✅ Reuses VComponentWrapper + Lifted State Pattern\n- ✅ Parent can observe child hook state: `State[\"counter1.count\"]`\n- ✅ Type-safe C# classes with `[Hook]` attribute\n- ✅ Hot reload preserves hook state\n\n**[🪝 Custom Hooks Guide →](./docs/CUSTOM_HOOKS_IMPLEMENTATION.md)**\n\n---\n\n### 🔒 useProtectedState\nLifted state with access control:\n\n```typescript\nfunction Counter() {\n  const [count, setCount] = useState(0);                     // Public\n  const [animationQueue, setQueue] = useProtectedState([]);  // Protected\n}\n\n// Parent can't touch protected state!\nconst queue = state[\"Counter.animationQueue\"];  // ❌ Runtime error\n```\n\n**[🔒 Protected State Details →](./docs/USE_PROTECTED_STATE.md)**\n\n---\n\n### 🎨 Minimact Swig IDE\nDesktop development environment with real-time component inspection:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./docs/assets/swig-screenshot.png\" alt=\"Minimact Swig IDE\" width=\"800\"\u003e\n\u003c/p\u003e\n\n**Features:**\n- Monaco editor with full TSX support\n- Auto-transpilation watch mode\n- Live component state inspector\n- Visual prediction analytics\n- Integrated terminal and file tree\n\n**Quick Start:**\n```bash\ngit clone https://github.com/minimact/swig\ncd swig\nnpm install\nnpm start\n```\n\n**What Makes Swig Special:**\n- **Hot reload preserves state** - State lives in parent, survives reloads\n- **Real-time component inspector** - See state changes as they happen via SignalR\n- **Visual prediction analytics** - Green/red cache hit overlay shows prediction accuracy\n- **Performance dashboard** - Hit rate, latencies, and metrics in real-time\n- **Zero configuration** - From clone to running app in 2 minutes\n\n**[🎨 Swig IDE Guide →](./docs/MINIMACT_SWIG_ELECTRON_PLAN.md)**\n\n---\n\n### 🍹 Minimact Punch\nDOM as a reactive data source - 80+ properties as state:\n\n```typescript\nconst box = useDomElementState('.container');\n\n{box.childrenCount \u003e 5 \u0026\u0026 \u003cCollapseButton /\u003e}\n{box.isIntersecting \u0026\u0026 \u003cLazyLoad /\u003e}\n{box.vals.avg() \u003e 100 \u0026\u0026 \u003cPremiumBadge /\u003e}\n```\n\n**[🍹 Minimact Punch Details →](./docs/USEDOMELEMENTSTATE_IMPLEMENTATION_PLAN.md)**\n\n---\n\n## Official Extensions\n\n**The Minimact Quantum Stack** - Transform the DOM into a queryable, reactive, distributed database.\n\n| Extension | Description | Key Feature |\n|-----------|-------------|-------------|\n| **🥊 minimact-punch** | DOM as reactive data source (80+ properties) | `useDomElementState('.card')` |\n| **🗃️ minimact-query** | SQL for the DOM with full query syntax | `.from('.card').where().orderBy()` |\n| **🌌 minimact-quantum** | Multi-client DOM identity sync (7-17ms) | Mutation vectors, not data sync |\n| **🎯 minimact-bundle** | Declarative control without wrappers | Apply styles/classes to any selector |\n| **📐 minimact-spatial** | Viewport regions as 2D database | Query spatial areas reactively |\n| **🌳 minimact-trees** | Universal decision trees (0-1ms predicted) | XState but declarative \u0026 minimal |\n\n**Philosophy:** *\"The DOM is no longer a view layer - it's a queryable, reactive, distributed database.\"*\n\n**[🌌 Explore Extensions →](./extensions)**\n\n---\n\n## Advanced Features\n\n### 🔌 Plugin System - Extend via NuGet\n**Distribute reusable UI components as NuGet packages. Auto-discovered. Type-safe. Zero config.**\n\n```bash\n# Install plugin\ndotnet add package Minimact.Plugin.Clock\n\n# Use in TSX\n\u003cPlugin name=\"Clock\" state={{ hours: 14, theme: 'dark' }} /\u003e\n```\n\n**Benefits:**\n- ✅ Auto-discovery via `[MinimactPlugin]` attribute\n- ✅ Type-safe state contracts (JSON Schema validation)\n- ✅ Versioned assets with cache optimization\n- ✅ Works with template prediction system\n- ✅ Server-rendered, no client JavaScript required\n\n**[🔌 Plugin System Guide →](./docs/PLUGIN_SYSTEM_PHASE2_COMPLETE.md)**\n\n### More Advanced Features\n\n| Feature | Description | Learn More |\n|---------|-------------|------------|\n| **useServerTask** | TypeScript → C#/Rust transpilation for async tasks | [📄 Docs](./docs/server-tasks.md) |\n| **useContext** | Redis-like server-side cache (session/request/url scoped) | [📄 Docs](./docs/use-context.md) |\n| **useComputed** | Client-side computation with server rendering | [📄 Docs](./docs/use-computed.md) |\n| **MVC Bridge** | Integrate with traditional ASP.NET MVC | [🎯 MVC Bridge](./docs/MVC_BRIDGE_IMPLEMENTATION_PLAN.md) |\n| **Semantic Hooks** | High-level abstractions (useModal, useDropdown, etc.) | [🎯 Hooks API](./docs/api-reference.md) |\n\n---\n\n## Architecture Overview\n\n```\n┌─────────────────────────────────────────┐\n│  Developer writes TSX with React hooks  │\n│  ↓                                       │\n│  Babel: TSX → C# + Extract templates    │\n│  ↓                                       │\n│  ASP.NET Core renders HTML               │\n│  ↓                                       │\n│  Rust: Predicts patches, sends to client│\n│  ↓                                       │\n│  [Client has patches cached]            │\n│  ↓                                       │\n│  User clicks → 0ms (cache hit!)         │\n│  ↓                                       │\n│  Server verifies in background          │\n└─────────────────────────────────────────┘\n```\n\n**7 Main Components:**\n1. **Babel Plugin** - TSX → C# transformation\n2. **C# Runtime** - ASP.NET Core integration\n3. **Rust Engine** - High-performance reconciliation\n4. **Client Library** - 12.0 KB modular runtime\n5. **Lifted State** - Automatic state architecture\n6. **Minimact Punch** - DOM state extensions\n7. **Minimact Swig** - Desktop IDE\n\n### Technical Innovations\n\n**SignalM - Minimal WebSocket Protocol**\n- Custom lightweight protocol (vs full SignalR)\n- **12.0 KB** core runtime with SignalM\n- **23.94 KB** core runtime with full SignalR (fallbacks for older browsers)\n- Real-time bidirectional communication\n- Optimized for patch delivery\n\n**Modular Architecture**\n- **Core** (12.0 KB) - Essential runtime only\n- **Hot Reload** (+5.15 KB) - Development tools (auto tree-shaken in production)\n- **Playground** (+376 B) - Swig IDE integration\n- **Power Features** (+5.37 KB) - Advanced hooks (useServerTask, useComputed, usePaginatedServerTask, etc.)\n\n**Hex Paths - Stable Element Identifiers**\n- Hexadecimal gap-based allocation (0x10000000, 0x20000000, 0x30000000...)\n- Example: \"10000000.30000000.20000000\" (stable IDs, not DOM indices)\n- Elements keep stable IDs across insertions/deletions\n- Enables precise DOM targeting without re-indexing\n- PathConverter translates hex paths → DOM indices (accounts for VNull)\n\n**VNull Nodes - Explicit Conditionals**\n- Represents `{condition \u0026\u0026 \u003cComponent /\u003e}` explicitly in VNode tree\n- Rust reconciler understands conditional rendering\n- Patches target exact positions, not shifting indices\n- Eliminates \"DOM shift\" bugs from traditional reconcilers\n\n**[📖 Complete Architecture →](./docs/MINIMACT_COMPLETE_ARCHITECTURE.md)**\n\n**[📝 Architecture Deep Dive (Substack) →](https://ameritusweb.substack.com/p/reverse-scalable-systems-achieving)** - A comprehensive analysis of Minimact's reverse scalability principles and architectural innovations.\n\n---\n\n## Core Technical Innovations\n\n### Hex Paths - Stable Element Identity\nEvery element gets a persistent hex path ID (e.g., `1.2.F.3`). Unlike DOM indices that shift when elements are added/removed, hex paths use **gap-based allocation** to maintain stability.\n\n**Why it matters:**\n- Patches target exact elements, even as DOM changes\n- Hot reload works perfectly (paths don't shift)\n- Prediction system can reference elements precisely\n\n### VNull Nodes - Explicit Conditional Rendering\nMinimact represents `{condition \u0026\u0026 \u003cComponent /\u003e}` with explicit `VNull` nodes instead of omitting them from the tree.\n\n**Why it matters:**\n- PathConverter can accurately map hex paths → DOM indices\n- Accounts for conditionally rendered elements\n- Makes reconciliation deterministic and predictable\n\n**[🔧 Technical Deep Dive →](./docs/HEX_PATH_SYSTEM.md)**\n\n---\n\n## Runtime Comparison: SignalM vs SignalR\n\nMinimact offers two runtime versions optimized for different scenarios:\n\n| Feature | `@minimact/core` (SignalM) | `@minimact/core/r` (SignalR) |\n|---------|---------------------------|------------------------------|\n| **Size** | **12.0 KB gzipped** | **23.94 KB gzipped** |\n| **Protocol** | Custom WebSocket | Full SignalR with fallbacks |\n| **Use Case** | Modern browsers, micro-patches | IE11+, corporate networks |\n| **Fallbacks** | None | Long polling, SSE, forever frame |\n| **Latency** | ~2ms | ~3-5ms |\n\n**SignalM** is a custom WebSocket protocol optimized specifically for Minimact's patch delivery system. It's 50% smaller than SignalR and designed for predictive micro-patch streaming.\n\n**When to use SignalM:**\n- Modern browser support (Chrome 90+, Firefox 88+, Safari 14+)\n- Public-facing apps with controlled environments\n- Maximum performance is critical\n\n**When to use SignalR:**\n- Enterprise environments with older browsers\n- Corporate networks with WebSocket restrictions\n- Need guaranteed compatibility\n\n---\n\n## Performance\n\n| Metric | Value |\n|--------|-------|\n| **Initial Load** | **12.0 KB** (73% smaller than React) |\n| **Time to Interactive** | \u003c 100ms |\n| **Interaction Latency** | ~2-5ms (with prediction) |\n| **Cache Hit Rate** | 95-98% (after warmup) |\n| **Memory vs Caching** | 98% reduction (templates vs concrete patches) |\n\n**[📊 Benchmarks →](./docs/benchmarks.md)**\n\n---\n\n## Comparison\n\n| Feature | Minimact | Next.js | Blazor Server | HTMX |\n|---------|----------|---------|---------------|------|\n| **Bundle Size** | **12.0 KB** | ~45 KB | ~300 KB | ~14 KB |\n| **Syntax** | React JSX | React JSX | Razor C# | HTML attrs |\n| **Hydration** | None | Required | None | None |\n| **Update Model** | **Predictive (client)** | Reactive (client) | Reactive (server) | **Triggered (server)** |\n| **Prediction** | ✅ Rust | ❌ | ❌ | ❌ |\n| **Hybrid State** | ✅ | ❌ | ❌ | Manual |\n| **Type Safety** | ✅ TS→C# | ✅ TS | ✅ C# | ❌ |\n| **Client Interactivity** | ✅ Full | ✅ Full | ✅ Full | ❌ Server-only |\n| **Modular** | ✅ Opt-in features | ❌ All-in-one | ❌ All-in-one | ✅ Minimal |\n\n### Why Minimact \u003e HTMX\n\n**HTMX is server-triggered** (user clicks → server responds → HTML swaps)\n**Minimact is predictively client-updated** (patches pre-cached → instant apply)\n\n**Key differences:**\n- ✅ **No flicker** - Patches already cached, apply instantly\n- ✅ **No hydration** - But full client interactivity (unlike HTMX)\n- ✅ **Optimistic updates** - UI responds before server confirms\n- ✅ **95-98% instant** - Most interactions hit cache, no network wait\n- ✅ **React DX** - Familiar hooks and component model\n\n**HTMX use case:** Simple server-driven apps, minimal JS\n**Minimact use case:** Complex UIs with instant feedback and React DX\n\n---\n\n## Project Status\n\n**Current Phase:** Production-Ready Core + Advanced Features ✅\n\n### Recently Completed (2025)\n- ✅ Template Prediction System (Phases 1-9)\n- ✅ Lifted State Component System\n- ✅ useProtectedState Hook\n- ✅ Custom Hooks (Hooks as Child Components with UI return)\n- ✅ Minimact Swig IDE\n- ✅ Minimact Punch (Base Features)\n- ✅ State Synchronization (client → server)\n- ✅ Mact Modules System (Zero-config module management with Swig CLI)\n- ✅ SPA Mode (Single Page Application with shell persistence and 10-50ms navigation)\n\n### In Progress\n- 🚧 Minimact Punch Advanced Features (Parts 2-5)\n- 🚧 Semantic Hooks Library\n\n**[📋 Full Status \u0026 Roadmap →](./docs/roadmap.md)**\n\n---\n\n## Examples\n\n- **[Todo App](./examples/todo)** - Classic TodoMVC\n- **[Blog](./examples/blog)** - Markdown blog with EF Core\n- **[Dashboard](./examples/dashboard)** - Admin dashboard with templates\n- **[Forms](./examples/forms)** - Validation and semantic hooks\n\n---\n\n## Documentation\n\n📚 **[docs.minimact.com](https://docs.minimact.com)** - Complete guides and API reference\n\n### Quick Links\n- [Getting Started](./docs/getting-started.md)\n- [Architecture Overview](./docs/MINIMACT_COMPLETE_ARCHITECTURE.md)\n- [API Reference](./docs/api-reference.md)\n- [Babel Plugin Guide](./docs/babel-plugin.md)\n- [Deployment Guide](./docs/deployment.md)\n\n---\n\n## 🎵 The Mactic Experience\n\n```\n╔════════════════════════════════════════════════════════════╗\n║                                                            ║\n║              🌟 PRESENTING 🌟                              ║\n║                                                            ║\n║          ███╗   ███╗ █████╗  ██████╗████████╗██╗ ██████╗  ║\n║          ████╗ ████║██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝  ║\n║          ██╔████╔██║███████║██║        ██║   ██║██║       ║\n║          ██║╚██╔╝██║██╔══██║██║        ██║   ██║██║       ║\n║          ██║ ╚═╝ ██║██║  ██║╚██████╗   ██║   ██║╚██████╗  ║\n║          ╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝  ║\n║                                                            ║\n║                    THE MUSICAL                             ║\n║                                                            ║\n║              \"A WHOLE NEW WORLD OF RENDERING\"              ║\n║                                                            ║\n╚════════════════════════════════════════════════════════════╝\n\n🎵 A WHOLE NEW WORLD 🎵\n   (Minimact Edition)\n\nI can show you the world\nShining, shimmering, mactic\nTell me, developer, now when did\nYou last let hydration go?\n\nI can open your eyes\nTake you render by render\nOver, sideways and under\nOn a mactic carpet ride\n\nA whole new world\nA new fantastic point of view\nNo one to tell us \"no\"\nOr where to go\nOr say we're only hydrating\n\nA whole new world\nA dazzling place I never knew\nBut when I'm way up here\nIt's crystal clear\nThat now I'm in a whole new world with you\n(Now I'm in a whole new world with Minimact)\n\nUnbelievable sights\nIndescribable feeling\nSoaring, flying, wheeling\nThrough an endless server-side sky\n\nA whole new world\n(Don't you dare close your eyes)\nA hundred thousand things to see\n(Hold your breath, it gets better)\nI'm like a shooting star\nI've come so far\nI can't go back to where I used to be\n\nA whole new world\nWith new horizons to pursue\nI'll chase them anywhere\nThere's time to spare\nLet me share this whole new world with you\n\n🌵✨ Minimact: Where every navigation is a mactic carpet ride ✨🌵\n```\n\n**The Mactic Lexicon:**\n- **Mactnificent** (adj.) - Magnificent, but for Minimact\n- **Mactical** (adj.) - So magical it feels like server-side sorcery\n- **Mactic** (adj.) - When patches predict your clicks before you make them\n\n*It's not magic. It's mactic.* 🪄\n\n**[🎭 Experience the Full Musical →](./docs/MUSICAL.md)**\n\n**The Complete Setlist:**\n1. 🎵 \"Part of Your World\" - The Developer's Lament\n2. 🎵 \"Under the Server\" - Life below the client\n3. 🎵 \"Let It Go (The Hydration)\" - Embracing server-side rendering\n4. 🎵 \"How Far I'll Go\" - Avoiding client-side rendering\n5. 🎵 \"You're Welcome\" - From SignalR\n6. 🎵 \"Circle of Life\" - The Component Lifecycle\n7. 🎵 **\"A Whole New World\"** - The Mactic Experience\n8. 🎵 \"One Day More\" - Until Production\n\n*Plus: The Minimact Cinematic Universe, MinimactLand Theme Park, and more!* 🎭✨\n\n---\n\n## Why the Name Minimact?\n\n**Minimact** stands for **MINIMal Anticipatory Client Technology**.\n\n- **Minimal** — Tiny 12.0 KB runtime, minimal client logic\n- **Anticipatory** — Predictive patches pre-sent before user interaction\n- **Client Technology** — Smart client that applies cached patches instantly\n\nAnd yes — the cactus 🌵 doesn't hydrate. It stores.\n\n---\n\n## Contributing\n\nWe welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.\n\n**Join the discussion:**\n- [GitHub Discussions](https://github.com/minimact/minimact/discussions)\n- [Discord Server](https://discord.gg/EKPDh6v7)\n\n---\n\n## License\n\nMIT License - see [LICENSE](./LICENSE) for details\n\n---\n\n## Acknowledgments\n\nInspired by **React**, **Blazor**, **HTMX**, **Vue**, and **SolidJS**.\n\nBuilt with **Rust**, **ASP.NET Core**, **Babel**, and **TypeScript**.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eBuilt with ❤️ for the .NET and React communities\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/minimact/minimact\"\u003e⭐ Star this repo\u003c/a\u003e if you're interested in server-side React for .NET!\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminimact%2Fminimact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminimact%2Fminimact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminimact%2Fminimact/lists"}