rip-lang 2.5.0 → 2.7.1

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 CHANGED
@@ -7,6 +7,49 @@ All notable changes to Rip will be documented in this file.
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [2.7.1] - 2026-02-03
11
+
12
+ ### Bun-Native REPL with Dynamic Import Support
13
+
14
+ **Full `import()` Support in REPL**: The REPL now uses Bun's native evaluation instead of Node's `vm` module, enabling dynamic imports:
15
+
16
+ ```coffee
17
+ rip> { Cash } = await import("./utils.js")
18
+ rip> config = Cash((await import("./config.js")).default)
19
+ rip> config.app.name
20
+ → 'My App'
21
+ ```
22
+
23
+ **Key changes:**
24
+ - Replaced `vm.runInContext` with file-based async evaluation
25
+ - Variables persist across REPL lines via `globalThis.__ripRepl`
26
+ - Temp files cleaned up automatically on exit
27
+ - Reactive runtime injected into global scope for cross-line sharing
28
+
29
+ This enables using the REPL for real development workflows with module imports.
30
+
31
+ ---
32
+
33
+ ## [2.5.1] - 2026-01-16
34
+
35
+ ### Template Enhancement
36
+
37
+ **Hyphenated Attributes Work Directly**:
38
+ ```coffee
39
+ render
40
+ # Before: needed quoted keys or spread syntax
41
+ i {"data-lucide": "search"}
42
+
43
+ # Now: just works!
44
+ i data-lucide: "search", aria-hidden: "true"
45
+ div data-testid: "container", aria-label: "Menu"
46
+ span data-foo-bar-baz: "multiple-hyphens-work"
47
+ ```
48
+
49
+ The lexer now automatically converts hyphenated attribute names (like `data-*`, `aria-*`) into quoted strings, making HTML-style data attributes intuitive and clean.
50
+
51
+ ---
52
+
10
53
  ## [2.5.0] - 2026-01-16
11
54
 
12
55
  ### Major Release - Parser Optimization + Complete Framework
@@ -156,7 +199,7 @@ Counter.new().mount("#app") # Selector string support
156
199
 
157
200
  | Category | Score | Notes |
158
201
  |----------|-------|-------|
159
- | **Reactivity** | A+ | Fine-grained, signals, effects |
202
+ | **Reactivity** | A+ | Fine-grained, state, effects |
160
203
  | **Templates** | A | S-expressions, Pug shorthand |
161
204
  | **Components** | A | Props, lifecycle, context API |
162
205
  | **Performance** | A | 250× faster parser gen, 51KB bundle |
@@ -167,7 +210,7 @@ Counter.new().mount("#app") # Selector string support
167
210
 
168
211
  **What's in 51KB?**
169
212
  - Complete compiler (lexer, parser, code generator)
170
- - Reactive runtime (signals, derived values, effects)
213
+ - Reactive runtime (state, computed values, effects)
171
214
  - Template engine (S-expression syntax, dynamic classes)
172
215
  - Component system (props, lifecycle, fine-grained updates)
173
216
  - Zero dependencies
@@ -272,10 +315,10 @@ Each item gets its own effect. Changing `selected` updates ONLY the affected cla
272
315
  ### Added - Reactive UI Framework
273
316
 
274
317
  **Phase 1: Reactivity** (previously released)
275
- - Signal-based reactivity: `count = 0` creates reactive state
276
- - Derived values: `doubled ~= count * 2` auto-tracks dependencies
277
- - Effects: `effect -> console.log count` runs on changes
278
- - Runtime: `__signal()`, `__computed()`, `__effect()`, `__batch()`, `__readonly()`
318
+ - State-based reactivity: `count := 0` creates reactive state
319
+ - Computed values: `doubled ~= count * 2` auto-tracks dependencies
320
+ - Effects: `~> console.log count` runs on changes
321
+ - Runtime: `__state()`, `__computed()`, `__effect()`, `__batch()`, `__readonly()`
279
322
 
280
323
  **Phase 2: Templates**
281
324
  - Indentation-based template syntax in `render` blocks
