Cycle.js driver that uses React DOM to render the view


stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
Minified + gzip package size for @cycle/react-dom in KB


Cycle ReactDOM

Cycle.js driver that uses React DOM to render the view

  • Provides a driver factory makeDOMDriver
  • Contains hyperscript helper functions, like in Cycle DOM
npm install @cycle/react-dom


import xs from 'xstream';
import {run} from '@cycle/run';
import {makeDOMDriver, div, h1, button} from '@cycle/react-dom';

function main(sources) {
  const inc = Symbol();
  const inc$ = sources.react.select(inc).events('click');

  const count$ = inc$.fold(count => count + 1, 0);

  const vdom$ = count$.map(i =>
      h1(`Counter: ${i}`),
      button(inc, 'Increment'),

  return {
    react: vdom$,

run(main, {
  react: makeDOMDriver(document.getElementById('app')),



Returns a driver that uses ReactDOM to render your Cycle.js app into the given container element.

Hyperscript helpers

Import hyperscript helpers such as div, span, p, button, input, etc to create React elements to represent the respective HTML elements: <div>, <span>, <p>, <button>, <input>, etc.

The basic usage is div(props, children), but some variations and shortcuts are allowed:

  • div() becomes h('div')
  • div('#foo') becomes h('div', {id: 'foo'})
  • div('.red') becomes h('div', {className: 'red'})
  • div('.red.circle') becomes h('div', {className: 'red circle'})
  • div('#foo.red') becomes h('div', {id: 'foo', className: 'red'})
  • div(propsObject) becomes h('div', propsObject)
  • div('text content') becomes h('div', 'text content')
  • div([child1, child2]) becomes h('div', [child1, child2])
  • div(props, 'text content') becomes h('div', props, 'text content')
  • div(props, [child1, child2]) becomes h('div', props, [child1, child2])
  • div('#foo.bar', props, [child1, child2])
  • etc

There are also shortcuts for (MVI) intent selectors:

  • div(someSymbol) becomes h('div', {sel: someSymbol})
  • div('inc#foo.bar') becomes h('div', {sel: 'inc', id: 'foo', className: 'bar'})
  • div('inc', props) becomes h('div', {sel: 'inc', ...props})
  • div('inc', 'text content') becomes h('div', {sel: 'inc'}, 'text content')
  • div('inc', [child1]) becomes h('div', {sel: 'inc'}, [child1])
  • div('inc', props, [child1]) becomes h('div', {sel: 'inc'}, [child1])
  • etc



Add the following to your webpack config:

module: {
  rules: [
      test: /\.jsx?$/,
      loader: 'babel-loader',
      options: {
        plugins: [
          ['transform-react-jsx', { pragma: 'jsxFactory.createElement' }],

If you used create-cycle-app you may have to eject to modify the config.

Automatically providing jsxFactory

You can avoid having to import jsxFactory in every jsx file by allowing webpack to provide it:

plugins: [
  new webpack.ProvidePlugin({
    jsxFactory: ['react-dom', 'jsxFactory']


Add the following to your tsconfig.json:

  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "jsxFactory.createElement"

If webpack is providing jsxFactory you will need to add typings to custom-typings.d.ts:

declare var jsxFactory: any;


import { jsxFactory } from '@cycle/react-dom';

function view(state$: Stream<State>): Stream<ReactElement> {
    return state$.map(({ count }) => (
            <h2>Counter: {count}</h2>
            <button sel="add">Add</button>
            <button sel="subtract">Subtract</button>


Please ensure you are depending on compatible versions of @cycle/react and @cycle/react-dom. They should both be at least version 2.1.x.

yarn list @cycle/react

should return a single result.


MIT, Andre 'Staltz' Medeiros 2018

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.