{"id":18741,"library":"remimi","title":"remimi","description":"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.","status":"maintenance","version":"2.0.4","language":"javascript","source_language":"en","source_url":"https://github.com/BrandwatchLtd/remimi","tags":["javascript","Redux.","Middleware","Mixpanel"],"install":[{"cmd":"npm install remimi","lang":"bash","label":"npm"},{"cmd":"yarn add remimi","lang":"bash","label":"yarn"},{"cmd":"pnpm add remimi","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for Mixpanel client-side tracking. Version bumped to fix Autotrack CVEs.","package":"mixpanel-browser","optional":false}],"imports":[{"note":"Default ESM export; CJS require needs .default","wrong":"const mixpanelMiddleware = require('remimi').default","symbol":"default","correct":"import mixpanelMiddleware from 'remimi'"},{"note":"The middleware is the default export, not a named export. Named import will fail.","wrong":"const { mixpanelMiddleware } = require('remimi')","symbol":"mixpanelMiddleware","correct":"import remimi from 'remimi'"},{"note":"Package ships minimal TypeScript definitions (index.d.ts). Use import type for options interface.","symbol":"type","correct":"import type { MixpanelOptions } from 'remimi'"}],"quickstart":{"code":"import { createStore, applyMiddleware } from 'redux';\nimport mixpanelMiddleware from 'remimi';\nimport rootReducer from './reducers';\n\nconst token = process.env.MIXPANEL_TOKEN || '';\nconst store = createStore(\n  rootReducer,\n  applyMiddleware(mixpanelMiddleware(token, {\n    personSelector: (state) => ({\n      $email: state.user.email,\n      $first_name: state.user.firstName,\n    }),\n    uniqueIdSelector: (state) => state.user.id,\n    actionTypeFormatter: (type) => type.replace(/_/g, ' '),\n    propertyFormatter: (prop) => prop.toLowerCase(),\n    valueFormatter: (val) => String(val),\n  }))\n);\n\n// Dispatch an action to track an event\nstore.dispatch({\n  type: 'Sign up complete',\n  meta: {\n    mixpanel: {\n      props: { source: 'landing-page' },\n    },\n  },\n});","lang":"javascript","description":"Creates a Redux store with remimi middleware, configures profile selectors and formatters, and dispatches a tracked action."},"warnings":[{"fix":"Run `npm ls mixpanel-browser` and ensure >=2.22.4. If not, update remimi or pin mixpanel-browser.","message":"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.","severity":"gotcha","affected_versions":"<=2.0.4"},{"fix":"To retain old behavior, pass the same formatter as propertyFormatter to valueFormatter: `valueFormatter: propertyFormatter`.","message":"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.","severity":"breaking","affected_versions":">=2.0.0 <2.0.0"},{"fix":"Place remimi after other side-effect middleware (like sagas) that rely on state snapshots. Use `applyMiddleware(thunk, remimi, logger)` ordering.","message":"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.","severity":"gotcha","affected_versions":">=2.0.2"},{"fix":"Consider migrating to redux-mixpanel or rewriting middleware using Redux Toolkit's listenerMiddleware.","message":"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.","severity":"deprecated","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Ensure dispatched actions are plain objects with meta.mixpanel as a plain object: `store.dispatch({ type: 'TEST', meta: { mixpanel: { eventName: 'Test', props: {} } } })`","cause":"The mixpanel action meta must be a plain object. Some users incorrectly pass functions or promises as the action or meta.mixpanel.","error":"Error: Actions must be plain objects. Use custom middleware for async actions."},{"fix":"Use `const mixpanelMiddleware = require('remimi').default` or switch to ESM `import mixpanelMiddleware from 'remimi'`.","cause":"Using CJS require without .default, or importing a named export that doesn't exist.","error":"Uncaught TypeError: mixpanelMiddleware is not a function"},{"fix":"Add `import mixpanel from 'mixpanel-browser'; mixpanel.init(token);` before creating the store.","cause":"remimi does not initialize mixpanel-browser; it expects the library to be initialized elsewhere before the middleware is used.","error":"Warning: mixpanel-browser is not initialized. Please call mixpanel.init() first."},{"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'`.","cause":"uniqueIdSelector returns null or undefined when the user is not logged in, but the middleware still tries to identify the user.","error":"TypeError: Cannot read properties of null (reading 'id')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}