@@ -297,8 +340,8 @@ Each item gets its own effect. Changing `selected` updates ONLY the affected cla
297
340
  - Optional: `@label?`
298
341
  - Default: `@label = "default"`
299
342
  - Rest: `@...rest`
300
- - Reactive state within components (auto-signals)
301
- - Derived values within components (auto-computed)
343
+ - Reactive state within components (auto-state)
344
+ - Computed values within components (auto-computed)
302
345
  - Component composition: `Button label: "Click"` inside render
303
346
  - Children/slots: `@children` prop for nested content
304
347
  - Lifecycle hooks: `mounted:`, `unmounted:`
@@ -312,8 +355,8 @@ Each item gets its own effect. Changing `selected` updates ONLY the affected cla
312
355
  ### Technical Details
313
356
  - Components compile to ES6 classes with constructor, render, mount, unmount
314
357
  - Props validated at construction (required props throw if missing)
315
- - State variables become `__signal()` calls
316
- - Derived values become `__computed()` calls
358
+ - State variables become `__state()` calls
359
+ - Computed values become `__computed()` calls
317
360
  - `mount()` wraps render in `__effect()` for reactive updates
318
361
  - PascalCase names in templates trigger component instantiation
319
362
 
package/README.md CHANGED
@@ -5,27 +5,37 @@
5
5
  <h1 align="center">Rip</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>Elegant reactive code that compiles to modern JavaScript</strong>
8
+ <strong>A modern language that compiles to JavaScript</strong>
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-2.5.0-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-2.7.1-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
- <a href="#"><img src="https://img.shields.io/badge/tests-1046%2F1046-brightgreen.svg" alt="Tests"></a>
14
+ <a href="#"><img src="https://img.shields.io/badge/tests-979%2F979-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
16
16
  </p>
17
17
 
18
18
  ---
19
19
 
20
- ## What is Rip?
20
+ Rip is a modern language inspired by CoffeeScript. It compiles to **ES2022** (classes, `?.`, `??`, modules), adds about a **dozen new operators**, includes **built-in reactivity**, and sports a self-hosting compiler with **zero dependencies** — all in about 10,000 lines of code.
21
21
 
22
- Rip is a modern reactive language that compiles to JavaScript. It takes the elegant, readable syntax that made CoffeeScript beloved and brings it into the modern era — with ES2022 output, built-in reactivity, and a clean component system for building UIs.
22
+ > **No imports. No hooks. No dependency arrays. Just write code.**
23
23
 
24
- The compiler is completely standalone with zero dependencies, and it's self-hosting: Rip compiles itself. At ~14,000 lines of code, it's smaller than CoffeeScript (17,760 LOC) while including a complete reactive framework with signals, templates, and components.
24
+ ```coffee
25
+ data = fetchUsers! # Dammit operator (call + await)
26
+ user = User.new name: "Alice" # Ruby-style constructor
27
+ squares = (x * x for x in [1..10]) # List comprehension
28
+
29
+ str =~ /Hello, (\w+)/ # Regex match
30
+ log "Found: #{_[1]}" # Captures in _[1], _[2], etc.
31
+ ```
32
+
33
+ ---
25
34
 
26
35
  **What makes Rip different:**
27
- - **Reactive primitives** — signals, derived values, and effects built into the language
28
36
  - **Modern output** — ES2022 with native classes, `?.`, `??`, modules
37
+ - **New operators** — `!`, `!?`, `//`, `%%`, `=~`, `.new()`, and more
38
+ - **Reactive operators** — `:=`, `~=`, `~>` as language syntax
29
39
  - **Zero dependencies** — everything included, even the parser generator
30
40
  - **Self-hosting** — `bun run parser` rebuilds the compiler from source
31
41
 
@@ -33,229 +43,150 @@ The compiler is completely standalone with zero dependencies, and it's self-host
33
43
 
34
44
  ## Installation
35
45
 
