Home

Awesome

ts-elmish

npm version build publish codecov Type Coverage npm

<!-- [![devDependencies Status](https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?type=dev)](https://david-dm.org/iyegoroff/ts-elmish?type=dev) -->

Elmish architecture in Typescript


Features

Packages

<table> <tbody> <tr> <td><a href="/packages/core">@ts-elmish/core</a></td> <td>elmish runtime</td> <td><img alt="dependencies" src="https://img.shields.io/librariesio/release/npm/@ts-elmish/core"></td> <!-- <td><a href="https://bundlephobia.com/package/@ts-elmish/core" title="min+gzip"><img src="https://badgen.net/bundlephobia/minzip/@ts-elmish/core?label=min+gzip"/></a></td> --> <td><a href="https://bundlephobia.com/package/@ts-elmish/core" title="min+gzip"><img src="https://img.shields.io/bundlephobia/minzip/@ts-elmish/core?label=min+gzip"/></a></td> <!-- <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/core" title="dependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Fcore"/></a></td> <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/core&type=dev" title="devDependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Fcore&type=dev"/></a></td> --> </tr> <tr> <td><a href="/packages/basic-effects">@ts-elmish/basic-effects</a></td> <td>effects from functions</td> <td><img alt="dependencies" src="https://img.shields.io/librariesio/release/npm/@ts-elmish/basic-effects"></td> <!-- <td><a href="https://bundlephobia.com/package/@ts-elmish/basic-effects" title="min+gzip"><img src="https://badgen.net/bundlephobia/minzip/@ts-elmish/basic-effects?label=min+gzip"/></a></td> --> <td><a href="https://bundlephobia.com/package/@ts-elmish/basic-effects" title="min+gzip"><img src="https://img.shields.io/bundlephobia/minzip/@ts-elmish/basic-effects?label=min+gzip"/></a></td> <!-- <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/basic-effects" title="dependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Fbasic-effects"/></a></td> <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/basic-effects&type=dev" title="devDependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Fbasic-effects&type=dev"/></a></td> --> </tr> <tr> <td><a href="/packages/railway-effects">@ts-elmish/railway-effects</a></td> <td>ROP-powered effects</td> <td><img alt="dependencies" src="https://img.shields.io/librariesio/release/npm/@ts-elmish/railway-effects"></td> <!-- <td><a href="https://bundlephobia.com/package/@ts-elmish/railway-effects" title="min+gzip"><img src="https://badgen.net/bundlephobia/minzip/@ts-elmish/railway-effects?label=min+gzip"/></a></td> --> <td><a href="https://bundlephobia.com/package/@ts-elmish/railway-effects" title="min+gzip"><img src="https://img.shields.io/bundlephobia/minzip/@ts-elmish/railway-effects?label=min+gzip"/></a></td> <!-- <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/railway-effects" title="dependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Frailway-effects"/></a></td> <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/railway-effects&type=dev" title="devDependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Frailway-effects&type=dev"/></a></td> --> </tr> <tr> <td><a href="/packages/react">@ts-elmish/react</a></td> <td>react view layer</td> <td><img alt="dependencies" src="https://img.shields.io/librariesio/release/npm/@ts-elmish/react"></td> <!-- <td><a href="https://bundlephobia.com/package/@ts-elmish/react" title="min+gzip"><img src="https://badgen.net/bundlephobia/minzip/@ts-elmish/react?label=min+gzip"/></a></td> --> <td><a href="https://bundlephobia.com/package/@ts-elmish/react" title="min+gzip"><img src="https://img.shields.io/bundlephobia/minzip/@ts-elmish/react?label=min+gzip"/></a></td> <!-- <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/react" title="dependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Freact"/></a></td> <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/react&type=dev" title="devDependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Freact&type=dev"/></a></td> --> </tr> <tr> <td><a href="/packages/mithril">@ts-elmish/mithril</a></td> <td>mithril view layer</td> <td><img alt="dependencies" src="https://img.shields.io/librariesio/release/npm/@ts-elmish/mithril"></td> <!-- <td><a href="https://bundlephobia.com/package/@ts-elmish/mithril" title="min+gzip"><img src="https://badgen.net/bundlephobia/minzip/@ts-elmish/mithril?label=min+gzip"/></a></td> --> <td><a href="https://bundlephobia.com/package/@ts-elmish/mithril" title="min+gzip"><img src="https://img.shields.io/bundlephobia/minzip/@ts-elmish/mithril?label=min+gzip"/></a></td> <!-- <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/mithril" title="dependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Fmithril"/></a></td> <td><a href="https://david-dm.org/iyegoroff/ts-elmish?path=packages/mithril&type=dev" title="devDependencies status"><img src="https://status.david-dm.org/gh/iyegoroff/ts-elmish.svg?path=packages%2Fmithril&type=dev"/></a></td> --> </tr> <tr> <td><a href="/packages/debugger">@ts-elmish/debugger</a></td> <td>redux-devtools integration</td> <td><img alt="dependencies" src="https://img.shields.io/librariesio/release/npm/@ts-elmish/debugger"></td> <!-- <td><a href="https://bundlephobia.com/package/@ts-elmish/debugger" title="min+gzip"><img src="https://badgen.net/bundlephobia/minzip/@ts-elmish/debugger?label=min+gzip"/></a></td> --> <td><a href="https://bundlephobia.com/package/@ts-elmish/debugger" title="min+gzip"><img src="https://img.shields.io/bundlephobia/minzip/@ts-elmish/debugger?label=min+gzip"/></a></td> </tr> </tbody> </table>

Getting started

At first you have to choose an effect handling strategy - currently there are two options:

Then just add ts-elmish packages to your project:

Useful generic purpose modules:

Basic example

import m, { Component } from 'mithril'
import { ElmishAttrs, createElmishRootComponent } from '@ts-elmish/mithril'
import { Effect } from '@ts-elmish/basic-effects'

type State = {
  readonly count: number
}

type Action = 'increment' | 'decrement'

const init = (): State => {
  return { count: 0 }
}

const update = ({ count }: State, action: Action): State => {
  switch (action) {
    case 'increment':
      return { count: count + 1 }

    case 'decrement':
      return { count: count - 1 }
  }
}

const Counter: Component<ElmishAttrs<State, Action>> = {
  view: ({ attrs: { count, dispatch } }) =>
    m('div', [
      m('div', count),
      m('button', { onclick: () => dispatch('increment') }, '+'),
      m('button', { onclick: () => dispatch('decrement') }, '-')
    ])
}

const App = createElmishRootComponent({
  init: () => [init(), Effect.none<Action>()],
  update: (state, action) => [update(state, action), Effect.none()],
  view: Counter
})

m.mount(document.body, {
  view: () => m(App, {})
})

Learning ts-elmish

Due to small size it is worth just to look at the code. Also there is a basic and advanced examples.

Links