sinwan
v1.5.1
Published
A fast reactive UI library for JSX, fine-grained reactivity, SSR, and hydration.
Maintainers
Readme
Sinwan gives you signals, component lifecycle hooks, a direct DOM renderer, and a React-shaped JSX runtime without a virtual DOM.
Why Sinwan?
Sinwan combines the developer experience of React's JSX with the performance of fine-grained reactivity — no virtual DOM diffing, no reconciliation overhead. Signals drive surgical DOM updates directly.
- No virtual DOM — components return plain element trees; the renderer patches the DOM at the exact node that changed.
- Fine-grained reactivity —
signal,computed, andeffecttrack dependencies automatically. Only the effects that read a changed signal re-run. - React-compatible JSX — use the same JSX syntax, component props, and TypeScript types you already know.
jsxImportSource: "sinwan"and you're done. - SSR + hydration —
renderToString/streamPageon the server,hydrateon the client. Hydratable strings and streaming supported. - Single dependency — only
csstypeat runtime. No React, no Solid, no Vue.
Install
npm install sinwanbun add sinwanJSX Setup
Use the automatic JSX runtime:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "sinwan",
},
}Quick Start
import { cc } from "sinwan/component";
import { signal } from "sinwan/reactivity";
import { mount } from "sinwan/renderer";
const Counter = cc(() => {
const count = signal(0);
return <button onClick={() => (count.value += 1)}>Count: {count}</button>;
});
mount(Counter, document.getElementById("app")!);Features
- Fine-grained reactivity:
signal,computed,effect,batch,nextTick,untrack,on,observable - JSX runtime:
sinwan/jsx-runtimeandsinwan/jsx-dev-runtime - Components:
cc, lifecycle hooks, provide/inject,<Show>,<For>... - DOM renderer: reactive text, attributes, events, refs, namespaces, and cleanup
- Server rendering:
renderToString,streamPage, hydratable strings and streams - Hydration: reuse server-rendered DOM with
hydrate
SSR and Hydration
// Server
import { renderToHydratableString } from "sinwan/react";
const html = await renderToHydratableString(App, { initial: 5 });// Client
import { hydrate } from "sinwan/hydration";
hydrate(App, document.getElementById("app")!, { initial: 5 });Documentation
Development
bun test
bun run typecheck
bun run buildAuthor
Mohammed Ben Cheikh
License
MIT - see LICENSE.
