Skip to content

Flexium Showcase

Experience the power of Flexium's fine-grained reactivity directly in your browser. All demos below are running live, powered by the core flexium library.

Real-World Examples

Check out these full applications built with Flexium:



Counter Demo

A simple counter demonstrating state() and computed() - the building blocks of Flexium reactivity.

View Source Code
tsx
import { state } from 'flexium/core'
import { Column, Row, Text, Pressable } from 'flexium/primitives'

function Counter() {
  const [count, setCount] = state(0)
  const [doubled] = state(() => count * 2)  // derived value

  return (
    <Column gap={16} padding={24}>
      <Text style={{ fontSize: '72px', fontWeight: 'bold' }}>
        {count}
      </Text>
      <Text>Doubled: {doubled}</Text>
      <Row gap={12}>
        <Pressable onPress={() => setCount(c => c - 1)}>
          <Text style={buttonStyle}>- Decrement</Text>
        </Pressable>
        <Pressable onPress={() => setCount(0)}>
          <Text style={buttonStyle}>Reset</Text>
        </Pressable>
        <Pressable onPress={() => setCount(c => c + 1)}>
          <Text style={buttonStyle}>+ Increment</Text>
        </Pressable>
      </Row>
    </Column>
  )
}

Todo List Demo

A fully functional todo list with add, toggle, and delete operations. Shows how Flexium handles list state and dynamic rendering.

View Source Code
tsx
import { state } from 'flexium/core'
import { Column, Row, Text, Pressable } from 'flexium/primitives'

function TodoApp() {
  const [todos, setTodos] = state([
    { id: 1, text: 'Learn Flexium', done: true },
    { id: 2, text: 'Build something awesome', done: false }
  ])
  const [inputText, setInputText] = state('')

  const addTodo = () => {
    if (!inputText.trim()) return
    setTodos(prev => [...prev, {
      id: Date.now(),
      text: inputText,
      done: false
    }])
    setInputText('')
  }

  const toggleTodo = (id) => {
    setTodos(prev => prev.map(t =>
      t.id === id ? { ...t, done: !t.done } : t
    ))
  }

  return (
    <Column gap={16}>
      <Row gap={8}>
        <input
          value={inputText}
          oninput={(e) => setInputText(e.target.value)}
          placeholder="Add a new todo..."
        />
        <Pressable onPress={addTodo}>
          <Text>Add</Text>
        </Pressable>
      </Row>

      {todos.map(todo => (
        <Row key={todo.id} gap={8} style={{ alignItems: 'center' }}>
          <input
            type="checkbox"
            checked={todo.done}
            onchange={() => toggleTodo(todo.id)}
          />
          <Text style={{
            textDecoration: todo.done ? 'line-through' : 'none'
          }}>
            {todo.text}
          </Text>
        </Row>
      ))}
    </Column>
  )
}

Stopwatch Demo

A precise stopwatch with lap recording. Demonstrates timer-based state updates and list management.

View Source Code
tsx
import { state, effect } from 'flexium/core'
import { Column, Row, Text, Pressable } from 'flexium/primitives'

