Skip to content
🐍 Minimal JavaScript Framework
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Kobra API Stability npm bundle size (minified + gzip) npm GitHub

Minimal JavaScript framework

⚠️ Still under active development.

πŸ‘Œ Features

  • Efficient Virtual DOM diffing
  • Shared state across routes
  • Redux style state management
  • Simple API (only 3 methods)

πŸ’» Usage

import { h, Kobra } from 'kobra';

const app = new Kobra();

const initialState = {
  count: 0

/** @jsx h */
app.route('/hello/:name', (state, dispatch) => (
    <h1>Hello, {}</h1>
    <button onClick={() => dispatch({ type: 'INC' })}>+{state.count}</button>

app.use((state = initialState, action) => {
  switch (action.type) {
    case 'INC':
      return { ...state, count: state.count + 1 };
      return state;


Getting started

Install Dependencies

yarn add kobra
yarn add babel-preset-env babel-plugin-transform-react-jsx --dev

Setup .babelrc

  "presets": ["env"],
  "plugins": [["transform-react-jsx", { "pragma": "h" }]]


route(path: String, handler: Function)

Specify a view to be rendered on a path. The handler receives the state and actions as the arguments.

Route parameters will be passed through the state argument as state.params

use(reducer: Function)

The reducer initializes the state and defines how the actions create the next state. The reducer function receives state and action as the first two arguments.

The action requires the property type. A payload may be also be defined.

Note: The use method is optional if you do not need state or actions in your application. You may also use multiple reducers by calling the use method for each new reducer.

mount(selector: DOMNode)

Mount the application and start listening to route changes


A Kobra component is simply a function that you use within your views. Components receive props and children as arguments.

const Page = (props, children) => (
      <a href="#/">Home</a>
      <a href="#/about">about</a>

app.route('/', (state, dispatch) => (
  <Page title="Home">

Cloning Elements

Use the cloneElement function to clone and return a new Kobra component. The result will have new props shallowly merged in.

import { cloneElement } from 'kobra';

cloneElement(element, [props], [...children]);

Asynchronous actions

Async actions are accomplished by dispatching the action from within callback or promise of an async function.

const view = (state, dispatch) => (
  <h1 onClick={() => asyncChange(dispatch)}>{state.text || 'Loading...'}</h1>

const asyncChange = dispatch => {
  setTimeout(() => {
    dispatch({ type: 'UPDATE_TEXT', payload: { text: 'Loaded' } });
  }, 1000);


Kobra has support for both hash (default) and browser routing. Define the router type for your app in the Kobra constructor.

Hash routing

import { Kobra } from 'kobra';

const app = new Kobra({ router: 'hash' });

Hash routing is the easiest to get up and running. You can use anchor tags as you normally would, however it's necessary to include the # prefix.

<a href="#/about">About</a>

Browser history routing

import { Kobra, Link } from 'kobra';

const app = new Kobra({ router: 'history' });

When using the browser history router, import the Link component. It's important to use the Link component instead of anchor tags so that the application can correctly transition between page states.

import { Link } from 'kobra';

<Link to="/about">About</Link>

You can also use the route function to properly transition between pages.

import { route } from 'kobra';


Route Params

Route patterns are defined in the first argument in the route method. Parameters are denoted with the : prefix. Parameter values are passed into the view through the state.params object.

Lifecycle Hooks

Lifecycle hooks can be attacted to any DOM node. All hooks are placed inside the hook attribute.

Lifecycle Name When it gets called
mount when the node is being created
update when the node is being updated
<div hook={{ mount: () => console.log('mounted') }} />


# install deps

# run tests
yarn test

# build dist
yarn build

# release to npm
yarn publish



You can’t perform that action at this time.