rip-lang 3.10.15 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +2 -2
- package/docs/RIP-INTERNALS.md +1 -1
- package/docs/RIP-LANG.md +1 -1
- package/docs/RIP-TYPES.md +1 -1
- package/docs/WEB-FRAMEWORKS.md +486 -0
- package/docs/WEB-ROADMAP.md +126 -0
- package/docs/WEB-STYLING.md +701 -0
- package/docs/charts.html +141 -129
- package/docs/dist/{rip-ui.min.js → rip.min.js} +118 -116
- package/docs/dist/rip.min.js.br +0 -0
- package/docs/evidence.html +1228 -0
- package/docs/example/index.html +1 -3
- package/docs/index.html +6 -2
- package/docs/results/index.html +1 -1
- package/docs/sierpinski.html +1 -1
- package/package.json +5 -4
- package/src/app.rip +1002 -0
- package/src/browser.js +9 -12
- package/src/compiler.js +12 -2
- package/src/components.js +40 -1
- package/src/types.js +2 -2
- package/docs/dist/rip-ui.min.js.br +0 -0
- package/docs/dist/rip.browser.min.js +0 -521
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/src/tags.js +0 -62
- /package/docs/{rip-1280w.png → assets/rip-1280w.png} +0 -0
- /package/docs/{rip-512b.png → assets/rip-512b.png} +0 -0
- /package/docs/{rip-fav.svg → assets/rip-fav.svg} +0 -0
- /package/docs/{rip.png → assets/rip.png} +0 -0
- /package/docs/{rip.svg → assets/rip.svg} +0 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="docs/rip-1280w.png" alt="Rip Logo" width="400">
|
|
2
|
+
<img src="docs/assets/rip-1280w.png" alt="Rip Logo" width="400">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Rip</h1>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.
|
|
12
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.12.0-blue.svg" alt="Version"></a>
|
|
13
13
|
<a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
|
|
14
14
|
<a href="#"><img src="https://img.shields.io/badge/tests-1%2C243%2F1%2C243-brightgreen.svg" alt="Tests"></a>
|
|
15
15
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
package/docs/RIP-INTERNALS.md
CHANGED
package/docs/RIP-LANG.md
CHANGED
package/docs/RIP-TYPES.md
CHANGED
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
# Web Framework Landscape: 2025–2026
|
|
2
|
+
|
|
3
|
+
> A structured comparison for evaluating the positioning of Rip UI against the
|
|
4
|
+
> five dominant JavaScript UI frameworks. Data gathered February 2026.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Summary Matrix
|
|
9
|
+
|
|
10
|
+
| Dimension | React 19 | Solid.js 1.9 | Svelte 5 | Vue 3.5 | Angular 19–20 |
|
|
11
|
+
|--------------------------|---------------------------|---------------------------|-----------------------------|---------------------------|----------------------------|
|
|
12
|
+
| **Reactive model** | VDOM + compiler hints | Signals (fine-grained) | Compiler + signals (runes) | Proxy-based reactivity | Signals + zone.js (legacy) |
|
|
13
|
+
| **Runtime size (gzip)** | ~45 KB | ~7 KB | ~2–18 KB (scales w/ usage) | ~27–34 KB | ~50–65 KB (130 KB+ fresh) |
|
|
14
|
+
| **Build step** | Required (Babel/SWC+) | Required (Vite/Rollup) | Required (Svelte compiler) | Required (Vite) | Required (Angular CLI) |
|
|
15
|
+
| **Compiler** | React Compiler (opt-in) | Compile-time transforms | Core design (deep compiler) | Vapor mode (in progress) | AOT template compiler |
|
|
16
|
+
| **SSR strategy** | RSC + streaming | SolidStart (streaming) | SvelteKit (streaming) | Nuxt 3 (streaming) | Angular SSR + incremental |
|
|
17
|
+
| **Hydration** | Full (selective w/ RSC) | Streaming progressive | Progressive (SvelteKit) | Lazy hydration (3.5) | Incremental (on-demand) |
|
|
18
|
+
| **Component model** | Functions + hooks | Functions + signals | `.svelte` files + runes | SFC (script/template) | Classes → standalone fns |
|
|
19
|
+
| **State management** | External (Zustand, etc.) | Built-in (signals/stores) | Built-in (runes) | Built-in (ref/reactive) | Built-in (signals) + RxJS |
|
|
20
|
+
| **Maturity / ecosystem** | Dominant (60% job market) | Niche (~1.2% adoption) | Growing (loved by devs) | Strong (esp. APAC/EU) | Enterprise standard |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 1. React 19+
|
|
25
|
+
|
|
26
|
+
### Core Reactive Model
|
|
27
|
+
**Virtual DOM with compiler-assisted optimization.** React still diffs a virtual
|
|
28
|
+
tree against the real DOM, but the new React Compiler (formerly React Forget)
|
|
29
|
+
automatically inserts memoization, eliminating most manual `useMemo`/`useCallback`.
|
|
30
|
+
Components re-execute on every state change — the VDOM diffing algorithm then
|
|
31
|
+
determines what DOM mutations to apply.
|
|
32
|
+
|
|
33
|
+
### Runtime Size
|
|
34
|
+
- **~45 KB** min+gzip for `react` + `react-dom`
|
|
35
|
+
- Server Components reduce *shipped* JS by keeping components server-side (zero
|
|
36
|
+
client JS for those components), but the React runtime itself is unchanged
|
|
37
|
+
- Real-world production apps with Server Components: ~156 KB total JS (vs. heavier
|
|
38
|
+
without RSC)
|
|
39
|
+
|
|
40
|
+
### Build Step
|
|
41
|
+
Required. Babel or SWC for JSX transforms, plus a bundler (Webpack, Vite, Turbopack).
|
|
42
|
+
React Compiler is an additional Babel plugin. Next.js/Remix abstract most of this.
|
|
43
|
+
|
|
44
|
+
### Developer Experience
|
|
45
|
+
- **Strengths:** Massive ecosystem (50,000+ npm packages), dominant job market (~60%
|
|
46
|
+
of frontend positions), excellent tooling (React DevTools, extensive docs), Server
|
|
47
|
+
Components reduce full-stack data-fetching boilerplate
|
|
48
|
+
- **React Compiler:** Eliminates memoization ceremony — one project removed 2,300
|
|
49
|
+
lines of `useMemo`/`useCallback` after migration
|
|
50
|
+
|
|
51
|
+
### Known Pain Points
|
|
52
|
+
- **`useEffect` remains the #1 footgun:** Dependency array confusion, accidental
|
|
53
|
+
infinite loops, race conditions, memory leaks. Developers consistently misuse it
|
|
54
|
+
for data fetching, subscription management, and lifecycle events
|
|
55
|
+
- **Mental model complexity:** Rules of hooks (no conditionals, no loops), closure
|
|
56
|
+
stale-state bugs, the server/client component boundary adds another dimension of
|
|
57
|
+
mental overhead (`'use client'` directives, RSC payload format)
|
|
58
|
+
- **Bundle size:** Even with RSC, the base runtime is the largest among non-Angular
|
|
59
|
+
frameworks. Tree-shaking doesn't reduce React's core
|
|
60
|
+
- **Decision paralysis:** No canonical state management, routing, or data fetching —
|
|
61
|
+
developers must evaluate Zustand vs. Jotai vs. Redux vs. Recoil vs. signals
|
|
62
|
+
libraries vs. context, etc.
|
|
63
|
+
|
|
64
|
+
### Component Composition
|
|
65
|
+
Functions returning JSX. Server Components (default) render on server, Client
|
|
66
|
+
Components (opt-in via `'use client'`) render on client. Props flow downward; state
|
|
67
|
+
is lifted or managed externally. Context API for dependency injection.
|
|
68
|
+
|
|
69
|
+
### State Management
|
|
70
|
+
No built-in solution beyond `useState`/`useReducer`. Ecosystem solutions dominate:
|
|
71
|
+
Zustand, Jotai, Redux Toolkit, Recoil. React 19 adds `useActionState` and
|
|
72
|
+
`useOptimistic` for form/mutation state.
|
|
73
|
+
|
|
74
|
+
### SSR / Hydration
|
|
75
|
+
- **React Server Components (RSC):** Components render on the server, producing a
|
|
76
|
+
compact binary RSC Payload. Client components receive serialized props and hydrate.
|
|
77
|
+
Server components ship zero JS to clients.
|
|
78
|
+
- **Streaming SSR:** HTML streams to the client progressively via `renderToPipeableStream`
|
|
79
|
+
- **Selective hydration:** Suspense boundaries allow React to hydrate high-priority
|
|
80
|
+
components first
|
|
81
|
+
- **Performance:** Initial page loads improve ~38% with RSC; e-commerce cases report
|
|
82
|
+
47% load time reduction
|
|
83
|
+
- **Limitation:** RSC is effectively a Next.js/framework feature — raw React doesn't
|
|
84
|
+
provide SSR infrastructure
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 2. Solid.js 1.9 (2.0 Experimental)
|
|
89
|
+
|
|
90
|
+
### Core Reactive Model
|
|
91
|
+
**True fine-grained reactivity via signals.** Components execute once — only signal
|
|
92
|
+
subscriptions trigger targeted DOM updates. No virtual DOM. No diffing. No
|
|
93
|
+
re-rendering of component functions. Signal reads automatically create subscriptions;
|
|
94
|
+
signal writes trigger only the exact DOM nodes that depend on them.
|
|
95
|
+
|
|
96
|
+
### Runtime Size
|
|
97
|
+
- **~7 KB** min+gzip (compiler + minimal runtime)
|
|
98
|
+
- 3x smaller than React's initial bundle
|
|
99
|
+
- Near-vanilla-JS benchmark performance: scores **1.07** (vs. 1.00 for raw JS, vs.
|
|
100
|
+
React's **1.71** — lower is better)
|
|
101
|
+
|
|
102
|
+
### Build Step
|
|
103
|
+
Required. Vite with `vite-plugin-solid` for JSX compilation. The compiler transforms
|
|
104
|
+
JSX into fine-grained reactive DOM operations (not virtual DOM creation).
|
|
105
|
+
|
|
106
|
+
### Developer Experience
|
|
107
|
+
- **Strengths:** JSX syntax familiar to React devs, signals are simple
|
|
108
|
+
(`createSignal`, `createEffect`, `createMemo`), no rules-of-hooks constraints,
|
|
109
|
+
components run once (easier mental model for when code executes), extreme
|
|
110
|
+
performance out of the box
|
|
111
|
+
- **SolidStart 1.0:** Full-stack meta-framework with SSR, SSG, CSR, file-based
|
|
112
|
+
routing, server functions — comparable to Next.js but for Solid
|
|
113
|
+
|
|
114
|
+
### Known Pain Points
|
|
115
|
+
- **Tiny ecosystem:** ~1.2% adoption (declining from 1.36%), disappeared from 2025
|
|
116
|
+
Stack Overflow survey. Few UI component libraries, limited third-party integrations
|
|
117
|
+
- **Bus factor:** 1,592 of 1,592 commits from Ryan Carniato; second contributor has
|
|
118
|
+
33. Entire project depends on one person
|
|
119
|
+
- **Code quality concerns:** 204 `@ts-expect-error`/`@ts-ignore` annotations,
|
|
120
|
+
`type TODO = any` at the core of the signal system (persisted 4+ years)
|
|
121
|
+
- **Hot reload instability:** Regular crashes requiring dev server restarts
|
|
122
|
+
- **Job market:** Negligible hiring demand
|
|
123
|
+
- **Solid 2.0 is experimental:** Breaking changes to reactivity, SSR, and hydration
|
|
124
|
+
are in progress. No release date. SolidStart 2.0 (Vite-native) is also being
|
|
125
|
+
rebuilt from scratch
|
|
126
|
+
|
|
127
|
+
### Component Composition
|
|
128
|
+
Functions returning JSX (same syntax as React). Components execute once — the return
|
|
129
|
+
value is the actual DOM. Control flow via `<Show>`, `<For>`, `<Switch>` components
|
|
130
|
+
(not JS conditionals, because the function body doesn't re-execute).
|
|
131
|
+
|
|
132
|
+
### State Management
|
|
133
|
+
Built-in and first-class:
|
|
134
|
+
- `createSignal()` — atomic reactive value
|
|
135
|
+
- `createStore()` — nested reactive objects (Proxy-based)
|
|
136
|
+
- `createResource()` — async data with Suspense integration
|
|
137
|
+
- `createMemo()` — derived computations
|
|
138
|
+
No need for external state libraries in most cases.
|
|
139
|
+
|
|
140
|
+
### SSR / Hydration
|
|
141
|
+
- **SolidStart:** Streaming SSR with progressive hydration
|
|
142
|
+
- **Islands architecture:** Partial hydration possible via Astro integration
|
|
143
|
+
- **Performance:** Among the fastest SSR implementations due to no VDOM overhead
|
|
144
|
+
- **Limitation:** SolidStart is less battle-tested than Next.js/Nuxt; the Vinxi
|
|
145
|
+
foundation is being replaced with pure Vite in SolidStart 2.0
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 3. Svelte 5
|
|
150
|
+
|
|
151
|
+
### Core Reactive Model
|
|
152
|
+
**Compiler-first with signal-like runes.** The Svelte compiler transforms `.svelte`
|
|
153
|
+
files into imperative DOM operations at build time. Svelte 5 introduces "runes" — a
|
|
154
|
+
signal-based reactivity system using `$state`, `$derived`, `$effect` — replacing the
|
|
155
|
+
implicit `let`-based reactivity of Svelte 4.
|
|
156
|
+
|
|
157
|
+
Key runes:
|
|
158
|
+
- `$state(value)` — reactive state (backed by Proxy)
|
|
159
|
+
- `$state.raw(value)` — reactive but non-deep (no Proxy)
|
|
160
|
+
- `$derived(expr)` — computed value, auto-tracks dependencies
|
|
161
|
+
- `$effect(() => ...)` — side effect that re-runs on dependency changes
|
|
162
|
+
|
|
163
|
+
### Runtime Size
|
|
164
|
+
- **~2–18 KB** depending on features used (compiler includes only what's needed)
|
|
165
|
+
- Svelte 5 achieves **up to 50% smaller bundles** vs. Svelte 4
|
|
166
|
+
- Production dashboard benchmark: 47 KB total JS (vs. React's 156 KB for identical
|
|
167
|
+
functionality)
|
|
168
|
+
- The "disappearing framework" ideal is partially preserved — but Svelte 5 now ships
|
|
169
|
+
a small runtime for the reactivity system
|
|
170
|
+
|
|
171
|
+
### Build Step
|
|
172
|
+
Required. The Svelte compiler is the core of the framework — `.svelte` files are not
|
|
173
|
+
valid JavaScript. SvelteKit uses Vite as the build tool.
|
|
174
|
+
|
|
175
|
+
### Developer Experience
|
|
176
|
+
- **Strengths:** Minimal boilerplate, single-file components with scoped CSS, runes
|
|
177
|
+
provide explicit reactivity that works outside `.svelte` files (in `.svelte.js` and
|
|
178
|
+
`.svelte.ts`), excellent tutorial/documentation, SvelteKit is batteries-included
|
|
179
|
+
- **Performance:** Fastest initial render in benchmarks (110ms vs. Vue 142ms vs.
|
|
180
|
+
React 178ms), lowest memory footprint (7.9 MB idle vs. React's 18.7 MB)
|
|
181
|
+
|
|
182
|
+
### Known Pain Points
|
|
183
|
+
- **Runes add complexity:** Three state runes (`$state`, `$state.raw`,
|
|
184
|
+
`$state.snapshot`) force choices that didn't exist before. Proxy-based state has
|
|
185
|
+
non-obvious performance implications
|
|
186
|
+
- **Loss of "magic" simplicity:** Svelte 4's `let x = 0` reactivity was beloved for
|
|
187
|
+
its simplicity. Runes feel more like "React hooks but for Svelte" to some devs
|
|
188
|
+
- **Store deprecation:** The transparent, simple store system is deprecated in favor
|
|
189
|
+
of runes. Stores and runes have subtly different reactivity models that don't fully
|
|
190
|
+
interoperate
|
|
191
|
+
- **Runtime shift:** Svelte now ships actual runtime code for reactivity, moving away
|
|
192
|
+
from the pure "compile-away-the-framework" philosophy
|
|
193
|
+
- **Custom component format:** `.svelte` files are not standard JS — requires tooling
|
|
194
|
+
for every editor, linter, formatter, and build pipeline
|
|
195
|
+
- **Smaller ecosystem than React/Vue:** Fewer component libraries, less hiring demand
|
|
196
|
+
|
|
197
|
+
### Component Composition
|
|
198
|
+
Single-file `.svelte` components with `<script>`, markup, and `<style>` sections.
|
|
199
|
+
Props via `$props()` rune. Slots for content projection. Snippets (new in Svelte 5)
|
|
200
|
+
for reusable template fragments.
|
|
201
|
+
|
|
202
|
+
### State Management
|
|
203
|
+
Built-in via runes:
|
|
204
|
+
- `$state` for component-local and shared state
|
|
205
|
+
- `$derived` for computed values
|
|
206
|
+
- `$effect` for side effects
|
|
207
|
+
- Shared state via `.svelte.js` modules (exportable reactive state)
|
|
208
|
+
- Legacy stores still work but are deprecated
|
|
209
|
+
|
|
210
|
+
### SSR / Hydration
|
|
211
|
+
- **SvelteKit:** Full-featured meta-framework with streaming SSR, SSG, ISR
|
|
212
|
+
- **Progressive hydration:** Components hydrate as needed
|
|
213
|
+
- **Load functions:** Data fetching runs on server, serialized to client
|
|
214
|
+
- **Adapter system:** Deploy to Node, Vercel, Cloudflare, static, etc.
|
|
215
|
+
- **Performance:** Excellent — small JS payloads mean fast hydration
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 4. Vue 3.5+
|
|
220
|
+
|
|
221
|
+
### Core Reactive Model
|
|
222
|
+
**Proxy-based reactivity system.** Vue uses JavaScript Proxies to intercept
|
|
223
|
+
property access and mutation on reactive objects. When a reactive property is read
|
|
224
|
+
during a component's render, Vue tracks it as a dependency. When the property changes,
|
|
225
|
+
Vue re-renders only the affected components.
|
|
226
|
+
|
|
227
|
+
Key primitives:
|
|
228
|
+
- `ref(value)` — reactive wrapper (access via `.value`)
|
|
229
|
+
- `reactive(object)` — deep reactive proxy
|
|
230
|
+
- `computed(() => ...)` — cached derived value
|
|
231
|
+
- `watch()` / `watchEffect()` — explicit side effects
|
|
232
|
+
|
|
233
|
+
**Vapor Mode** (in development for Vue 3.6): A new compilation strategy that
|
|
234
|
+
eliminates the Virtual DOM entirely, generating direct DOM-update code similar to
|
|
235
|
+
Solid.js. Same developer-facing API, different compilation output.
|
|
236
|
+
|
|
237
|
+
### Runtime Size
|
|
238
|
+
- **~27–34 KB** min+gzip (official: ~27 KB runtime, reported in benchmarks as ~34 KB)
|
|
239
|
+
- Vue 3.5: 56% memory usage improvement, 10x faster for large reactive arrays
|
|
240
|
+
- Vapor Mode (when stable) will further reduce overhead by removing VDOM diffing code
|
|
241
|
+
|
|
242
|
+
### Build Step
|
|
243
|
+
Required. Vite (created by Vue's author, Evan You) is the standard build tool.
|
|
244
|
+
Single-file components (`.vue`) require the Vue compiler.
|
|
245
|
+
|
|
246
|
+
### Developer Experience
|
|
247
|
+
- **Strengths:** Best learning curve among major frameworks, excellent documentation,
|
|
248
|
+
Composition API offers React-hooks-like composability without the footguns,
|
|
249
|
+
progressive adoption (can use Options API or Composition API), strong TypeScript
|
|
250
|
+
integration
|
|
251
|
+
- **Nuxt 3:** Mature meta-framework with auto-imports, file-based routing, server
|
|
252
|
+
routes, excellent DX
|
|
253
|
+
|
|
254
|
+
### Known Pain Points
|
|
255
|
+
- **`.value` ceremony:** `ref()` requires accessing `.value` in script but not in
|
|
256
|
+
templates — a persistent source of confusion
|
|
257
|
+
- **Two API styles:** Options API vs. Composition API creates ecosystem fragmentation;
|
|
258
|
+
tutorials/libraries may use either
|
|
259
|
+
- **Vapor Mode delays:** Originally planned for Vue 3.4, now expected in 3.6+.
|
|
260
|
+
Compatibility challenges have pushed the timeline repeatedly
|
|
261
|
+
- **Enterprise adoption gaps:** Strong in APAC/EU design-led markets but limited
|
|
262
|
+
hiring pools in US enterprise compared to React/Angular
|
|
263
|
+
- **Ecosystem size:** Large but smaller than React's — fewer choices in some niches
|
|
264
|
+
|
|
265
|
+
### Component Composition
|
|
266
|
+
Single-file `.vue` components with `<script setup>`, `<template>`, and `<style>`
|
|
267
|
+
sections. `<script setup>` is the modern default — top-level bindings are
|
|
268
|
+
automatically exposed to the template. Props via `defineProps()`, events via
|
|
269
|
+
`defineEmits()`. Slots for content projection.
|
|
270
|
+
|
|
271
|
+
### State Management
|
|
272
|
+
Built-in reactivity is often sufficient:
|
|
273
|
+
- `ref()` / `reactive()` for local/shared state
|
|
274
|
+
- `computed()` for derived values
|
|
275
|
+
- `provide` / `inject` for dependency injection
|
|
276
|
+
- **Pinia** (official) for complex global state — simple, TypeScript-native, devtools
|
|
277
|
+
integration
|
|
278
|
+
- Vue 3.5+ SSR: `useId()` for hydration-safe unique IDs
|
|
279
|
+
|
|
280
|
+
### SSR / Hydration
|
|
281
|
+
- **Nuxt 3:** Full-featured meta-framework (SSR, SSG, ISR, hybrid rendering)
|
|
282
|
+
- **Lazy hydration (Vue 3.5):** Components can defer hydration until needed
|
|
283
|
+
- **Streaming SSR:** Supported via Nuxt 3 + `renderToWebStream`
|
|
284
|
+
- **`useId()`:** Stable hydration-safe IDs for accessibility and form elements
|
|
285
|
+
- **Performance:** Good — smaller runtime means less JS to hydrate
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## 5. Angular 19–20
|
|
290
|
+
|
|
291
|
+
### Core Reactive Model
|
|
292
|
+
**Signals (new) + Zone.js change detection (legacy).** Angular is transitioning from
|
|
293
|
+
Zone.js-based change detection (monkey-patches all async APIs to trigger global
|
|
294
|
+
change detection) to a granular Signals-based system.
|
|
295
|
+
|
|
296
|
+
Signal primitives:
|
|
297
|
+
- `signal(value)` — writable reactive value (`.set()`, `.update()`)
|
|
298
|
+
- `computed(() => ...)` — read-only derived signal
|
|
299
|
+
- `effect(() => ...)` — side effect (stabilized in Angular 20)
|
|
300
|
+
- `linkedSignal()` — signal linked to a source (stabilized in Angular 20)
|
|
301
|
+
|
|
302
|
+
**Zoneless** (Developer Preview in Angular 20): Removes Zone.js entirely, relying
|
|
303
|
+
on Signals for change detection. Cleaner stack traces, smaller bundles, better
|
|
304
|
+
compatibility with third-party code.
|
|
305
|
+
|
|
306
|
+
### Runtime Size
|
|
307
|
+
- **~50–65 KB** gzipped for core framework
|
|
308
|
+
- Fresh "Hello World" project: **130–138 KB+** min+gzip
|
|
309
|
+
- Removing Zone.js (zoneless) reduces this, but Angular remains the heaviest framework
|
|
310
|
+
- FCP: 400–800 ms (vs. Vue's 150–300 ms, React's ~300 ms)
|
|
311
|
+
|
|
312
|
+
### Build Step
|
|
313
|
+
Required. Angular CLI with Webpack or esbuild. AOT (Ahead-of-Time) template
|
|
314
|
+
compilation is the default — templates are compiled to optimized JS at build time.
|
|
315
|
+
Strict project structure enforced by the CLI.
|
|
316
|
+
|
|
317
|
+
### Developer Experience
|
|
318
|
+
- **Strengths:** Opinionated "batteries-included" framework (routing, forms, HTTP,
|
|
319
|
+
i18n, testing all built-in), excellent for large teams with enforced patterns,
|
|
320
|
+
strong TypeScript integration (TypeScript is required, not optional), dependency
|
|
321
|
+
injection is powerful for enterprise architecture
|
|
322
|
+
- **Angular 19–20 improvements:** Standalone components as default (no more
|
|
323
|
+
NgModules), Signals stabilized, resource API for async data, better DevTools
|
|
324
|
+
|
|
325
|
+
### Known Pain Points
|
|
326
|
+
- **Boilerplate:** Even with standalone components, Angular requires more ceremony
|
|
327
|
+
than alternatives. Decorators, metadata, DI registration
|
|
328
|
+
- **Change detection confusion:** `ExpressionChangedAfterItHasBeenCheckedError`
|
|
329
|
+
produces stack traces pointing to framework code, not developer code. This error
|
|
330
|
+
has been a top Angular complaint for years
|
|
331
|
+
- **Bundle size:** Largest runtime of all major frameworks. Zone.js adds ~35 KB alone
|
|
332
|
+
- **Learning curve:** Steepest of all frameworks. New hires struggle for months.
|
|
333
|
+
RxJS adds another learning dimension on top of Signals
|
|
334
|
+
- **Two reactive paradigms:** RxJS Observables and Signals now coexist, creating
|
|
335
|
+
confusion about when to use which. `toSignal()` / `toObservable()` bridge the gap
|
|
336
|
+
but add complexity
|
|
337
|
+
- **DI runtime errors:** "No provider for X!" errors are common and hard to debug
|
|
338
|
+
|
|
339
|
+
### Component Composition
|
|
340
|
+
Standalone components (Angular 19+ default) — no NgModule required. Components are
|
|
341
|
+
TypeScript classes with decorators. Templates use Angular's own syntax (`@if`, `@for`,
|
|
342
|
+
`@switch` — new control flow in Angular 17+). Content projection via `<ng-content>`.
|
|
343
|
+
Directives for cross-cutting behavior.
|
|
344
|
+
|
|
345
|
+
### State Management
|
|
346
|
+
Built-in (increasingly):
|
|
347
|
+
- Signals for synchronous reactive state
|
|
348
|
+
- RxJS for async streams (legacy but deeply embedded)
|
|
349
|
+
- Services + DI for shared state
|
|
350
|
+
- **NgRx** (Redux-like) for complex enterprise state — being updated for Signals
|
|
351
|
+
- **Resource API** (Angular 19+) for async data fetching with Signals integration
|
|
352
|
+
|
|
353
|
+
### SSR / Hydration
|
|
354
|
+
- **Angular SSR:** Built-in (formerly Angular Universal), now tightly integrated
|
|
355
|
+
- **Incremental hydration:** Components stay dehydrated until triggered. Triggers:
|
|
356
|
+
`viewport`, `interaction`, `idle`, `timer(ms)`, `immediate`, `never`,
|
|
357
|
+
`when(condition)`
|
|
358
|
+
- **`@defer` blocks:** Lazy-load components with built-in hydration trigger syntax
|
|
359
|
+
- **Event replay:** User interactions during SSR are captured and replayed after
|
|
360
|
+
hydration (Angular 18+)
|
|
361
|
+
- **Performance:** Incremental hydration significantly improves FID and CLS, but
|
|
362
|
+
larger initial bundle still creates overhead vs. lighter frameworks
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Cross-Cutting Analysis
|
|
367
|
+
|
|
368
|
+
### The Convergence Toward Signals
|
|
369
|
+
|
|
370
|
+
Every major framework is converging on signal-based reactivity:
|
|
371
|
+
|
|
372
|
+
| Framework | Signal Implementation | Status |
|
|
373
|
+
|-----------|------------------------------------|------------------|
|
|
374
|
+
| Solid.js | Pioneered the pattern | Stable (1.x) |
|
|
375
|
+
| Angular | `signal()`, `computed()`, `effect()` | Stable (v20) |
|
|
376
|
+
| Vue | `ref()`, `reactive()`, `computed()` | Stable (v3.0+) |
|
|
377
|
+
| Svelte | `$state`, `$derived`, `$effect` | Stable (v5) |
|
|
378
|
+
| React | No signals — VDOM + Compiler | Divergent path |
|
|
379
|
+
|
|
380
|
+
React is the outlier. Every other framework has adopted signals (or signal-like
|
|
381
|
+
reactivity). React's response is the React Compiler — automating VDOM optimizations
|
|
382
|
+
rather than changing the reactive model.
|
|
383
|
+
|
|
384
|
+
### The Compiler Spectrum
|
|
385
|
+
|
|
386
|
+
Frameworks sit on a spectrum from pure runtime to pure compiler:
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
Pure Runtime ←——————————————————————————→ Pure Compiler
|
|
390
|
+
React Vue Angular Svelte (Solid)
|
|
391
|
+
(VDOM + (Proxy + (AOT + (Compiler + (Compiler +
|
|
392
|
+
Compiler future template runes signals,
|
|
393
|
+
hints) Vapor) compile) runtime) minimal RT)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
- **React:** Mostly runtime. Compiler adds optimization hints but doesn't change
|
|
397
|
+
the execution model.
|
|
398
|
+
- **Vue:** Runtime reactivity. Vapor Mode will add a compiler path that bypasses VDOM.
|
|
399
|
+
- **Angular:** AOT template compilation + runtime change detection. Signals are
|
|
400
|
+
reducing runtime overhead.
|
|
401
|
+
- **Svelte:** Deep compiler, but Svelte 5 added a signal runtime. Shifting right
|
|
402
|
+
to left.
|
|
403
|
+
- **Solid:** Compiler transforms JSX to fine-grained DOM ops. Minimal runtime (~7 KB).
|
|
404
|
+
|
|
405
|
+
### Where the Gaps Are (Opportunities for Rip UI)
|
|
406
|
+
|
|
407
|
+
1. **No framework has unified the server/client model cleanly.** React's RSC is the
|
|
408
|
+
most ambitious attempt but creates a two-world problem (`'use client'` directives,
|
|
409
|
+
different rules for each). Every other framework punts to a meta-framework (Nuxt,
|
|
410
|
+
SvelteKit, SolidStart).
|
|
411
|
+
|
|
412
|
+
2. **Reactivity is powerful but each flavor has ergonomic costs.** React's hooks have
|
|
413
|
+
rules and footguns. Vue's `.value` is a papercut. Svelte's runes added complexity.
|
|
414
|
+
Angular's Signals coexist awkwardly with RxJS. Solid's signals are elegant but the
|
|
415
|
+
JSX control flow (`<For>`, `<Show>`) is a compromise.
|
|
416
|
+
|
|
417
|
+
3. **Bundle size vs. DX is an unresolved tension.** Svelte and Solid ship tiny bundles
|
|
418
|
+
but require custom file formats or component-level conventions. React and Angular
|
|
419
|
+
are heavy but offer familiar JS/TS ergonomics.
|
|
420
|
+
|
|
421
|
+
4. **State management is fragmented.** React has no built-in solution (dozens of
|
|
422
|
+
competing libraries). Vue/Svelte/Solid have built-in primitives but each with
|
|
423
|
+
quirks. Angular has two competing paradigms (RxJS + Signals).
|
|
424
|
+
|
|
425
|
+
5. **Hydration is still a problem everyone is solving differently.** Full hydration
|
|
426
|
+
(wasteful), progressive hydration (complex), incremental hydration (Angular's
|
|
427
|
+
approach), resumability (Qwik's approach). No consensus, each with trade-offs.
|
|
428
|
+
|
|
429
|
+
6. **TypeScript integration varies.** Angular requires it. React/Vue/Svelte support
|
|
430
|
+
it but with varying degrees of type inference quality (Svelte's compiler and Vue's
|
|
431
|
+
SFC templates are harder to type-check than plain TSX).
|
|
432
|
+
|
|
433
|
+
7. **Custom file formats create tooling tax.** `.svelte`, `.vue`, `.astro` files
|
|
434
|
+
each need custom language server support, linter plugins, formatter configs. Plain
|
|
435
|
+
`.js`/`.ts` (React, Solid) avoid this at the cost of less framework-level
|
|
436
|
+
optimization.
|
|
437
|
+
|
|
438
|
+
### Performance Benchmarks (JS Framework Benchmark, 2025)
|
|
439
|
+
|
|
440
|
+
| Framework | Score (lower = faster) | Startup (ms) | Memory (MB) |
|
|
441
|
+
|-------------|------------------------|-------------|-------------|
|
|
442
|
+
| Vanilla JS | 1.00 | — | — |
|
|
443
|
+
| Solid.js | 1.07 | 28 | ~8 |
|
|
444
|
+
| Svelte 5 | ~1.10 | 35 | ~8 |
|
|
445
|
+
| Vue 3 | ~1.30 | 42 | ~11 |
|
|
446
|
+
| React 19 | 1.71 | 55 | ~19 |
|
|
447
|
+
| Angular 19 | ~1.80+ | 78 | ~22 |
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Positioning Questions for Rip UI
|
|
452
|
+
|
|
453
|
+
Based on this landscape, a new framework should be prepared to answer:
|
|
454
|
+
|
|
455
|
+
1. **Reactive model:** Signals, VDOM, compiler-generated, or something new? The
|
|
456
|
+
industry has nearly converged on signals — deviating needs a strong argument.
|
|
457
|
+
|
|
458
|
+
2. **Compiler depth:** How much work happens at build time vs. runtime? The trend is
|
|
459
|
+
toward more compilation, but each compiler approach creates tooling complexity.
|
|
460
|
+
|
|
461
|
+
3. **Runtime weight:** Can you beat Solid's 7 KB? Can you approach zero-runtime like
|
|
462
|
+
original Svelte promised? What's the minimum viable runtime?
|
|
463
|
+
|
|
464
|
+
4. **Server integration:** Is the server/client boundary a first-class concept? Can
|
|
465
|
+
it avoid the `'use client'` / meta-framework split that plagues React?
|
|
466
|
+
|
|
467
|
+
5. **Hydration strategy:** Full, progressive, incremental, resumable, or none? This
|
|
468
|
+
is the current frontier of framework innovation.
|
|
469
|
+
|
|
470
|
+
6. **File format:** Custom (`.svelte`, `.vue`) or standard JS/TS? Custom formats
|
|
471
|
+
enable deeper optimization but impose ecosystem costs.
|
|
472
|
+
|
|
473
|
+
7. **State management:** Built-in or ecosystem? Every framework that delegated this
|
|
474
|
+
to the ecosystem (React) regrets it. Every framework with built-in state must
|
|
475
|
+
balance simplicity with power.
|
|
476
|
+
|
|
477
|
+
8. **TypeScript story:** First-class types? Type inference quality? Can the framework
|
|
478
|
+
provide better type safety than existing options?
|
|
479
|
+
|
|
480
|
+
9. **Migration story:** Can React/Vue/Svelte developers adopt incrementally, or is it
|
|
481
|
+
all-or-nothing?
|
|
482
|
+
|
|
483
|
+
10. **What's the one thing you can do that none of them can?** Every successful
|
|
484
|
+
framework had a clear differentiator: React had the VDOM (2013), Vue had
|
|
485
|
+
progressive adoption (2014), Svelte had compile-away-the-framework (2019),
|
|
486
|
+
Solid had true fine-grained reactivity (2021), Qwik had resumability (2023).
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Rip UI — Roadmap
|
|
2
|
+
|
|
3
|
+
## What's There
|
|
4
|
+
|
|
5
|
+
### Core Reactive System
|
|
6
|
+
- **Reactive primitives** — `:=` (state), `~=` (computed), `~>` (effects) as
|
|
7
|
+
language syntax. Fine-grained dependency tracking, batching, readonly (`=!`).
|
|
8
|
+
- **`__Component` base class** — mount, unmount, context push/pop, constructor
|
|
9
|
+
lifecycle all handled in the runtime. Components just override `_init`.
|
|
10
|
+
- **`__state` signal passthrough** — if a value is already a signal, `__state`
|
|
11
|
+
returns it as-is. No separate `isSignal` check needed.
|
|
12
|
+
- **Fine-grained DOM** — `_create` builds real DOM nodes, `_setup` wires
|
|
13
|
+
reactive effects that update individual text nodes and attributes.
|
|
14
|
+
- **Timing primitives** — `delay`, `debounce`, `throttle`, `hold` as small
|
|
15
|
+
user-space functions composing `:=` + `~>` + cleanup. No framework API.
|
|
16
|
+
|
|
17
|
+
### Component Model
|
|
18
|
+
- **Component composition** — PascalCase identifiers in render blocks
|
|
19
|
+
instantiate child components. `card.rip` → `Card`. App-scoped, lazy-compiled,
|
|
20
|
+
cached after first use. No imports needed.
|
|
21
|
+
- **Reactive props** — parent passes `:=` signals directly to children.
|
|
22
|
+
Child's `__state` passthrough returns the signal as-is. Two-way binding.
|
|
23
|
+
- **Readonly props** — `=!` for props that children can read but not write.
|
|
24
|
+
- **Children blocks** — `Card title: "Hello" -> p "content"` passes children
|
|
25
|
+
as a DOM node via the `@children` slot. `#content` for layout slots.
|
|
26
|
+
- **Unmount cascade** — parent tracks child instances in `_children`.
|
|
27
|
+
`unmount()` cascades depth-first.
|
|
28
|
+
- **Conditional rendering** — `if`/`else` in render blocks with anchor-based
|
|
29
|
+
conditional DOM.
|
|
30
|
+
- **List rendering** — `for item in items` with keyed reconciliation.
|
|
31
|
+
- **Event handling** — `@click: method` binds to `this.method` correctly.
|
|
32
|
+
- **CSS classes** — `div.counter.active` compiles to static className.
|
|
33
|
+
Dynamic classes via `__clsx(...)`.
|
|
34
|
+
- **Context** — `setContext`/`getContext`/`hasContext` for sharing data
|
|
35
|
+
between ancestor and descendant components without prop drilling.
|
|
36
|
+
- **Lifecycle hooks** — `mounted`, `unmounted` work. `beforeMount`,
|
|
37
|
+
`beforeUnmount` are recognized.
|
|
38
|
+
|
|
39
|
+
### State & Routing
|
|
40
|
+
- **Reactive stash** — shared reactive store with proxy-based access.
|
|
41
|
+
- **File-based router** — URL-to-component mapping with params, guards,
|
|
42
|
+
layouts, `_navigating` signal, keep-alive component cache.
|
|
43
|
+
- **Hash routing** — `launch '/app', hash: true` for static single-file
|
|
44
|
+
deployment. Uses `readUrl()`/`writeUrl()` helpers. Back/forward and
|
|
45
|
+
direct URL loading work correctly.
|
|
46
|
+
- **State persistence** — `persist: true` enables debounced auto-save of
|
|
47
|
+
`app.data` to sessionStorage. `_writeVersion` signal + `beforeunload` safety.
|
|
48
|
+
- **Error boundaries** — catch mount-time errors.
|
|
49
|
+
|
|
50
|
+
### Infrastructure
|
|
51
|
+
- **Component store** — in-memory `.rip` file storage with compilation cache
|
|
52
|
+
and file watchers for hot reload via SSE.
|
|
53
|
+
- **`launch bundle:`** — inline all components as heredoc strings in a single
|
|
54
|
+
HTML file. Zero-server deployment. `docs/demo.html` is a 337-line example.
|
|
55
|
+
- **Combined bundle** — `rip-ui.min.js` (~52KB Brotli) packages the compiler
|
|
56
|
+
and pre-compiled UI framework in one file. Eliminates the `ui.rip` fetch
|
|
57
|
+
and its runtime compilation. `importRip('ui.rip')` is intercepted and returns
|
|
58
|
+
the pre-compiled module instantly.
|
|
59
|
+
- **Parallel loading** — Monaco Editor preloaded via `<link rel="preload">`,
|
|
60
|
+
compiler exports available instantly via `globalThis.__ripExports`. All
|
|
61
|
+
synchronous setup runs in parallel with the Monaco CDN fetch.
|
|
62
|
+
- **FOUC prevention** — playground pages use `body { opacity: 0 }` with a
|
|
63
|
+
`body.ready` fade-in transition after full initialization.
|
|
64
|
+
- **Runtime deduplication** — both runtimes register on `globalThis.__rip`
|
|
65
|
+
and `globalThis.__ripComponent`. Multiple compilations share one runtime.
|
|
66
|
+
- **Smooth app launch** — container fades in after first mount + font load.
|
|
67
|
+
- **Navigation anti-flicker** — `_navigating` uses `delay 100` to suppress
|
|
68
|
+
brief loading indicators.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Where Rip UI Wins
|
|
73
|
+
|
|
74
|
+
1. **Simplicity of the reactive model.** Three operators, minimal complete set. No hooks rules, no dependency arrays, no `.value` papercuts.
|
|
75
|
+
2. **Zero-build development.** No other framework runs entirely in the browser with zero build tooling.
|
|
76
|
+
3. **Timing primitives from composition.** `delay`, `debounce`, `throttle`, `hold` prove architectural correctness — hard problems dissolve into small functions.
|
|
77
|
+
4. **Effect cleanup design.** Returning a function from an effect for cleanup is the cleanest pattern across all frameworks.
|
|
78
|
+
5. **Syntax over API.** `:=` beats `ref()`. `~=` beats `computed()`. `~>` beats `watchEffect()`. Less ceremony, same power.
|
|
79
|
+
6. **Static deployment.** Hash routing + `launch bundle:` = full SPA in a single HTML file on any static host.
|
|
80
|
+
|
|
81
|
+
## Where Others Win
|
|
82
|
+
|
|
83
|
+
1. **Ecosystem.** Zero component libraries, zero third-party integrations, zero community packages.
|
|
84
|
+
2. **SSR.** No server-side rendering means no SEO, no progressive enhancement.
|
|
85
|
+
3. **Performance proof.** No benchmarks, no published numbers.
|
|
86
|
+
4. **TypeScript depth.** Framework exports have no `.d.ts` files.
|
|
87
|
+
5. **Tooling.** No DevTools extension, no CLI scaffolding.
|
|
88
|
+
6. **Battle-testing.** React serves billions. We serve a demo app.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## The Path Forward
|
|
93
|
+
|
|
94
|
+
### Must-have (blocks adoption)
|
|
95
|
+
1. Named slots — multiple content projection points (header, body, footer)
|
|
96
|
+
2. Framework `.d.ts` files — TypeScript definitions for all exports
|
|
97
|
+
|
|
98
|
+
### Should-have (competitive parity)
|
|
99
|
+
3. AOT compilation path — component-level ahead-of-time for production (framework AOT done in v0.3.2)
|
|
100
|
+
4. SSR — server rendering for SEO
|
|
101
|
+
5. js-framework-benchmark — published performance numbers
|
|
102
|
+
6. Keyed list reconciliation — optimized array diffing for large datasets
|
|
103
|
+
|
|
104
|
+
### Nice-to-have (ecosystem growth)
|
|
105
|
+
7. DevTools extension — visual component/state inspector
|
|
106
|
+
8. `create-rip-app` CLI — project scaffolding
|
|
107
|
+
9. Headless UI primitives — accessible dropdown, modal, dialog
|
|
108
|
+
10. State-preserving HMR — keep reactive state during hot reload
|
|
109
|
+
11. Scoped slots and teleport — advanced composition patterns
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Known Caveats
|
|
114
|
+
|
|
115
|
+
- **`getCompiled`/`setCompiled` cache modules, not JS strings.** Same source
|
|
116
|
+
at two paths = two cached modules. No deduplication across paths.
|
|
117
|
+
- **Stash proxy missing `getOwnPropertyDescriptor` trap.** Works in practice
|
|
118
|
+
but could cause issues with `Object.keys`/spread in strict environments.
|
|
119
|
+
- **Router regex recreated on every `buildRoutes` call.** Not a problem with
|
|
120
|
+
small route tables. Could optimize with fingerprint comparison.
|
|
121
|
+
- **`router.current` creates a new object on every read.** A cached object
|
|
122
|
+
that updates inside batch would reduce garbage.
|
|
123
|
+
- **REPL reactive state doesn't persist across `rip()` calls.** Each call is
|
|
124
|
+
a separate compilation. All reactive code must be in a single call.
|
|
125
|
+
- **Hash routing and path routing are mutually exclusive.** Set once at
|
|
126
|
+
`launch` time. No runtime switching between modes.
|