36
- **Option 1: Install from npm**
37
- ```bash
38
- curl -fsSL https://bun.sh/install | bash # Install Bun (if needed)
39
- bun add -g rip-lang
40
- ```
41
-
42
- **Option 2: Clone from source**
43
46
  ```bash
44
- git clone https://github.com/shreeve/rip-lang.git
45
- cd rip-lang && bun link
47
+ bun add -g rip-lang # Install globally
46
48
  ```
47
49
 
48
- **Then use it:**
49
50
  ```bash
50
- rip # Interactive REPL
51
- rip file.rip # Run a file
52
- rip -c file.rip # Compile to JavaScript
53
- bun file.rip # Direct execution with Bun loader
51
+ rip # Interactive REPL
52
+ rip file.rip # Run a file
53
+ rip -c file.rip # Compile to JavaScript
54
54
  ```
55
55
 
56
56
  ---
57
57
 
58
- ## Language Features
58
+ ## Language
59
59
 
60
60
  ### Functions & Classes
61
+
61
62
  ```coffee
62
- # Three function styles
63
- def greet(name) # Named function (hoisted)
63
+ def greet(name) # Named function
64
64
  "Hello, #{name}!"
65
65
 
66
- add = (a, b) -> a + b # Arrow function
67
- handler = (e) => @process e # Fat arrow (preserves this)
68
-
69
- # Classes with clean syntax
70
- class Animal
71
- constructor: (@name) ->
72
- speak: -> console.log "#{@name} makes a sound"
66
+ add = (a, b) -> a + b # Arrow function
67
+ handler = (e) => @process e # Fat arrow (preserves this)
73
68
 
74
69
  class Dog extends Animal
75
- speak: -> console.log "#{@name} barks"
70
+ speak: -> log "#{@name} barks"
76
71
 
77
- # Ruby-style constructors (both styles work)
78
- dog = Dog.new("Buddy") # → new Dog("Buddy")
79
- dog = new Dog("Buddy") # Traditional JS style
72
+ dog = Dog.new("Buddy") # Ruby-style constructor
80
73
  ```
81
74
 
82
75
  ### Destructuring & Comprehensions
76
+
83
77
  ```coffee
84
- # Destructuring
85
78
  {name, age} = person
86
79
  [first, ...rest] = items
87
80
 
88
- # Comprehensions (context-aware!)
89
- squares = (x * x for x in [1..10]) # Returns array
90
- console.log x for x in items # Just loops (no array created)
81
+ squares = (x * x for x in [1..10]) # Array comprehension
82
+ console.log x for x in items # Loop (no array)
91
83
  ```
92
84
 
93
- ### Async & Optional Chaining
85
+ ### Async & Chaining
86
+
94
87
  ```coffee
95
- # Auto-async detection
96
88
  def loadUser(id)
97
- response = await fetch "/api/users/#{id}"
89
+ response = await fetch "/api/#{id}"
98
90
  await response.json()
99
91
 
100
- # Optional chaining (both styles work)
101
- user?.profile?.name # ES2020 native
102
- arr?[0] # CoffeeScript soak
103
- fn?(arg) # Safe call
92
+ user?.profile?.name # Optional chaining
93
+ data = fetchData! # Await shorthand
104
94
  ```
105
95
 
106
- ---
96
+ ### Reactivity
107
97
 
