remimi

raw JSON →
2.0.4 verified Sat Apr 25 auth: no javascript maintenance

Redux middleware for tracking actions through Mixpanel analytics. v2.0.4 is the latest release (Feb 2018), in maintenance mode with no updates since. Integrates Mixpanel events, profile updates, and action-type-to-event mapping directly into Redux dispatch flow. Differentiates from generic analytics middleware by providing profile selectors, human-friendly formatters, and automatic action type tracking. Supports person profiles, custom properties, increment, and value formatting. Only 500+ weekly downloads on npm as of 2025; alternatives include redux-mixpanel or direct mixpanel-browser integration.

error Error: Actions must be plain objects. Use custom middleware for async actions.
cause The mixpanel action meta must be a plain object. Some users incorrectly pass functions or promises as the action or meta.mixpanel.
fix
Ensure dispatched actions are plain objects with meta.mixpanel as a plain object: store.dispatch({ type: 'TEST', meta: { mixpanel: { eventName: 'Test', props: {} } } })
error Uncaught TypeError: mixpanelMiddleware is not a function
cause Using CJS require without .default, or importing a named export that doesn't exist.
fix
Use const mixpanelMiddleware = require('remimi').default or switch to ESM import mixpanelMiddleware from 'remimi'.
error Warning: mixpanel-browser is not initialized. Please call mixpanel.init() first.
cause remimi does not initialize mixpanel-browser; it expects the library to be initialized elsewhere before the middleware is used.
fix
Add import mixpanel from 'mixpanel-browser'; mixpanel.init(token); before creating the store.
error TypeError: Cannot read properties of null (reading 'id')
cause uniqueIdSelector returns null or undefined when the user is not logged in, but the middleware still tries to identify the user.
fix
Guard the uniqueIdSelector to return a fallback value (e.g., 'anonymous') or skip identification when user is absent: uniqueIdSelector: (state) => state.user?.id || 'anonymous'.
gotcha The package includes mixpanel-browser as a dependency. In v2.0.4, mixpanel-browser was bumped to patched versions to mitigate Autotrack XSS attacks. Always verify the mixpanel-browser version is >=2.22.4.
fix Run `npm ls mixpanel-browser` and ensure >=2.22.4. If not, update remimi or pin mixpanel-browser.
breaking v2.0.0 changed value behavior: values now remain unformatted by default when a propertyFormatter is given. Previously, propertyFormatter was applied to values as well.
fix To retain old behavior, pass the same formatter as propertyFormatter to valueFormatter: `valueFormatter: propertyFormatter`.
gotcha The middleware only fires after the Redux state has been updated (since v2.0.2). This means the action's state change is already applied when the Mixpanel event fires. If you need to track state before the update, you must reverse the middleware order or use a different pattern.
fix Place remimi after other side-effect middleware (like sagas) that rely on state snapshots. Use `applyMiddleware(thunk, remimi, logger)` ordering.
deprecated The package has not been updated since 2018. The Redux ecosystem has shifted to Redux Toolkit, which changes middleware setup. No issues or pull requests are addressed.
fix Consider migrating to redux-mixpanel or rewriting middleware using Redux Toolkit's listenerMiddleware.
npm install remimi
yarn add remimi
pnpm add remimi

Creates a Redux store with remimi middleware, configures profile selectors and formatters, and dispatches a tracked action.

import { createStore, applyMiddleware } from 'redux';
import mixpanelMiddleware from 'remimi';
import rootReducer from './reducers';

const token = process.env.MIXPANEL_TOKEN || '';
const store = createStore(
  rootReducer,
  applyMiddleware(mixpanelMiddleware(token, {
    personSelector: (state) => ({
      $email: state.user.email,
      $first_name: state.user.firstName,
    }),
    uniqueIdSelector: (state) => state.user.id,
    actionTypeFormatter: (type) => type.replace(/_/g, ' '),
    propertyFormatter: (prop) => prop.toLowerCase(),
    valueFormatter: (val) => String(val),
  }))
);

// Dispatch an action to track an event
store.dispatch({
  type: 'Sign up complete',
  meta: {
    mixpanel: {
      props: { source: 'landing-page' },
    },
  },
});