Cerebral
make sense of complex apps
TRY THE DEMO
TUTORIAL
API

Model

With Cerebral you define the state of your application as a single model: a single state tree. This state tree manages all application state, whether from a server, like a list of users, or client side state, like the currently selected tab of a UI.

All state changes are reflected live in the debugger, giving you a complete picture of how your application behaves. You can even edit the state tree directly and see the changes immediately in your application’s UI.

controller.js
Debugger
import Model from 'cerebral/models/immutable'
import {Controller} from 'cerebral'

const model = Model({
  newItemTitle: '',
  isLoading: false,
  items: [],
  error: null
})

const controller = Controller(model)

export default controller

submitNewItemTitle.js
Debugger
import {set} from 'cerebral/operators'
import addItem from '../actions/addItem'
import postItem from '../actions/postItem'
import updateItem from '../actions/updateItem'
import removeFailedItem from '../actions/removeFailedItem'

export default [
  addItem,
  set('state:newItemTitle', ''),
  set('state:isSaving', true),
  postItem, {
    success: [
      updateItem
    ],
    error: [
      removeFailedItem
    ]
  },
  set('state:isSaving', false)
]

Controller

The Cerebral controller is where you define all state changing logic in your application– code that runs after a button click or a received websocket message, for example.

State changes are modeled using signals. It is a declarative approach, meaning that you are able to describe behaviour without implementing anything. Using arrays and objects to build signals makes them look like decision trees, which is a very good construct to help you build a mental image of complex flows.

The debugger knows when signals trigger and what data goes through them, giving you great insight into your application.

View

Components get data from one or more state paths. When a change occurs in the model, Cerebral notifies the view layer about what paths have changed. Rendering is highly optimized since components only re-render if their registered state paths have actually changed.

The debugger lets you know all the current active state paths and what components are rendered when these state paths change.

React
Snabbdom
Inferno
Debugger
import React from 'react'
import {connect} from 'cerebral-view-react'

export default connect({
  items: 'items'
},
  function Items(props) {
    return (
      <ul>
        {this.props.items.map((item, index) => (
          <li key={index}>
            {item.title}
          </li>
        ))}
      </ul>
    )
  }
)
import {connect, h} from 'cerebral-view-snabbdom'

export default connect({
  items: 'items'
},
  function Items(props) {
    return (
      h('ul', props.items.map(item, index) => (
        h('li', {
          key: index
        }, item.title)
      ))
    )
  }
)
import Inferno from 'inferno'
import {connect} from 'cerebral-view-inferno'

export default connect({
  items: 'items'
},
  function Items(props) {
    return (
      <ul>
        {this.props.items.map((item, index) => (
          <li key={index}>
            {item.title}
          </li>
        ))}
      </ul>
    )
  }
)

"As a core part of our stack, Cerebral was integral in modularizing and scaling our complex application to adapt to our growing user base"
- Chris Fricke, Stem
They are all pretty excited about Cerebral