{"id":17908,"library":"redux-pack","title":"Redux Pack Middleware for Promise Handling","description":"Redux Pack is a Redux middleware library designed to simplify the handling of asynchronous actions through a declarative, promise-based approach. It aims to reduce boilerplate and prevent common issues associated with `redux-thunk`, such as multiple sequential dispatches causing performance penalties and inconsistent state, by treating a promise's lifecycle as a single action. The library's core utility is the `handle` function, which allows reducers to declaratively respond to the start, success, failure, and completion of a promise. However, the package, currently at version 0.1.5, was last published in March 2017. It is considered abandoned, lacks support for modern Redux versions (e.g., v5+), contemporary JavaScript features like ES Modules, and is superseded by Redux Toolkit's `createAsyncThunk` for robust and officially recommended async logic management. Community-maintained TypeScript types (`@types/redux-pack`) exist, but the core library itself does not offer official type support.","status":"abandoned","version":"0.1.5","language":"javascript","source_language":"en","source_url":"https://github.com/lelandrichardson/redux-pack","tags":["javascript","redux","middleware","promise","async","normalize","normalizr","react"],"install":[{"cmd":"npm install redux-pack","lang":"bash","label":"npm"},{"cmd":"yarn add redux-pack","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-pack","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core state management library that redux-pack extends as middleware.","package":"redux","optional":false}],"imports":[{"note":"The primary middleware function to be applied to the Redux store. While not explicitly named `middleware` in the README, this is a common pattern for middleware packages. It is typically a named export, though older packages might have used a default export.","wrong":"import reduxPackMiddleware from 'redux-pack'; // CommonJS style for older default exports or incorrect named import\nconst reduxPackMiddleware = require('redux-pack'); // Not designed for direct require() in modern setups","symbol":"reduxPackMiddleware","correct":"import { middleware as reduxPackMiddleware } from 'redux-pack';"},{"note":"Used within reducers to declaratively manage state transitions based on the lifecycle (start, success, failure, always) of a promise action.","wrong":"const handle = require('redux-pack').handle; // Old CommonJS syntax\nimport handle from 'redux-pack'; // Incorrect if it's a named export","symbol":"handle","correct":"import { handle } from 'redux-pack';"},{"note":"Redux Pack expects users to define their own action type constants. The library does not export pre-defined action type constants for promise lifecycle stages, instead it infers them from the base action type.","wrong":"import { LOAD_FOO } from 'redux-pack'; // Action types are user-defined, not imported from the library.","symbol":"ACTION_TYPE_NAME","correct":"export const LOAD_FOO = 'LOAD_FOO';"}],"quickstart":{"code":"import { createStore, applyMiddleware, combineReducers } from 'redux';\nimport { middleware as reduxPackMiddleware, handle } from 'redux-pack';\n\n// 1. Define Action Types\nexport const LOAD_USER = 'LOAD_USER';\n\n// 2. Define an API utility (mock for example)\nconst Api = {\n  getUser: (id) => new Promise(resolve => {\n    setTimeout(() => {\n      console.log(`Fetching user ${id}...`);\n      resolve({ id, name: `User ${id}`, email: `user${id}@example.com` });\n    }, 500);\n  })\n};\n\n// 3. Create an Action Creator\nexport function loadUser(id) {\n  return {\n    type: LOAD_USER,\n    promise: Api.getUser(id),\n    meta: {\n      onStart: () => console.log(`Starting fetch for user ${id}`),\n      onSuccess: (payload) => console.log('User fetched successfully:', payload),\n      onFailure: (error) => console.error('Failed to fetch user:', error),\n      // Other hooks: onFinish, always\n    }\n  };\n}\n\n// 4. Create a Reducer\nconst initialState = { \n  user: null, \n  isLoading: false, \n  error: null \n};\n\nfunction userReducer(state = initialState, action) {\n  switch (action.type) {\n    case LOAD_USER:\n      return handle(state, action, {\n        start: prevState => ({ ...prevState, isLoading: true, error: null }),\n        success: prevState => ({ ...prevState, isLoading: false, user: action.payload }),\n        failure: prevState => ({ ...prevState, isLoading: false, error: action.payload }),\n        finish: prevState => ({ ...prevState })\n      });\n    default:\n      return state;\n  }\n}\n\n// 5. Configure the Redux Store\nconst rootReducer = combineReducers({\n  user: userReducer\n});\n\nconst store = createStore(\n  rootReducer,\n  applyMiddleware(reduxPackMiddleware)\n);\n\n// 6. Dispatch the action\nconsole.log('Initial state:', store.getState());\nstore.dispatch(loadUser(123));\n\nstore.subscribe(() => {\n  console.log('Current state:', store.getState());\n});\n\n// Example dispatch for a second user (showing different state change)\nsetTimeout(() => {\n  store.dispatch(loadUser(456));\n}, 1500);","lang":"javascript","description":"Demonstrates setting up a Redux store with `redux-pack` middleware, defining a promise-based action, and handling its lifecycle in a reducer using the `handle` utility, including optional lifecycle hooks in `meta`."},"warnings":[{"fix":"Avoid using `redux-pack` for new projects. For existing projects, consider migrating to Redux Toolkit's `createAsyncThunk` for modern async logic handling, which is actively maintained and officially supported by the Redux team.","message":"Redux Pack is effectively abandoned, with its last npm package update (v0.1.5) occurring in March 2017. This means it is highly unlikely to receive updates for security vulnerabilities, bug fixes, or compatibility with newer versions of Redux, React, or JavaScript features (like ES Modules).","severity":"breaking","affected_versions":">=0.1.5"},{"fix":"Ensure your build tool is configured to correctly handle CJS modules, or preferably, migrate to a modern solution like Redux Toolkit which offers full ESM/CJS compatibility.","message":"This library was designed before modern ES Modules (ESM) were standard in the JavaScript ecosystem. It ships with CommonJS (CJS) modules and may have compatibility issues or require specific bundler configurations (e.g., Webpack, Rollup, Vite) to work correctly in an ESM-first environment.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Familiarize yourself with Redux Toolkit and its `createAsyncThunk` for managing async operations. It is the recommended and best-practice approach in the current Redux ecosystem.","message":"Redux Pack's approach to promise handling has been largely superseded by Redux Toolkit, specifically the `createAsyncThunk` utility. Redux Toolkit provides a more integrated, opinionated, and modern solution for async logic, including built-in handling of loading states, errors, and TypeScript support, which `redux-pack` predates.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"If using `redux-pack` in a TypeScript project, ensure you install `@types/redux-pack`. However, for robust type safety and modern TypeScript features, migration to Redux Toolkit is strongly recommended.","message":"The `redux-pack` library itself does not ship with official TypeScript type definitions. While community-contributed types (`@types/redux-pack`) exist and are actively maintained by the DefinitelyTyped project, relying solely on community types can sometimes lead to inconsistencies or delays in supporting new library features (though this is less relevant for an abandoned library).","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure `reduxPackMiddleware` is correctly applied to your Redux store using `applyMiddleware`: `const store = createStore(rootReducer, applyMiddleware(reduxPackMiddleware));`","cause":"The `redux-pack` middleware has not been applied to the Redux store, or it's misconfigured, causing Redux to treat the promise-returning action as a non-plain object.","error":"Error: Actions must be plain objects. Instead, the actual type was: 'Promise'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions."},{"fix":"Verify that `redux-pack` is installed (`npm install redux-pack` or `yarn add redux-pack`) and that `handle` is imported as a named export: `import { handle } from 'redux-pack';`","cause":"The `handle` utility from `redux-pack` was not imported correctly or `redux-pack` itself was not installed.","error":"TypeError: Cannot read properties of undefined (reading 'handle') or handle is not a function"},{"fix":"Ensure your action creator returns an object with a `promise` key whose value is an actual Promise: `return { type: 'MY_ACTION', promise: myAsyncFunction(), ... };`","cause":"An action dispatched using `redux-pack`'s expected format (an object with a `promise` key) either did not contain a `promise` key or the value associated with `promise` was not a valid Promise instance.","error":"TypeError: A promise must be returned from the action creator (or present in the `promise` key of the action object)."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}