zenkai-js
v0.3.7
Published
A modern frontend library with signals-based reactivity, template strings syntax, and built-in routing + state management
Downloads
1,879
Maintainers
Readme
Zenkai
The code you read is the code that runs
A lightweight frontend library with signals-based reactivity, template string syntax, and built-in routing + state management.
Quick Start
# Create a new project
npx zenkai-js awaken my-app
cd my-app
npm run devWhy Zenkai?
The Problem with React
React is great, but it comes with complexity:
- Virtual DOM overhead - React maintains a virtual copy of the DOM and diffs it on every update
- Hooks rules - Must follow rules of hooks, can't use them in loops or conditions
- Build step required - Need Babel/Webpack/Vite to transpile JSX
- Large bundle size - React + ReactDOM is ~42KB gzipped
- Ecosystem fragmentation - Need separate packages for routing, state management
What Zenkai Does Differently
| Feature | React | Zenkai | |---------|-------|--------| | Reactivity | Virtual DOM diffing | Fine-grained signals | | Syntax | JSX (requires build) | Template strings (native JS) | | State | useState/useReducer hooks | Plain signals | | Routing | Separate package (react-router) | Built-in | | State Management | Separate package (Redux/Zustand) | Built-in | | Bundle Size | ~42KB (React + ReactDOM) | ~13KB (everything included) |
Honest Comparison
Where Zenkai is Better
1. Bundle Size
React ecosystem: ~68KB gzipped (React + ReactDOM + Router + Redux)
Zenkai: ~13KB gzipped (everything included)2. Mental Model
// React - Need to understand hooks, deps array, closure pitfalls
const [count, setCount] = useState(0)
useEffect(() => {
console.log(count) // Stale closure issues possible
}, [count]) // Must remember deps
// Zenkai - Just signals and effects
const count = signal(0)
effect(() => {
console.log(count()) // Always current, no deps array
})3. No Build Step Required
// Works directly in browser - template strings are native JavaScript
import { html, render } from 'zenkai-js/dom'
function App() {
return html`<h1>Hello World</h1>`
}Where React is Better
1. Ecosystem Size
- React: Massive ecosystem, thousands of libraries, component libraries
- Zenkai: New, limited ecosystem, fewer resources
2. Job Market
- React: Most demanded frontend skill, huge community
- Zenkai: New, no job market yet
3. Maturity
- React: Battle-tested by Facebook, 10+ years of development
- Zenkai: New, may have bugs, fewer contributors
4. Tooling
- React: Excellent DevTools, testing libraries, IDE support
- Zenkai: Basic DevTools, limited testing utilities
When to Use Zenkai
- Small to medium projects where bundle size matters
- Side projects and experiments where simplicity is valued
- Learning reactive programming concepts
- Performance-critical applications needing fine-grained updates
- Progressive enhancement - adding interactivity to existing pages
When to Stick with React
- Large enterprise applications with established patterns
- Teams where React expertise already exists
- Projects needing specific React libraries (complex component libraries, etc.)
- Job requirements - React is the safe choice
Core Concepts
Signals - Reactive State
import { signal, computed, effect } from 'zenkai-js'
// Create reactive values
const count = signal(0)
// Computed values (auto-update)
const doubled = computed(() => count() * 2)
// Side effects
effect(() => {
console.log(`Count is ${count()}`)
})
// Update
count.set(5)
count.update(n => n + 1)Template Strings - No JSX Needed
import { html, render } from 'zenkai-js/dom'
function Counter() {
const count = signal(0)
return html`
<div class="counter">
<h1>Count: ${count}</h1>
<button @click=${() => count.update(n => n + 1)}>
Increment
</button>
</div>
`
}
render(Counter, document.getElementById('app'))Built-in Router
import { createRouter, Link, useParams } from 'zenkai-js/router'
const router = createRouter({
routes: [
{ path: '/', component: Home },
{ path: '/users/:id', component: UserProfile },
{ path: '*', component: NotFound }
]
})
function UserProfile() {
const { id } = useParams()
return html`<h1>User ${id}</h1>`
}Built-in State Management
import { createStore } from 'zenkai-js/store'
const store = createStore({
state: { count: 0 },
actions: {
increment(state) { state.count++ }
},
computed: {
doubled: state => state.count * 2
}
})
store.actions.increment()API Reference
Core
| Function | Description |
|----------|-------------|
| signal(value) | Create reactive value |
| computed(fn) | Create derived value |
| effect(fn) | Run side effect |
| batch(fn) | Batch updates |
DOM
| Function | Description |
|----------|-------------|
| html\...`| Template literal |
|render(component, container)| Mount to DOM |
|@click=${fn}| Event binding |
|${signal}` | Reactive binding |
Router
| Function | Description |
|----------|-------------|
| createRouter(options) | Create router |
| useParams() | Get route params |
| navigate(path) | Programmatic navigation |
| Link | Navigation component |
Store
| Function | Description |
|----------|-------------|
| createStore(options) | Create store |
| store.state | Access state |
| store.actions | Dispatch actions |
| store.computed | Computed values |
Installation
# Using the CLI
npx zenkai-js awaken my-app
# Or install manually
npm install zenkai-jsProject Structure
my-app/
├── src/
│ ├── main.ts # Entry point
│ ├── App.ts # Root component
│ └── components/ # Components
├── index.html
├── package.json
└── vite.config.tsDevelopment
# Install dependencies
npm install
# Build library
npm run build
# Build CLI
npm run build:cli
# Run tests
npm testRoadmap
- [ ] Server-side rendering (SSR)
- [ ] More testing utilities
- [ ] Component library
- [ ] VS Code extension
- [ ] Better DevTools integration
- [ ] Documentation site
Contributing
Contributions are welcome! Please read our contributing guidelines.
License
MIT © Vignesh
Acknowledgments
Inspired by:
