{"id":17918,"library":"refx","title":"refx Redux Middleware for Side Effects","description":"refx is a Redux middleware designed for managing side effects in applications, last updated in 2018 with version 3.1.1. It offers an alternative to solutions like `redux-thunk` by allowing developers to define side effects as an object of action type keys, with handlers that receive both the dispatched action and the store instance. A core differentiator is its emphasis on keeping Redux actions as plain objects, promoting easier extension and composition compared to thunk-augmented action creators. Despite its unique approach and lightweight footprint (241 bytes gzipped and minified), the package has seen no updates in several years, making its compatibility with recent Redux ecosystem changes, such as Redux Toolkit 2.0 or Redux 5.0, questionable. Its release cadence is effectively non-existent, and it does not ship with TypeScript types, requiring manual declarations for modern TypeScript projects.","status":"abandoned","version":"3.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/aduth/refx","tags":["javascript","redux","redux-middleware","middleware"],"install":[{"cmd":"npm install refx","lang":"bash","label":"npm"},{"cmd":"yarn add refx","lang":"bash","label":"yarn"},{"cmd":"pnpm add refx","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for Internet Explorer 8 compatibility if targeted.","package":"es5-shim","optional":true}],"imports":[{"note":"refx is a default export. Ensure your bundler handles default ESM imports correctly, especially in mixed CJS/ESM projects.","wrong":"import { refx } from 'refx';","symbol":"refx","correct":"import refx from 'refx';"},{"note":"CommonJS usage. This is the primary export format and generally works reliably in Node.js environments.","symbol":"refx","correct":"const refx = require('refx');"},{"note":"When included directly via a script tag in a browser, the `refx` function is exposed globally. This method is generally considered legacy for modern applications.","symbol":"refx","correct":"// refx is available globally after script inclusion"}],"quickstart":{"code":"import { createStore, applyMiddleware } from 'redux';\nimport refx from 'refx';\n\n// A placeholder Redux reducer\nfunction todos(state = [], action) {\n  switch (action.type) {\n    case 'TODO_ADD':\n      return [...state, { id: Date.now(), text: action.todo, completed: false }];\n    case 'TODO_SAVED':\n      console.log('TODO_SAVED action dispatched:', action.todo);\n      return state.map(todo => (todo.id === action.todo.id ? { ...todo, text: action.todo.text } : todo));\n    default:\n      return state;\n  }\n}\n\nconst effects = {\n  TODO_ADD: (action, store) => {\n    console.log(`Intercepted TODO_ADD for todo: ${action.todo}`);\n    // Simulate an API call\n    new Promise(resolve => setTimeout(() => resolve({ id: Date.now(), text: action.todo + ' (saved)' }), 500))\n      .then(todo => {\n        store.dispatch({\n          type: 'TODO_SAVED',\n          todo\n        });\n      });\n  },\n  // You can also add other effects, e.g., for error handling or logging\n  // TODO_ERROR: (action, store) => console.error('Error:', action.error)\n};\n\nfunction configureStore() {\n  return createStore(todos, [], applyMiddleware(refx(effects)));\n}\n\nconst store = configureStore();\n\nconsole.log('Initial state:', store.getState());\n\nstore.dispatch({ type: 'TODO_ADD', todo: 'Learn refx' });\nstore.dispatch({ type: 'TODO_ADD', todo: 'Understand side effects' });\n\n// Since effects are async, state updates from effects will happen later.\n// The initial dispatch only updates the store synchronously.\n// console.log('State after first dispatch (before effect completes):', store.getState());\n\n// You would typically observe state changes via subscriptions or UI frameworks\nstore.subscribe(() => {\n  console.log('Current state:', store.getState());\n});","lang":"javascript","description":"This example demonstrates how to set up `refx` middleware with a basic Redux store. It defines an effect to intercept a `TODO_ADD` action, simulate an asynchronous API call, and then dispatch a `TODO_SAVED` action once the 'save' operation completes."},"warnings":[{"fix":"Consider migrating to actively maintained Redux side effect libraries such as Redux Thunk (v3.0+) or Redux Saga, especially when using Redux Toolkit. If sticking with `refx`, be prepared for manual compatibility layers and potential runtime issues with modern Redux versions and bundlers.","message":"The `refx` package has not been updated since 2018 (v3.1.1) and is effectively abandoned. It is highly unlikely to be compatible with modern Redux ecosystems, including Redux Toolkit 2.0 or Redux core 5.0, without significant modifications. These newer versions introduced breaking changes in middleware typing and packaging.","severity":"breaking","affected_versions":">=3.1.1 (due to external ecosystem changes)"},{"fix":"Migrate your Redux store setup to use `configureStore` from `@reduxjs/toolkit`. This is the recommended modern approach for Redux applications. If `refx` cannot be integrated directly, you might need to find an alternative side effect solution.","message":"The example usage of `createStore` is deprecated in Redux 4.2.0+ and Redux 5.0+, which encourages migration to `configureStore` from Redux Toolkit. While `createStore` still works, it will show a strikethrough in IDEs.","severity":"deprecated","affected_versions":">=3.1.1 (due to external Redux changes)"},{"fix":"Create a `refx.d.ts` file in your project to declare the module and its types. For example: `declare module 'refx' { import { Middleware } from 'redux'; type EffectHandler = (action: any, store: any) => any; type EffectsMap = { [key: string]: EffectHandler | EffectHandler[] }; function refx(effects: EffectsMap | EffectsMap[]): Middleware; export default refx; }`","message":"The package does not ship with TypeScript type definitions. Using `refx` in a TypeScript project will require creating custom declaration files (`.d.ts`) for the middleware and effect handlers to ensure type safety.","severity":"gotcha","affected_versions":">=3.1.1"},{"fix":"If using TypeScript, ensure your custom `refx.d.ts` definitions correctly cast or narrow the `action` and `store` parameters within your effect handlers. For JavaScript, be aware of the potential for runtime type-related issues if `refx` expects specific types that are no longer guaranteed by newer Redux versions.","message":"Modern Redux (v5.0, Redux Toolkit 2.0) introduced changes to how middleware parameters (`action`, `next`) are typed, shifting them to `unknown` for enhanced safety. An older middleware like `refx` might not account for these explicit `unknown` types, potentially leading to TypeScript errors or runtime type mismatches if not carefully managed.","severity":"gotcha","affected_versions":">=3.1.1 (when used with Redux 5.0+ or RTK 2.0+)"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure you are using the correct import syntax for your module environment. For ESM, use `import refx from 'refx';`. For CommonJS, use `const refx = require('refx');`. Verify your bundler configuration (Webpack, Rollup, Vite, etc.) is correctly resolving `refx`'s module exports.","cause":"Attempting to use `refx` in an environment that expects a different module format (e.g., CommonJS `require` in an ESM-only context, or vice-versa), or an incorrect import statement.","error":"Error: Middleware is not a function"},{"fix":"In your custom `refx.d.ts` or directly within your effect handlers, explicitly type the `store` parameter to `Redux.Store` or a more specific store type, ensuring `dispatch` is recognized. For example: `(action: any, store: Redux.Store) => { store.dispatch(...) }`","cause":"This TypeScript error can occur when using `refx` with modern Redux (v5.0+) due to stricter typing of middleware parameters. The `store` object passed to effect handlers might be typed as `any` or `unknown` in `refx`'s unofficial types, clashing with Redux's evolved type definitions.","error":"Property 'dispatch' does not exist on type 'unknown'"},{"fix":"Refactor your Redux store initialization to use `configureStore` from `@reduxjs/toolkit`. You will need to define your `refx` middleware and effects within `configureStore`'s middleware array. This may require adapting `refx`'s integration if it expects specific `createStore` behaviors.","cause":"This is a deprecation warning from Redux itself when `createStore` is used. While not a runtime error, it indicates using a legacy API.","error":"console.warn: `createStore` has been deprecated. Use `configureStore` from Redux Toolkit instead."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}