npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mehdux

v0.5.5

Published

A straight forward state container

Readme

mehdux 🐧

Just another tiny, simple state machine

  • 💆 Easy to grasp API
  • 🐎 ~1kb: Tiny, small, slim, light, slender, fit
  • ⚛️ Small React (~850 bytes), Preact (~800 bytes) and Picodom (~200 bytes) integrations
  • 😌 Support for thunk actions, middlewares, combining stores
  • 🛂 Written in TypeScript
  • 🎉 WordArt logo
  • 🌞 Emojis in README.md

Motivation

Nobody thinks the JS community needs another state management library, so I made one to spite you all.

Examples

Usage

npm install mehdux

Initializing mehdux

import { Store } from 'mehdux'

const initialState = {
  value: 0
}

const actions = {
  // ...
}

const store = new Store(initialState, actions)

Creating and using actions

The actions you create should be a function that takes the state and returns a function returning the new state.

const actions = {
  inc: state => value => ({
    ...state,
    value: state.value + value
  }),
  dec: state => value => ({
    ...state,
    value: state.value - value
  })
}

Mehdux transforms the actions you pass the store. Using the actions simply looks like this:

store.actions.inc(1)

Subscribe to state changes

To subscribe to state changes you use the connect-function on the store instance you have already created.

On a state change the subscriber gets invoked with the state tree as the first argument and the actions as the second argument.

store.connect()(console.log)

store.actions.inc(10)
// logs { value: 10 }, { inc: f(), dec: f() }

The connect function can take an object containing the following options: mapStateToProps, mapActionsToProps, leading and force. All of these properties are optional.

MapStateToProps

Enables you to only subscribe to certain parts of the state tree. This should be a function that takes state as an argument and returns an object.

On every state update this function will be called. If the result is different from the last state update, the connected function will be called.

const mapStateToProps = ({ something, somethingElse }) => ({
  something,
  somethingElse
})

store.connect({ mapStateToProps })(console.log)

This is very similiar to how you mapping state to props in react-redux works. If null is passed, the conneciton will not get any state updates.

MapActionsToProps

Works in the same way mapStateToProps works, enabling you to only pass certain actions to you connected function.

const mapActionsToProps = actions => ({
  inc: actions.inc,
  increaseByTen: () => actions.inc(10),
})

store.connect({ mapActionsToProps })(console.log)

Notice how this enables you to preset an action like the increaseByTen demonstrates above. If null is passed, the conneciton will not get any actions passed.

Leading

The leading option is an optional boolean that tells the store whether or not to execute the connected function on the time of connection. Default: false

Force

The force option is also an optional boolean that tells the store to execute the connected function on every action, eventhough the state did not change. Default: false

Usage with other frameworks

Mehdux has built-in integrations with react, preact and picodom.

React and Preact

To connect a component to the store you need to wrap the component in the connect-function from mehdux.

import { connect } from 'mehdux/react' // or 'mehdux/preact'

There are two ways to pass the store to the connect-function in mehdux:

  1. By wrapping your app in a higher order provider-function like, similiar to how react-redux does it.
  2. Passing the store in the options object to the connect function.

1. By using a Provider

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider, connect } from 'mehdux/react' // or 'mehdux/preact'
import { store } from './store' // or wherever you keep your store instance


const Button = ({ state, actions }) => {
  return <button onClick={actions.inc}>{state.value}</button>
}

const ConnectedButton = connect()(Button)

ReactDOM.render(
  <Provider store={store}>
    <ConnectedButton />
  </Provider>,
  document.getElementById('root')
)

2. By passing in the store instance

import { connect } from 'mehdux/react' // or 'mehdux/preact'
import { store } from './store' // or wherever you keep your store instance


const Button = ({ state, actions }) => {
  return <button onClick={actions.inc}>{state.value}</button>
}

const ConnectedButton = connect({ store })(Button)

Picodom

Mehdux exports a tiny, small, slender, light, fit connect-function for easy stateful components in Picodom.

Regular usagage

A typical Picodom and Mehdux app might look like this:

// @jsx h
import { h, patch } from 'picodom'
import { store } from './store' // or wherever you keep your store instance

let node = null

const render = viewFn => (state, actions) => {
  patch(node, (node = viewFn(state, actions)), root);
};

const view = (state, actions) => {
  return <button onClick={actions.inc}>{state.value}</button>
}

store.connect()(render(view))

Out of the box stateful components connected to a store is not straight-forward with Picodom. To make connected components in Picodom a breeze Mehdux comes with a small connect-function.

Here is how to do it:

// @jsx h
import { h, patch } from 'picodom'
import { connect } from 'mehdux/picodom'
import { store } from './store' // or wherever you keep your store instance

let node = null

// Note the storeInstance that gets passed to 'render' from 'store.connect'
const render = viewFn => (state, actions, storeInstance) => {
  patch(node, (node = viewFn(state, actions, storeInstance)), root);
};

const Button = ({ actions, state }) => {
  return <button onClick={actions.inc}>{state.value}</button>
}

const ConnectedButton = connect()(Button)

const view = (state, actions, storeInstance) => {
  return (
    <div>
      <ConnectedButton store={storeInstance} />
    </div>
  )
}

// Note the third argument to connect, which forces the store to emit even on equal states.
// This is to enable the stateful components inside `view` to get rerun,
// eventhough the parent state does not change.

store.connect({ leading: true, force: true })(render(view))

Note: This implementation will likely be rewritten to be more similiar to the React/Preact-implementations

Advanced usage

Dispatching multiple or async actions

Mehdux has support for dispatching actions within actions. You have access to other actions within an action.

To dispatch simply execute the action you want.

const actions = {
  addUser: state => user => ({
    ...state,
    user: [...state.users, user]
  }),
  addManyUsers: state => () => {
    actions.addUser('Kari')
    actions.addUser('Ola')
  },
  addUserIn2s: (state, actions) => user => {
    setTimeout(() => actions.addUser(user), 2000)
  },
  fetchAndSetName: (state, actions) => async () => {
    const res = await fetch('https://myapi.com/v0')
    const user = await res.json()
    actions.addUser(user)
  }
}

Middleware/Enhancers

Store takes a third argument along side initialState and actions. This is an array of middleware-functions. Each middleware gets called on actions being called on the store.

They recieve the action name, arguments, currentState and nextState.

Logging and analytics are examples of middleware usages.

mehdux/utils includes a helper function for applying middlewares, but you are free to just pass an array as well.

import { Store } from 'mehdux'
import { applyMiddleware } from 'mehdux/utils'
import { Logger, Analytics } from './middlewares' // or wherever you keep your middlewares

const store = new Store({}, {}, applyMiddleware(Logger, Analytics)

export { store }

Combining multiple store instances

Bigger apps often have complex state trees. In redux you would handle this by combining reducers. With Mehdux you can combine stores with the combineStores-function from mehdux/utils like so:

import { combineStores } from 'mehdux/utils'

const store = combineStores({
  users: userStore,
  posts: postStore
}, /* myMiddleware */)

By default combineStores does not copy the middlewares for each sub-store. And you need to apply the middlewares as the second argument. However, if you want to copy the original middlewares past to the store you can by passing true as the second argument to combineStores.

Todos

  • Tests
  • Sort out type-definitions when using microbundle

License

MIT.