DevLog.at

Learning Overmind

My current work task is to dig into the codebase of codesandbox. One of the libraries they use for state management is overmind. Like an alterative to redux, at first glance.

17d

Overmind clocks in at 6.5kb gzipped, according to bundle phobia. Not bad considering its longer list of features.

17d

Written in TypeScript!

17d

Defining actions is more intuitive than vanilla redux. Overmind seems to inject a wrapped snapshot of your state into your action function, allowing your code to directly mutate. Here's the example on their introduction page:

createOvermind({
  state: {
    count: 0
  },
  actions: {
    increaseCount({ state, actions }) {
      state.count++;
      actions.decreaseCount()
    },
    decreaseCount({ state }) {
      state.count--;
    }
  }
})

As you can see, the action functions get their own state object, which is then modified directly. Overmind keeps track of whether or not it changes:

It will automatically track whatever state you use and then flag itself as dirty whenever it changes. If derived state is used while being dirty, the function will run again. If it is not dirty a cached value is returned.

Certainly intuitive, much like mobx. I wonder how it does with arrays, though. I remember having trouble with arrays when I tried mobx a few years ago.

17d

Effects are another overmind concept. The name is a nod to functional programming, I'm sure. But here they don't seem to be anything special, other than being an object that gets passed around to actions. Which, while useful, I'm not sure what makes them "effects".

17d

Overmind's typing just threw me a curveball. They present this code example:

import { Action } from 'overmind';

export const changeNewTodoTitle: Action<string> = ({ state }, title) => {
  state.newTodoTitle = title;
}

And hovering over state in the codesandbox... it's typed?! How does it know?

Digging around further I found this:

declare module 'overmind' {
  interface Config extends IConfig<typeof config> {}
}

Ahh, that's it. The example augments one of Overmind's types, causing it to propogate amongst its other types – such as Action in this example.

An option for applications, but not for libraries. I wonder what the manual typing looks like.

17d

Overmind's devtool seems useful. Looks strangely nice for a devtool, design-wise.

17d

Seeing Overmind be used in codesandbox's codebase is actually a sight to behold. Here's their fork button as an example:

export const ForkButton: FunctionComponent = () => {
  const {
    actions: {
      editor: { forkSandboxClicked },
    },
    state: {
      editor: {
        isForkingSandbox,
        currentSandbox: { owned },
      },
    },
  } = useOvermind();

  return (
    <ProgressButton
      loading={isForkingSandbox}
      onClick={forkSandboxClicked}
      secondary={owned}
      small
    >
      <ForkIcon />

      {isForkingSandbox ? 'Forking...' : 'Fork'}
    </ProgressButton>
  );
};

Great use of destructuring to keep the interaction clean and crisp. And best of all, it's completely typed!

16d

Interesting how Overmind has its own functional programming utilities. I guess it's nice that you don't have to install another library to get the basics. But I also hope they get properly tree-shaken when they aren't used.

12d

Welcome to DevLog

The open thought platform for developers.

Share your work as you work on it. Easier than a blog, handier than Twitter.

Sign in and write down valuable thoughts that would otherwise be forgotten.