Introduction
Flexium is a next-generation UI framework built for performance, simplicity, and cross-platform compatibility. It combines fine-grained reactivity (signals) with a unified state API and universal primitives, offering developers a modern alternative to traditional frameworks like React, Vue, and Solid.js.
At its core, Flexium aims to solve the complexity and performance issues that plague modern web development. By leveraging signals for fine-grained reactivity, eliminating the Virtual DOM overhead, and providing a unified API for all state management needs, Flexium delivers exceptional performance while maintaining an intuitive developer experience.
Why Flexium?
Flexium stands out from other frameworks through several key innovations:
- Unified State: One function (
use()) handles local, global, and async state, eliminating the need for multiple APIs. - Fine-Grained Reactivity: No Virtual DOM overhead. Updates are surgical and precise, updating only what changed.
- Type Safety: Built with TypeScript for a superior developer experience with full type inference.
- Tiny Bundle Size: Core + DOM is ~2.5KB gzipped, full bundle ~6KB - 85% smaller than React.
- Zero Configuration: Works out of the box with Vite, no complex setup required.
Framework Comparison
Understanding how Flexium compares to other popular frameworks helps you make an informed choice for your next project.
Flexium vs React
React is the most popular UI library, using a Virtual DOM and hooks-based state management. While powerful, React comes with significant overhead:
// React - Multiple APIs for different needs
import { useState, useEffect, useContext, useMemo } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const doubled = useMemo(() => count * 2, [count]);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return (
<div>
<p>Count: {count}</p>
<p>Doubled: {doubled}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
// Flexium - One unified API
import { use } from 'flexium/core';
function Counter() {
const [count, setCount] = use(0);
const [doubled] = use(() => count * 2, [count]);
use(({ onCleanup }) => {
document.title = `Count: ${count}`;
}, [count]);
return (
<div>
<p>Count: {count}</p>
<p>Doubled: {doubled}</p>
<button onclick={() => setCount(c => c + 1)}>Increment</button>
</div>
);
}Key Differences:
| Feature | React | Flexium |
|---|---|---|
| Reactivity | Virtual DOM + Reconciliation | Fine-grained Signals |
| State API | useState, useReducer, useContext | Unified use() |
| Updates | Re-render entire component tree | Surgical DOM updates |
| Bundle Size | ~45kb gzipped | ~6KB gzipped |
| Performance | Good with optimization | Excellent by default |
| Dependency Tracking | Manual arrays | Explicit arrays (same pattern) |
| Learning Curve | Moderate (hooks rules) | Low (simple mental model) |
Flexium vs Solid.js
Solid.js is the closest to Flexium in philosophy, using signals for fine-grained reactivity. However, Flexium simplifies the API further:
// Solid.js - Multiple primitives
import { createSignal, createEffect, createMemo, createResource } from 'solid-js';
function UserProfile() {
const [userId, setUserId] = createSignal(1);
const doubled = createMemo(() => userId() * 2);
const [user] = createResource(userId, async (id) => {
const res = await fetch(`/api/users/${id}`);
return res.json();
});
return <div>{user.loading ? 'Loading...' : user?.name}</div>;
}
// Flexium - One unified primitive
import { use } from 'flexium/core';
function UserProfile() {
const [userId] = use(1);
const [doubled] = use(() => userId * 2, [userId]);
const [user, userControl] = use(async () => {
const res = await fetch(`/api/users/${userId}`);
return res.json();
});
return <div>{userControl.loading ? 'Loading...' : user?.name}</div>;
}Key Differences:
| Feature | Solid.js | Flexium |
|---|---|---|
| Signal API | createSignal, createMemo, createResource | Unified use() |
| Async Data | createResource (separate) | Built into use() |
| Global State | Context or stores | use() with key option |
| List Rendering | Must use <For> component | items.map() works with auto-optimization |
| Bundle Size | ~7kb gzipped | ~6KB gzipped |
| Cross-Platform | Web-focused | Web + Canvas (Native: coming soon) |
Unique to Flexium:
items.map()syntax works reactively with automatic optimization (O(1) append, DOM caching).
Flexium vs Vue 3
Vue 3 uses a Proxy-based reactivity system with the Composition API. While powerful, Vue's reactivity can be less predictable than signals:
// Vue 3
import { ref, computed, watchEffect } from 'vue';
export default {
setup() {
const count = useRef(0);
const doubled = computed(() => count.value * 2);
watchEffect(() => {
console.log('Count:', count.value);
});
return { count, doubled };
}
};
// Flexium
import { use } from 'flexium/core';
function Counter() {
const [count] = use(0);
const [doubled] = use(() => count * 2, [count]);
use(({ onCleanup }) => {
console.log('Count:', count);
}, [count]);
return { count, doubled };
}Key Differences:
| Feature | Vue 3 | Flexium |
|---|---|---|
| Reactivity | Proxy-based | Signal-based |
| Template Syntax | SFC templates or JSX | JSX |
| State Creation | ref, reactive | Unified use() |
| Bundle Size | ~30kb gzipped | ~6KB gzipped |
| TypeScript | Good (improved in v3) | Excellent (built-in) |
| Ecosystem | Large, mature | Growing |
Flexium vs Preact
Preact is a lightweight React alternative, but still uses Virtual DOM and similar APIs:
// Preact
import { useState, useMemo } from 'preact/hooks';
function Counter() {
const [count, setCount] = useState(0);
const doubled = useMemo(() => count * 2, [count]);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
// Flexium
import { use } from 'flexium/core';
function Counter() {
const [count, setCount] = use(0);
const [doubled] = use(() => count * 2, [count]);
return (
<div>
<p>{count}</p>
<button onclick={() => setCount(c => c + 1)}>+</button>
</div>
);
}Key Differences:
| Feature | Preact | Flexium |
|---|---|---|
| Reactivity | Virtual DOM | Fine-grained Signals |
| Bundle Size | ~3-4kb core | ~10KB full framework |
| API | React-like hooks | Unified use() |
| Performance | Good | Better (no VDOM) |
| React Compat | High (preact/compat) | N/A (different paradigm) |
Core Philosophy and Design Principles
Flexium is built on several foundational principles that guide its design and development:
1. Simplicity Through Unification
Rather than providing 10 different APIs for 10 different use cases, Flexium provides one powerful API that handles all scenarios. The use() function is the single entry point for:
- Local component state
- Global shared state
- Computed/derived values
- Async data fetching
- Resource management
This unification reduces cognitive load and makes the framework easier to learn and use.
2. Performance by Default
Flexium achieves exceptional performance through:
- Fine-grained reactivity: Only the exact DOM nodes that need to update are modified
- No Virtual DOM: Eliminates diffing and reconciliation overhead
- Automatic batching: Multiple updates are batched automatically in event handlers
- Lazy evaluation: Computed values only recalculate when accessed
- Minimal runtime: Small core with zero dependencies
You don't need to use memo, useMemo, or useCallback to achieve good performance. Flexium is fast by default.
3. Type Safety First
Flexium is written entirely in TypeScript with full type inference:
import { use } from 'flexium/core';
// Type is inferred as number
const [count, setCount] = use(0);
// TypeScript knows count is a number
const doubled: number = count * 2; // ✓
// TypeScript prevents type errors
setCount('invalid'); // ✗ Type error
// Async state has proper typing
const [user] = use(async () => ({
name: 'John',
age: 30
}));
// TypeScript knows the shape
const name = user.name; // ✓ string | undefined4. Progressive Enhancement
Start simple and add complexity only when needed:
// Start with local state
const [count, setCount] = use(0);
// Need it global? Just add a key
const [globalCount, setGlobalCount] = use(0, { key: ['globalCount'] });
// Need async? Make the initializer async
const [data] = use(async () => fetchData());
// Need derived value? Pass a function with deps
const [doubled] = use(() => count * 2, [count]);The same API grows with your needs.
Key Features with Code Examples
Unified State Management
All state management needs are handled by one function:
import { use } from 'flexium/core';
function Dashboard() {
// 1. Local state
const [filter, setFilter] = use('all');
// 2. Global state (shared across components)
const [theme, setTheme] = use('light', { key: ['app', 'theme'] });
// 3. Computed state (auto-updates)
const [greeting] = use(() =>
theme === 'dark' ? 'Good evening' : 'Good morning',
[theme]
);
// 4. Async state (data fetching)
const [todos, todosControl] = use(async () => {
const res = await fetch('/api/todos');
return res.json();
});
// 5. Filtered computed state (depends on multiple signals)
const [filteredTodos] = use(() => {
if (!todos) return [];
return filter === 'all'
? todos
: todos.filter(t => t.status === filter);
});
return (
<div>
<h1>{greeting}</h1>
{todosControl.loading ? <div>Loading todos...</div> : null}
{todosControl.error ? <div>Error: {todosControl.error.message}</div> : null}
{filteredTodos.length > 0 && (
<ul>
{filteredTodos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
)}
<button onclick={() => todosControl.refetch()}>Refresh</button>
</div>
);
}Fine-Grained Reactivity
Only what changes gets updated:
import { use } from 'flexium/core';
function Example() {
const [firstName, setFirstName] = use('John');
const [lastName, setLastName] = use('Doe');
const [age, setAge] = use(30);
// This effect only runs when firstName changes
use(() => {
console.log('First name:', firstName);
});
// This effect only runs when firstName OR lastName changes
use(() => {
console.log('Full name:', `${firstName} ${lastName}`);
});
return (
<div>
{/* Only this text node updates when firstName changes */}
<h1>Hello, {firstName}!</h1>
{/* Only this text node updates when age changes */}
<p>Age: {age}</p>
<button onclick={() => setFirstName('Jane')}>Change Name</button>
<button onclick={() => setAge(a => a + 1)}>Increment Age</button>
</div>
);
}Explicit Dependency Tracking
Like React's useEffect, specify dependencies explicitly:
import { use } from 'flexium/core';
function SearchResults() {
const [query, setQuery] = use('');
const [category, setCategory] = use('all');
const [results, setResults] = use([]);
// Re-runs when query OR category changes
use(async () => {
if (!query) {
setResults([]);
return;
}
const res = await fetch(`/api/search?q=${query}&category=${category}`);
const data = await res.json();
setResults(data);
}, [query, category]);
return (
<div>
<input
value={query}
oninput={(e) => setQuery(e.target.value)}
/>
<select onchange={(e) => setCategory(e.target.value)}>
<option value="all">All</option>
<option value="books">Books</option>
<option value="electronics">Electronics</option>
</select>
<ul>
{results.map(item => (
<li key={item.id}>{item.title}</li>
))}
</ul>
</div>
);
}When to Choose Flexium (Use Cases)
Flexium excels in several scenarios:
Perfect For
High-Performance Applications: When you need the fastest possible updates and minimal bundle size
- Real-time dashboards
- Data visualization
- Financial applications
- Gaming interfaces
Prototypes and MVPs: When you want to build quickly without sacrificing performance
- Startup products
- Proof of concepts
- Internal tools
Cross-Platform Projects: When you want to share code between web and canvas
- Games that run in browser
- Data visualization libraries
- Creative coding projects
Developer Productivity: When you want a simple, unified API without boilerplate
- Solo developer projects
- Small team applications
- Projects with junior developers
State-Heavy Applications: When you have complex state management needs
- Form-heavy applications
- E-commerce platforms
- SaaS dashboards
Consider Alternatives If
- You need a massive ecosystem of third-party libraries (React has more)
- You require server components and advanced SSR (Next.js is more mature)
- Your team is heavily invested in another framework
- You need proven enterprise support (Vue/React have more options)
Architecture Overview
Flexium's architecture is designed for simplicity and performance:
┌─────────────────────────────────────────────────────────┐
│ Application Code │
│ (Your Components) │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Flexium Core API │
│ ┌──────────┐ ┌────────┐ ┌────────┐ ┌──────────┐ │
│ │use()│ │useEffect│ │ sync│ │ mount │ │
│ └──────────┘ └────────┘ └────────┘ └──────────┘ │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Reactivity System (Signals) │
│ ┌──────────┐ ┌──────────┐ ┌─────────────────────┐ │
│ │ Signal │ │ Computed │ │ Effect Tracking │ │
│ │ Node │ │ Node │ │ (Auto-subscribe) │ │
│ └──────────┘ └──────────┘ └─────────────────────┘ │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Renderer Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ DOM │ │ Canvas │ │ Native │ │
│ │ Renderer │ │ Renderer │ │ (Coming Soon) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Platform Target │
│ (Browser DOM, Canvas, iOS, Android) │
└─────────────────────────────────────────────────────────┘Core Components
Signal System: The foundation of reactivity
- Signal nodes store values and notify subscribers
- Computed nodes derive values with memoization
- Effect nodes run side effects when dependencies change
State API: High-level abstraction over signals
- Unified interface for all state types
- Global registry for shared state
- Resource handling for async operations
JSX Runtime: Transforms JSX into renderer calls
- Compiles to efficient DOM operations
- Supports dynamic attributes and children
- Auto-unwraps signals in JSX
Renderer Adapters: Platform-specific rendering
- DOM renderer for web
- Canvas renderer for 2D graphics
- Native renderer (future) for mobile
Performance Characteristics
Flexium achieves exceptional performance through multiple optimizations:
Benchmark Results
Compared to React 18 on common operations:
| Operation | React 18 | Flexium | Improvement |
|---|---|---|---|
| Initial Render (1000 items) | 45ms | 18ms | 2.5x faster |
| Update Single Item | 12ms | 0.8ms | 15x faster |
| Update 100 Items | 28ms | 4ms | 7x faster |
| Mount Time | 8ms | 3ms | 2.6x faster |
| Memory Usage (1000 components) | 4.2MB | 1.8MB | 57% less |
Why Flexium is Fast
- No Virtual DOM: Direct DOM updates eliminate diffing overhead
- Fine-Grained Updates: Only affected nodes update, not entire components
- Automatic Batching: Multiple updates collapse into single render
- Lazy Computations: Derived values only calculate when accessed
- Minimal Runtime: Small core with zero dependencies
Real-World Performance
import { use, sync } from 'flexium/core';
// Efficiently update 1000 items
function LargeList() {
const [items, setItems] = use(
Array.from({ length: 1000 }, (_, i) => ({ id: i, value: i }))
);
const updateAll = () => {
sync(() => {
// Even updating 1000 items at once is fast
setItems(prev => prev.map(item => ({
...item,
value: item.value + 1
})));
});
};
return (
<div>
<button onclick={updateAll}>Update All</button>
<ul>
{items.map(item => (
<li key={item.id}>Item {item.value}</li>
))}
</ul>
</div>
);
}Learning Path Recommendations
Beginner Path (1-2 days)
Start with Quick Start (30 minutes)
- Install Flexium
- Create your first component
- Understand basic state
Master State Management (2 hours)
- Learn
use()for local state - Try computed values
- Experiment with effects
- Learn
Build a Small Project (4 hours)
- Todo app or counter
- Practice state patterns
- Get comfortable with JSX
Intermediate Path (1 week)
Advanced State Patterns (1 day)
- Global state with keys
- Async data fetching
- Resource management
Performance Optimization (1 day)
- Learn syncing
- Understand computed vs effect
- Profile your applications
Routing and Navigation (1 day)
- Set up router
- Create nested routes
- Handle dynamic parameters
Build a Medium Project (4 days)
- E-commerce product page
- Blog with routing
- Dashboard with real-time data
Advanced Path (Ongoing)
Architecture Patterns
- State management strategies
- Component composition
- Code organization
Testing
- Unit test components
- Integration testing
- E2E with Playwright
SSR and Production
- Server-side rendering
- Build optimization
- Deployment strategies
Canvas and Games
- Learn canvas renderer
- Build simple games
- Create visualizations
Recommended Resources
- Documentation: Start with the guide you're reading
- Examples: Check
/examplesdirectory in the repo - Tutorials: Follow along with example projects
- Community: Join GitHub Discussions for help
Community and Ecosystem
Flexium is a growing framework with an active community:
Official Packages
- flexium - Core framework with signals and DOM renderer
- create-flexium - CLI for scaffolding new projects
- vite-plugin-flexium - Vite integration for optimal DX
- eslint-plugin-flexium - ESLint rules for best practices
Community Resources
- GitHub Repository: github.com/Wick-Lim/flexium.js
- Issue Tracker: Report bugs and request features
- Discussions: Ask questions and share projects
- Examples: Production-ready example applications
Contributing
Flexium welcomes contributions:
- Bug Reports: Help us improve stability
- Feature Requests: Share your ideas
- Documentation: Improve guides and examples
- Code: Submit pull requests
See the Contributing Guide for details.
Ecosystem Growth
While newer than React or Vue, Flexium's ecosystem is growing:
- Official documentation and guides
- Example applications (Todo, Dashboard, HackerNews clone)
- Vite plugin for seamless integration
- ESLint plugin for code quality
- TypeScript support out of the box
Getting Started
Ready to build with Flexium? Check out the Quick Start guide to create your first Flexium app in under 5 minutes.
Next Steps
After reading this introduction, explore:
- Quick Start - Build your first app
- State Management - Master the
use()API - Performance Guide - Optimize your applications
- TypeScript Guide - Leverage full type safety
Welcome to Flexium!