function Stopwatch() {
  const [seconds, setSeconds] = state(0)
  const [isRunning, setIsRunning] = state(false)
  const [laps, setLaps] = state([])

  // Format time display
  const formatTime = (s) => {
    const mins = Math.floor(s / 60)
    const secs = Math.floor(s % 60)
    const ms = Math.floor((s % 1) * 100)
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms.toString().padStart(2, '0')}`
  }

  let intervalId
  const startStop = () => {
    if (isRunning) {
      clearInterval(intervalId)
      setIsRunning(false)
    } else {
      setIsRunning(true)
      intervalId = setInterval(() => {
        setSeconds(s => s + 0.01)
      }, 10)
    }
  }

  return (
    <Column gap={16}>
      <Text style={{ fontSize: '48px', fontFamily: 'monospace' }}>
        {() => formatTime(seconds)}
      </Text>

      <Row gap={8}>
        <Pressable onPress={startStop}>
          <Text style={{ background: isRunning ? 'red' : 'green' }}>
            {isRunning ? 'Stop' : 'Start'}
          </Text>
        </Pressable>
        <Pressable onPress={() => setLaps(prev => [seconds, ...prev])}>
          <Text>Lap</Text>
        </Pressable>
        <Pressable onPress={() => { setSeconds(0); setLaps([]) }}>
          <Text>Reset</Text>
        </Pressable>
      </Row>

      {laps.map((lap, i) => (
        <Text key={i}>Lap {i + 1}: {formatTime(lap)}</Text>
      ))}
    </Column>
  )
}

Canvas Animation Demo

Interactive canvas with particle trail effects. Move your mouse to see smooth, reactive canvas rendering.

View Source Code
tsx
import { state, effect } from 'flexium/core'
import { Canvas, DrawCircle } from 'flexium/canvas'

function ParticleCanvas() {
  const [mouseX, setMouseX] = state(150)
  const [mouseY, setMouseY] = state(150)
  const [hue, setHue] = state(0)
  const [particles, setParticles] = state([])

  // Animate hue
  effect(() => {
    const id = setInterval(() => setHue(h => (h + 1) % 360), 16)
    return () => clearInterval(id)
  })

  const handleMouseMove = (e) => {
    const rect = e.target.getBoundingClientRect()
    const x = e.clientX - rect.left
    const y = e.clientY - rect.top

    setMouseX(x)
    setMouseY(y)
    setParticles(prev => [...prev.slice(-20), { x, y, hue }])
  }

  return (
    <Canvas
      width={300}
      height={300}
      onmousemove={handleMouseMove}
      style={{ background: '#1a1a2e', cursor: 'crosshair' }}
    >
      {/* Particle trail */}
      {particles.map((p, i) => (
        <DrawCircle
          key={i}
          x={p.x}
          y={p.y}
          radius={10 * ((i + 1) / particles.length)}
          fill={`hsla(${p.hue}, 70%, 60%, ${(i + 1) / particles.length})`}
        />
      ))}

      {/* Main cursor circle */}
      <DrawCircle
        x={mouseX}
        y={mouseY}
        radius={20}
        fill={() => `hsl(${hue}, 70%, 60%)`}
      />
    </Canvas>
  )
}

Snake Game Demo

A complete game built with Flexium's game module. Use arrow keys or WASD to control the snake!

View Source Code
tsx
import { state, effect } from 'flexium/core'
import { mount } from 'flexium/dom'
import { Canvas, DrawRect } from 'flexium/canvas'
import { keyboard, createLoop, Keys } from 'flexium/interactive'

const [snake, setSnake] = state([{ x: 7, y: 7 }])
const [direction, setDirection] = state('RIGHT')
const [food, setFood] = state({ x: 12, y: 7 })
const [score, setScore] = state(0)

function SnakeGame() {
  const kb = keyboard()

  const loop = createLoop({
    onUpdate: (delta) => {
      // Handle input and move snake
      moveSnake()
    }
  })

  effect(() => {
    loop.start()
    return () => loop.stop()
  })

  return (
    <Canvas width={300} height={300}>
      {/* Render food */}
      <DrawRect x={food().x * 20} y={food().y * 20}
                width={20} height={20} fill="#e74c3c" />

      {/* Render snake */}
      {snake().map((segment, i) => (
        <DrawRect x={segment.x * 20} y={segment.y * 20}
                  width={20} height={20} fill={i === 0 ? '#27ae60' : '#2ecc71'} />
      ))}
    </Canvas>
  )
}

Context API Demo

Authentication, shopping cart, and notifications with multiple providers working together.

View Source Code
tsx
import { state } from 'flexium/core'

// Auth state - shared globally
function useAuth() {
  const [user, setUser] = state(null, { key: 'app:auth:user' })
  
  const login = (name: string) => {
    setUser({ name })
  }
  
  const logout = () => {
    setUser(null)
  }
  
  return { user, login, logout }
}

// Cart state - shared globally
function useCart() {
  const [items, setItems] = state<Array<{id: number, name: string, price: number, qty: number}>>([], { key: 'app:cart:items' })
  
  const addItem = (product: {id: number, name: string, price: number}) => {
    setItems(items => {
      const existing = items.find(item => item.id === product.id)
      if (existing) {
        return items.map(item => item.id === product.id ? {...item, qty: item.qty + 1} : item)
      }
      return [...items, {...product, qty: 1}]
    })
  }
  
  const removeItem = (id: number) => {
    setItems(items => items.filter(item => item.id !== id))
  }
  
  const updateQty = (id: number, delta: number) => {
    setItems(items => items.map(item => item.id === id ? {...item, qty: item.qty + delta} : item))
  }
  
  const [total] = state(() => items.reduce((sum, item) => sum + item.price * item.qty, 0), { key: 'app:cart:total' })
  
  return { items, addItem, removeItem, updateQty, total }
}

// Notification state - shared globally
function useNotifications() {
  const [notifications, setNotifications] = state<Array<{msg: string, type: string}>>([], { key: 'app:notifications' })
  
  const notify = (msg: string, type: string) => {
    setNotifications(n => [...n, { msg, type }])
    setTimeout(() => {
      setNotifications(n => n.slice(1))
    }, 3000)
  }
  
  return { notifications, notify }
}

function App() {
  return <Shop />
}

function Shop() {
  const { user, login, logout } = useAuth()
  const { items, addItem, total } = useCart()
  const { notify } = useNotifications()

  const products = [
    { id: 1, name: 'Flexium Pro', price: 99 },
    { id: 2, name: 'Signal Pack', price: 49 }
  ]

  return (
    <div>
      {user() ? (
        <button onclick={logout}>Logout</button>
      ) : (
        <button onclick={() => login('Alice')}>Login</button>
      )}

      {products.map(product => (
        <button
          key={product.id}
          onclick={() => {
            addItem(product)
            notify(`Added ${product.name}`, 'success')
          }}
          disabled={!user()}
        >
          Add {product.name} - ${product.price}
        </button>
      ))}

      <div>Cart Total: ${total()}</div>
    </div>
  )
}

Why These Demos Matter

Unlike React or Vue, Flexium does not use a Virtual DOM for updates. When you interact with these demos:

  1. Only the changed values update - The component function does NOT re-run
  2. Direct DOM manipulation - Signals update the DOM directly via subscriptions
  3. Computed values are cached - They only recalculate when dependencies change
  4. No diffing overhead - Updates are surgical and precise

Performance Characteristics

AspectFlexiumVirtual DOM Frameworks
Update MechanismDirect signal subscriptionTree diffing
Component Re-rendersNever (after initial)On every state change
MemoryMinimal (no virtual tree)Maintains virtual tree copy
Bundle Size~3KB30-100KB+

Framework Interop

All these Flexium demos are actually running inside Vue components (VitePress)! Flexium's minimal footprint and DOM-based approach makes it easy to embed in any environment.


Explore the Docs

Each documentation page now includes live demos. Here are some highlights:


Build Your Own

Ready to create something? Browse the API Docs with live demos on every page, or dive into the Quick Start guide to begin building.

Last updated:

Released under the MIT License.