๐ Rasen Design Philosophy โ
ใใใ (Rasen) โ Japanese for "Spiral". Inspired by the anime Tengen Toppa Gurren Lagann, where spiral energy represents the power to break through all limits.
Why Rasen? โ
Modern frontend frameworks are mature, but we've observed several fundamental issues:
1. Reinventing the Reactive Wheel โ
Vue, Solid, Signals... Reactive systems have been nearly perfected. As framework developers, we should let users choose "the best" rather than forcing them to accept yet another homegrown reactive solution.
2. The Overhead of Virtual DOM โ
VDOM adds unnecessary complexity in many scenarios. Direct manipulation is often simpler and more efficient.
3. The Cross-Platform Struggle โ
When you need to switch from HTML to Canvas to WebGL within the same context, existing frameworks offer little help. Cross-platform rendering shouldn't be this hard.
4. Frameworks Are Too Narrow โ
Why is React limited to DOM and React Native? Why is Vue confined to DOM? The realm of graphical rendering extends far beyond these boundaries.
Core Design: Dual Decoupling โ
Rasen's architecture is built on two fundamental decouplings:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ User Code โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Rasen Core (Paradigm) โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Reactive Runtime โ Render Target โ
โ Adapters โ Adapters โ
โ โโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Vue Reactivity โ โ โ DOM / Canvas / React Native โ โ
โ โ TC39 Signals โ โ โ HTML(SSR) / WebGL / ... โ โ
โ โ Any reactive โ โ โ Any mountable target... โ โ
โ โโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโReactive Decoupling โ
We don't create a new reactive system. Through the ReactiveRuntime interface, users choose freely:
// Use Vue's reactivity
import { createVueRuntime } from '@rasenjs/reactive-vue'
setReactiveRuntime(createVueRuntime())
// Or use TC39 Signals
import { createSignalsRuntime } from '@rasenjs/reactive-signals'
setReactiveRuntime(createSignalsRuntime())Render Target Decoupling โ
Through the unified MountFunction<Host> pattern, the same component paradigm renders to any target:
// DOM
const Button = () => div({ children: [...] })
// Canvas 2D
const Circle = () => circle({ x: 100, y: 100, radius: 50 })
// React Native
const Card = () => view({ style: {...}, children: [...] })
// HTML (SSR/SSG)
const Page = () => html({ children: [...] })Three-Phase Functions: Lifecycle as Closures โ
A Rasen component is a three-phase function, each phase corresponding to a lifecycle stage:
const Component = (props) => { // ๐ฆ Phase 1: Setup
// Initialize reactive state
const count = ref(0)
return (host) => { // ๐ Phase 2: Mount
// Mount to host, establish watchers
const stop = watch(() => count.value, (val) => {
// Update rendering
})
return () => { // ๐งน Phase 3: Unmount
// Cleanup resources
stop()
}
}
}Why This Design? โ
1. Closures Naturally Isolate โ Avoiding React's Stale Closure Problem
React Hooks' stale closure issue stems from function components re-executing on every render. Rasen's three-layer closure structure inherently avoids this โ each lifecycle phase has its own isolated closure scope.
2. Lifecycle Is Visible
No need to memorize useEffect dependency array rules. No need to understand when onMounted vs onUnmounted fires. The nested function structure directly expresses the lifecycle hierarchy.
3. Composition Over Inheritance
Components are functions. Functions compose freely. No classes, no extends, no mixins.
Self-Controlled Rendering: Components as Mounters โ
Traditional framework rendering flow:
Component declares tags โ Framework collects โ Framework schedules โ Framework operates hostRasen's rendering flow:
Component receives host โ Component decides how to mountHost Passes Down the Chain โ
The host isn't a black box inside the framework. It passes down the mount chain to every component:
// Primitive component: directly operates the host
const div = (props) => (host: HTMLElement) => {
const el = document.createElement('div')
host.appendChild(el)
// ...set attributes, events, children
return () => el.remove()
}
// Business component: appears as a single-layer function
const Counter = () => div({
children: [
span({ textContent: count }),
button({ onClick: increment, children: '+' })
]
})Unified Components โ
In Rasen, business components and primitive components have no fundamental difference. div, view, circle โ these "tags" are also component functions; they just encapsulate host operations.
Benefits:
- No distinction between "native components" and "custom components"
- Primitive component implementation is transparent, freely extensible
- Business components appear as single-layer functions (primitives encapsulate mount logic)
Minimal Core, Infinite Possibilities โ
Rasen's core code is extremely small โ nearly zero. Because what it delivers isn't code, but a paradigm.
The Essence of the Paradigm โ
type MountFunction<Host> = (host: Host) => (() => void) | undefinedAnything with a concept of "mount" and "unmount" can use Rasen's pattern:
| Render Target | Host Type | Examples |
|---|---|---|
| DOM | HTMLElement | div, span, button |
| Canvas 2D | CanvasRenderingContext2D | rect, circle, text |
| React Native | Container (Fabric) | view, text, image |
| HTML (SSR) | string[] | String concatenation |
| WebGL | WebGLRenderingContext | Shaders, meshes |
| Three.js | Scene | 3D objects |
| Terminal TUI | Terminal | Text interfaces |
| File Generation | FileWriter | Any file format |
Rasen has no boundaries โ because it's just a paradigm.
Positioning: Universal Graphical Rendering Paradigm for JS โ
Rasen isn't just another frontend framework.
Our vision spans the entire graphical rendering domain within JavaScript execution environments:
- DOM/HTML is just one of many render targets
- On par with Canvas, WebGL, React Native, Terminal
- Long-term goal: become the universal rendering layer for the JS ecosystem
โโโโโโโโโโโโโโโโโโโโโ
โ Rasen Paradigm โ
โโโโโโโโโโฌโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโ โโโโโโโโโโ โโโโโโโโโโ
โ DOM โ โ Canvas โ โ RN โ ...
โโโโโโโโโโ โโโโโโโโโโ โโโโโโโโโโComparison with Other Frameworks โ
| Feature | React | Vue | Solid | Rasen |
|---|---|---|---|---|
| Virtual DOM | โ | โ | โ | โ |
| Built-in Reactivity | โ (Hooks) | โ | โ | โ (Pluggable) |
| Cross Render Targets | Limited | โ | โ | โ Core Design |
| Closure Pitfalls | Common | Rare | Rare | Structurally Avoided |
| Core Size | Large | Medium | Small | Minimal |
| Learning Curve | Steep | Moderate | Moderate | Gentle |
Rasen doesn't aim to replace these frameworks โ it provides a lower-level, more flexible paradigm, letting developers choose freely based on their scenarios.
Summary โ
One Reactive Core, Multiple Render Targets
Rasen's core philosophy:
- Don't Reinvent Wheels โ Use the best existing reactive systems
- Don't Over-Engineer โ Abandon VDOM, operate directly
- Set No Boundaries โ Render to any mountable target
- Solve Closures with Closures โ Three-phase functions, clear lifecycle
- Paradigm Over Implementation โ Minimal core, infinite possibilities
Like the spiral energy in Tengen Toppa Gurren Lagann, Rasen pursues constant breakthrough โ breaking through framework boundaries, rendering limitations, and the very definition of frontend.