108
- ## Unique Features
109
-
110
- ### New Operators & Syntax
111
-
112
- | Feature | Example | What it does |
113
- |---------|---------|--------------|
114
- | **Ruby `.new()`** | `Counter.new()` | Ruby-style constructor → `new Counter()` |
115
- | **Dammit `!`** | `fetchData!` | Calls the function AND awaits it |
116
- | **Void `!`** | `def process!` | Suppresses implicit return (always returns undefined) |
117
- | **Otherwise `!?`** | `val !? 5` | Defaults only if `undefined` (null/0/false are kept!) |
118
- | **Floor div `//`** | `7 // 2` | Floor division → `Math.floor(7 / 2)` = 3 |
119
- | **True mod `%%`** | `-1 %% 3` | True modulo (not remainder) → 2, not -1 |
120
- | **Equal, dammit! `=!`** | `MAX =! 100` | Forces `const` declaration (can't reassign) |
121
- | **Ternary `?:`** | `x > 0 ? 'yes' : 'no'` | JS-style ternary (plus CoffeeScript's if/then/else) |
122
- | **Dual optional** | `a?.b` and `a?[0]` | Both ES6 native and CoffeeScript soak styles |
123
-
124
- ### Regex Enhancements
125
-
126
- | Feature | Example | What it does |
127
- |---------|---------|--------------|
128
- | **Match `=~`** | `str =~ /(\w+)/` | Ruby-style regex, captures in `_[1]` |
129
- | **Regex index** | `str[/pat/, 1]` | Extract capture group directly |
130
- | **Heregex** | `///pat # comment///` | Extended regex with comments and whitespace |
131
-
132
- ### Strings & Data
133
-
134
- | Feature | Example | What it does |
135
- |---------|---------|--------------|
136
- | **Heredoc** | `'''` closing column | Smart indentation — closing position sets left margin |
137
- | **`__DATA__`** | `__DATA__\nconfig...` | Ruby-style inline data section, accessible as `DATA` |
138
-
139
- ### Reactivity (Built-in)
140
-
141
- | Feature | Example | What it does |
142
- |---------|---------|--------------|
143
- | **Signal `:=`** | `count := 0` | Creates reactive state container |
144
- | **Derived `~=`** | `doubled ~= count * 2` | Auto-updates when dependencies change |
145
- | **Effect** | `effect -> log x` | Runs whenever referenced signals change |
146
-
147
- ### Components & Templates
148
-
149
- | Feature | Example | What it does |
150
- |---------|---------|--------------|
151
- | **Component** | `component Counter` | Define reactive UI component |
152
- | **Render** | `render` block | Indentation-based HTML templates |
153
- | **Props** | `@prop`, `@prop?`, `@prop = default` | Component input from parent |
154
- | **Rest props** | `@...rest` | Capture remaining props |
155
- | **Two-way bind** | `input value <=> name` | Bidirectional data binding |
156
- | **Event handlers** | `@click: handler` | DOM event binding |
157
- | **Lifecycle** | `mounted:`, `unmounted:` | Component lifecycle hooks |
158
- | **Context API** | `setContext`, `getContext` | Pass data down component tree |
159
- | **Fine-grained** | No virtual DOM | Surgical DOM updates via signals |
160
-
161
- **→ 26 major enhancements over CoffeeScript!**
98
+ State, computed values, and effects as language operators:
162
99
 
163
- ---
100
+ | Operator | Mnemonic | Example | What it does |
101
+ |----------|----------|---------|--------------|
102
+ | `=` | "gets value" | `x = 5` | Regular assignment |
103
+ | `:=` | "has state" | `count := 0` | Reactive state container |
104
+ | `~=` | "always equals" | `twice ~= count * 2` | Auto-updates on changes |
105
+ | `~>` | "reacts to" | `~> log count` | Runs on dependency changes |
106
+ | `=!` | "equals, dammit!" | `MAX =! 100` | Readonly constant |
164
107
 
165
- ## Reactivity
108
+ ---
166
109
 
167
- Built into the language, not a library:
110
+ ## New Operators
168
111
 
169
- ```coffee
170
- # Signals hold reactive state
171
- count := 0
172
- name := "world"
112
+ | Operator | Example | What it does |
113
+ |----------|---------|--------------|
114
+ | `!` (dammit) | `fetchData!` | Calls AND awaits |
115
+ | `!` (void) | `def process!` | Suppresses implicit return |
116
+ | `!?` (otherwise) | `val !? 5` | Default only if `undefined` |
117
+ | `?:` (ternary) | `x > 0 ? 'yes' : 'no'` | JS-style ternary expression |
118
+ | `?.` `?[]` | `a?.b` `a?[0]` | Optional chaining (both styles) |
119
+ | `...` (spread) | `[...rest, last]` | Spread at start or end (JS: end only) |
120
+ | `//` | `7 // 2` | Floor division → 3 |
121
+ | `%%` | `-1 %% 3` | True modulo → 2 |
122
+ | `=~` | `str =~ /Hello, (\w+)/` | Match (captures in `_`) |
123
+ | `[//, n]` | `str[/Hello, (\w+)/, 1]` | Extract capture n |
124
+ | `.new()` | `Dog.new()` | Ruby-style constructor |
173
125
 
174
- # Derived values auto-update
175
- doubled ~= count * 2
176
- greeting ~= "Hello, #{name}!"
126
+ **Optional chaining** Both CoffeeScript and ES6 styles are supported:
177
127
 
178
- # Effects run when dependencies change
179
- effect -> console.log greeting
128
+ | Syntax | Style | Compiles to |
129
+ |--------|-------|-------------|
130
+ | `obj?[0]` | CoffeeScript | `(obj != null ? obj[0] : undefined)` |
131
+ | `fn?(arg)` | CoffeeScript | `(typeof fn === 'function' ? fn(arg) : undefined)` |
132
+ | `obj?.[0]` | ES6/JS | `obj?.[0]` |
133
+ | `fn?.(arg)` | ES6/JS | `fn?.(arg)` |
180
134
 
181
- name = "Rip" # Effect runs → "Hello, Rip!"
182
- count = 5 # Nothing (greeting doesn't depend on count)
183
- ```
135
+ ### Heredoc & Heregex
184
136
 
185
- [Full reactivity guide →](docs/REACTIVITY.md)
137
+ **Heredoc** The closing `'''` position sets the left margin (smart dedent):
186
138
 
187
- ---
188
-
189
- ## Components
139
+ ```coffee
140
+ html = '''
141
+ <div>
142
+ <p>Hello</p>
143
+ </div>
144
+ '''
145
+ # Result: " <div>\n <p>Hello</p>\n </div>" (note the leading 2 spaces)
146
+ ```
190
147
 
191
- Build reactive UIs with fine-grained DOM updates:
148
+ **Heregex** Extended regex with comments and whitespace:
192
149
 
193
150
  ```coffee
194
- component Counter
195
- @label = "Count"
196
- count := 0
197
- inc: -> count += 1
198
- dec: -> count -= 1
199
-
200
- render
201
- div.counter
202
- h2 @label
203
- span.value count
204
- button @click: @inc, "+"
205
- button @click: @dec, "−"
151
+ pattern = ///
152
+ ^(\d{3}) # area code
153
+ -(\d{4}) # number
154
+ ///
206
155
  ```
207
156
 
208
- **Event handlers** — two patterns:
209
- ```coffee
210
- # Normal: define methods, reference with @
211
- inc: -> count += 1
212
- button @click: @inc, "+"
157
+ ---
213
158
 
214
- # Compact: inline with fat arrow (parens required)
215
- button (@click: => @count++), "+"
216
- ```
159
+ ## vs React / Vue / Solid
217
160
 
218
- **Features:**
219
- - Props: `@prop`, `@prop?` (optional), `@prop = default`
220
- - Lifecycle: `mounted:`, `unmounted:`
221
- - Context API: `setContext`, `getContext`
222
- - Fine-grained updates: only changed nodes update, no virtual DOM
161
+ | Concept | React | Vue | Solid | Rip |
162
+ |---------|-------|-----|-------|-----|
163
+ | State | `useState()` | `ref()` | `createSignal()` | `x := 0` |
164
+ | Computed | `useMemo()` | `computed()` | `createMemo()` | `x ~= y * 2` |
165
+ | Effect | `useEffect()` | `watch()` | `createEffect()` | `~> body` |
223
166
 
224
- [Component guide →](docs/COMPONENTS.md)
167
+ Rip's reactivity is framework-agnostic — use it with React, Vue, Svelte, or vanilla JS.
225
168
 
226
169
  ---
227
170
 
228
- ## Templates
171
+ ## vs CoffeeScript
229
172
 
230
- Indentation-based HTML with CSS-style selectors:
231
-
232
- ```coffee
233
- render
234
- div#app.container
235
- h1.title "Hello, #{name}!"
236
- input value: username, @input: updateName
237
- button.("btn", active && "primary") @click: submit
238
- "Submit"
239
- ul.items
240
- for item in items
241
- li key: item.id, item.name
242
- ```
173
+ | Feature | CoffeeScript | Rip |
174
+ |---------|--------------|-----|
175
+ | **Output** | ES5 (var, prototypes) | ES2022 (classes, `?.`, `??`) |
176
+ | **Reactivity** | None | Built-in |
177
+ | **Dependencies** | Multiple | Zero |
178
+ | **Self-hosting** | No | Yes |
179
+ | **Lexer** | 3,558 LOC | 3,250 LOC |
180
+ | **Compiler** | 10,346 LOC | 5,878 LOC |
181
+ | **Total** | 17,760 LOC | ~10,100 LOC |
243
182
 
244
- - `div#id.class1.class2` IDs and classes
245
- - `@click: @handler` — Event handlers (method reference)
246
- - `(@click: => @count++)` — Inline handlers (fat arrow, parens required)
247
- - `.("class1", cond && "class2")` — Dynamic classes (Tailwind-friendly)
248
- - `value <=> var` — Two-way binding
249
-
250
- [Template guide →](docs/TEMPLATES.md)
183
+ Smaller codebase, modern output, built-in reactivity.
251
184
 
252
185
  ---
253
186
 
254
- ## Browser Support
255
-
256
- Run Rip directly in the browser (51KB compressed—complete language + reactive framework).
187
+ ## Browser
257
188
 
258
- **Try it live:** [https://shreeve.github.io/rip-lang/](https://shreeve.github.io/rip-lang/)
189
+ Run Rip directly in the browser (51KB compressed):
259
190
 
260
191
  ```html
261
192
  <script src="https://shreeve.github.io/rip-lang/docs/dist/rip.browser.min.js"></script>
@@ -266,78 +197,50 @@ Run Rip directly in the browser (51KB compressed—complete language + reactive
266
197
  </script>
267
198
  ```
268
199
 
269
- ```bash
270
- bun run browser # Build the bundle
271
- bun run serve # Start dev server at localhost:3000
272
- ```
200
+ **Try it live:** [shreeve.github.io/rip-lang](https://shreeve.github.io/rip-lang/)
273
201
 
274
202
  ---
275
203
 
276
- ## Modernizing What CoffeeScript Started
277
-
278
- CoffeeScript showed us beautiful syntax. Rip takes that vision further:
279
-
280
- | | Rip | CoffeeScript |
281
- |---|---|---|
282
- | **Output** | ES2022 (classes, `?.`, `??`) | ES5 (var, prototypes) |
283
- | **Reactivity** | Built-in (signals, effects, templates) | None |
284
- | **Dependencies** | Zero | Multiple |
285
- | **Self-hosting** | Yes (compiles itself) | No |
286
- | **Codebase** | ~14,000 LOC | 17,760 LOC |
287
-
288
- ---
289
-
290
- ## Why S-Expressions?
291
-
292
- Traditional compilers use complex AST node classes. Rip uses simple arrays:
204
+ ## Architecture
293
205
 
294
206
  ```
295
207
  Source → Lexer → Parser → S-Expressions → Codegen → JavaScript
296
208
  ["=", "x", 42]
297
209
  ```
298
210
 
299
- **Traditional AST:**
300
- ```javascript
301
- class BinaryOp {
302
- constructor(op, left, right) { ... }
303
- compile() { /* 50 lines */ }
304
- }
305
- ```
306
-
307
- **Rip's approach:**
308
- ```javascript
309
- case '+': return `(${gen(left)} + ${gen(right)})`;
310
- ```
211
+ Simple arrays instead of AST node classes. The compiler is self-hosting — `bun run parser` rebuilds from source.
311
212
 
312
- | Component | CoffeeScript | Rip |
313
- |-----------|--------------|-----|
314
- | Lexer | 3,558 LOC | 3,537 LOC |
315
- | Parser Generator | 2,285 LOC (Jison) | ~1,000 LOC (Solar) |
316
- | Compiler | 10,346 LOC | 7,965 LOC |
317
- | **Total** | **17,760 LOC** | **~14,000 LOC** |
213
+ ---
318
214
 
319
- Result: Smaller than CoffeeScript, yet includes a complete **reactive framework** with signals, derived values, effects, templates, and components.
215
+ ## The Rip Stack
320
216
 
321
- ---
217
+ Rip includes optional packages for full-stack development:
322
218
 
323
- ## Runtime Compatibility
219
+ | Package | Purpose | Lines |
220
+ |---------|---------|-------|
221
+ | [@rip-lang/api](packages/api/) | Web framework (Sinatra-style) | ~595 |
222
+ | [@rip-lang/server](packages/server/) | Multi-worker process manager | ~1,110 |
223
+ | [@rip-lang/db](packages/db/) | DuckDB HTTP server | ~225 |
224
+ | [@rip-lang/schema](packages/schema/) | ORM with reactive models | ~420 |
324
225
 
325
- **Runs everywhere:** Bun (first-class), Node.js 12+, Deno, modern browsers.
226
+ ```bash
227
+ bun add @rip-lang/api @rip-lang/server
228
+ ```
326
229
 
327
- Output uses ES2022: classes, `let`/`const`, `?.`, `??`, `for await`, top-level await.
230
+ [Full stack documentation →](packages/README.md)
328
231
 
329
232
  ---
330
233
 
331
234
  ## Quick Reference
332
235
 
333
236
  ```bash
334
- rip # Interactive REPL
335
- rip file.rip # Run a file
336
- rip -c file.rip # Compile to JavaScript
337
- rip -s file.rip # Show S-expressions (debug parser)
338
- rip -t file.rip # Show tokens (debug lexer)
339
- bun run test # Run all 1033 tests
340
- bun run parser # Rebuild parser (self-hosting!)
237
+ rip # REPL
238
+ rip file.rip # Run
239
+ rip -c file.rip # Compile
240
+ rip -t file.rip # Tokens
241
+ rip -s file.rip # S-expressions
242
+ bun run test # 979 tests
243
+ bun run parser # Rebuild parser
341
244
  bun run browser # Build browser bundle
342
245
  ```
343
246
 
@@ -347,12 +250,11 @@ bun run browser # Build browser bundle
347
250
 
348
251
  | Guide | Description |
349
252
  |-------|-------------|
350
- | [AGENT.md](AGENT.md) | Complete developer/AI guide |
351
- | [docs/REACTIVITY.md](docs/REACTIVITY.md) | Signals, effects, derived values |
352
- | [docs/COMPONENTS.md](docs/COMPONENTS.md) | Component system |
353
- | [docs/TEMPLATES.md](docs/TEMPLATES.md) | Template DSL |
253
+ | [docs/GUIDE.md](docs/GUIDE.md) | Language guide |
254
+ | [docs/REACTIVITY.md](docs/REACTIVITY.md) | Reactivity deep dive |
255
+ | [docs/INTERNALS.md](docs/INTERNALS.md) | Compiler architecture |
256
+ | [packages/](packages/README.md) | Full-stack packages |
354
257
  | [CONTRIBUTING.md](CONTRIBUTING.md) | How to contribute |
355
- | [CHANGELOG.md](CHANGELOG.md) | Version history |
356
258
 
357
259
  ---
358
260
 
@@ -362,7 +264,7 @@ bun run browser # Build browser bundle
362
264
  { "dependencies": {} }
363
265
  ```
364
266
 
365
- Everything included: compiler, parser generator (solar.rip), REPL, browser bundle, test framework. Rip compiles itself — `bun run parser` rebuilds from source.
267
+ Everything included: compiler, parser generator, REPL, browser bundle, test framework.
366
268
 
367
269
  ---
368
270
 
@@ -370,24 +272,12 @@ Everything included: compiler, parser generator (solar.rip), REPL, browser bundl
370
272
 
371
273
  > *Simplicity scales.*
372
274
 
373
- Keep the IR simple (S-expressions), keep the pipeline clear (lex → parse → generate), keep the code minimal. Test everything.
275
+ Simple IR (S-expressions), clear pipeline (lex → parse → generate), minimal code, comprehensive tests.
374
276
 
375
277
  ---
376
278
 
377
- ## Credits
279
+ **Inspired by:** CoffeeScript, Lisp, Ruby | **Powered by:** [Bun](https://bun.sh)
378
280
 
379
- **Inspired by:** CoffeeScript (syntax), Lisp/Scheme (S-expressions), Ruby (regex operators, `__DATA__`), Solar (parser generator).
380
-
381
- **Powered by:** [Bun](https://bun.sh) — the fast all-in-one JavaScript runtime.
382
-
383
- ---
281
+ MIT License
384
282
 
385
- ## License
386
-
387
- MIT
388
-
389
- ---
390
-
391
- <p align="center">
392
- <strong>Start simple. Build incrementally. Ship elegantly.</strong> ✨
393
- </p>
283
+ <p align="center"><strong>Start simple. Build incrementally. Ship elegantly.</strong></p>
package/docs/BROWSER.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # Rip in the Browser
4
4
 
5
- **Complete Language + Reactive Framework in 51KB**
5
+ **Complete Language + Reactive Runtime in 51KB**
6
6
 
7
- Rip compiles to modern JavaScript and runs beautifully in the browser. With brotli compression, the entire package—compiler, reactive runtime, template engine, and component system—fits in just **51KB**. That's a complete framework in less space than most utility libraries!
7
+ Rip compiles to modern JavaScript and runs beautifully in the browser. With brotli compression, the entire package—compiler and reactive runtime—fits in just **51KB**. That's a complete language in less space than most utility libraries!
8
8
 
9
9
  ---
10
10
 
@@ -18,16 +18,14 @@ rip.browser.min.js.br 51 KB (brotli, 91% smaller!)
18
18
 
19
19
  **What's in that 51KB?**
20
20
  - Complete compiler (lexer, parser, code generator)
21
- - Reactive runtime (signals, derived values, effects)
22
- - Template engine (S-expression syntax, dynamic classes)
23
- - Component system (props, lifecycle, fine-grained updates)
21
+ - Reactive runtime (state, computed values, effects)
24
22
  - Zero dependencies
25
23
 
26
24
  **For comparison:**
27
25
  - React (min+gzip): ~42KB (just the library, no compiler)
28
26
  - Vue (min+gzip): ~34KB (just the library, no compiler)
29
27
  - Svelte: ~2KB runtime (but requires build step + compiler)
30
- - **Rip: 51KB (complete language + framework, runs anywhere!)**
28
+ - **Rip: 51KB (complete language + reactive runtime, runs anywhere!)**
31
29
 
32
30
  ---
33
31
 
@@ -900,11 +898,10 @@ See the `docs/examples/` directory for working demos:
900
898
  - More features than most frameworks, smaller than most libraries
901
899
  - Fast loading even on mobile
902
900
 
903
- **2. Complete Framework**
904
- - Reactive primitives (signals, derived, effects)
905
- - S-expression templates with fine-grained updates
906
- - Component system with props and lifecycle
901
+ **2. Complete Language**
902
+ - Reactive primitives (state, computed, effects)
907
903
  - Modern ES6+ output
904
+ - Framework-agnostic — use with any UI library
908
905
 
909
906
  **3. Zero Build Step**
910
907
  - Write Rip directly in HTML
@@ -965,7 +962,7 @@ Then serve `node_modules/rip-lang/dist/rip.browser.min.js`
965
962
  **Rip in the browser gives you:**
966
963
 
967
964
  ✅ **51KB** - Complete language + reactive framework (brotli)
968
- ✅ **Reactivity** - Signals, derived values, effects
965
+ ✅ **Reactivity** - State, computed values, effects
969
966
  ✅ **Templates** - S-expression syntax, fine-grained DOM updates
970
967
  ✅ **Components** - Props, lifecycle, zero virtual DOM
971
968
  ✅ **Triple REPL** - Terminal, Browser, Console