Obsydian

A lightweight JavaScript framework for building reactive user interfaces

Features

Virtual DOM

Efficient updates with virtual DOM diffing

State Management

Simple and predictable state management with reducers

Component-Based

Build UIs with reusable components

Lightweight

Small footprint (~5KB minified)

Routing

Built-in hash-based routing system

Getting Started

CDN

import { createApp, o, oFragment } from 'https://unpkg.com/obsydian@latest'

NPM

npm install obsydian

Quick Example

import { createApp, o, oFragment } from 'obsydian'

const state = { count: 0 }

const reducers = {
    "increment": (state) => ({ ...state, count: state.count + 1 }),
    "decrement": (state) => ({ ...state, count: state.count - 1 })
}

function Counter(state, emit) {
    return oFragment([
        o('button', { on: { click: () => emit('decrement') }}, ['-']),
        o('span', {}, [state.count]),
        o('button', { on: { click: () => emit('increment') }}, ['+'])
    ])
}

createApp({ state, reducers, view: Counter }).mount(document.body)

Routing

Basic Routing

import { createApp, o, HashRouter, oFragment } from 'obsydian'

// Define routes
const router = new HashRouter([
  { path: "/", action: () => emit("set-filter", "all") },
  { path: "/users/:id", action: () => emit("load-user", router.params.id) }
]);

// Initialize router
await router.init();

Route Navigation

function NavBar(state, emit) {
  return o("nav", {}, [
    o("a", { 
      href: "#/",
      on: { click: () => router.navigateTo("/") }
    }, ["Home"]),
    o("a", { 
      href: "#/users/123",
      on: { click: () => router.navigateTo("/users/123") }
    }, ["User Profile"])
  ]);
}

TodoMVC Example with Routing

const router = new HashRouter([
  { path: "/", action: () => emit("set-filter", "all") },
  { path: "/active", action: () => emit("set-filter", "active") },
  { path: "/completed", action: () => emit("set-filter", "completed") }
]);

function FilterNav(state, emit) {
  return o("ul", { class: "filters" }, [
    o("li", {}, [
      o("a", { 
        href: "#/",
        class: state.filter === "all" ? "selected" : "",
        on: { click: () => router.navigateTo("/") }
      }, ["All"])
    ]),
    // ...more filter links
  ]);
}

Router Features

  • Hash-based routing (#/path)
  • Route parameters (/users/:id)
  • Query string support (?q=search)
  • Navigation methods (navigateTo, back, forward)
  • Route change subscriptions