{"id":17026,"library":"listr2","title":"Listr2 - Interactive Terminal Task Lists","description":"Listr2 is a robust and highly interactive task list manager for Node.js command-line applications, designed to provide live updates and a dynamic user experience. As of version 10.2.1, it emphasizes modern JavaScript practices and is primarily used with TypeScript, shipping with comprehensive type definitions. It evolved from the original Listr package, offering a rewritten architecture for improved flexibility, extensibility, and performance, including advanced error handling, concurrent task execution, and support for multiple renderers (e.g., default, verbose, silent). Its release cadence is active, with frequent updates addressing bug fixes, dependency updates, and new features, often released in minor and patch versions. Key differentiators include its ability to manage complex multi-level tasks with live output, integration with popular prompt libraries like Inquirer.js and Enquirer through dedicated adapters, and a flexible API for customizability, making it suitable for complex CLI workflows.","status":"active","version":"10.2.1","language":"javascript","source_language":"en","source_url":"https://github.com/listr2/listr2","tags":["javascript","listr","listr2","cli","task","list","tasklist","terminal","term","typescript"],"install":[{"cmd":"npm install listr2","lang":"bash","label":"npm"},{"cmd":"yarn add listr2","lang":"bash","label":"yarn"},{"cmd":"pnpm add listr2","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides integration with Inquirer.js for interactive prompts within tasks.","package":"@listr2/prompt-adapter-inquirer","optional":true},{"reason":"Provides integration with Enquirer for interactive prompts within tasks.","package":"@listr2/prompt-adapter-enquirer","optional":true}],"imports":[{"note":"Listr2 is primarily designed for ESM. While it may offer CJS compatibility through transpilation or bundlers, direct `require()` is not the recommended or fully supported way to import the main `Listr` class in modern Node.js environments, especially with its high Node.js engine requirement. Using `import` is preferred for type inference and future compatibility.","wrong":"const Listr = require('listr2')","symbol":"Listr","correct":"import { Listr } from 'listr2'"},{"note":"Renderers are imported as named exports. Listr2 also provides `ListrSimpleRenderer` and `ListrVerboseRenderer`.","symbol":"ListrDefaultRenderer","correct":"import { ListrDefaultRenderer } from 'listr2'"},{"note":"For type-checking tasks, explicitly import `ListrTask` for better code completion and safety, especially when defining complex task arrays or subtasks.","symbol":"ListrTask","correct":"import type { ListrTask } from 'listr2'"}],"quickstart":{"code":"import { Listr, ListrDefaultRenderer } from 'listr2';\n\ninterface MyContext {\n  input: string;\n  output: string;\n}\n\nasync function runTasks() {\n  const tasks = new Listr<MyContext>(\n    [\n      {\n        title: 'Main task 1: Processing input',\n        task: async (ctx, task) => {\n          ctx.input = 'initial data';\n          task.output = `Input set to: ${ctx.input}`;\n          await new Promise((resolve) => setTimeout(resolve, 1000));\n        }\n      },\n      {\n        title: 'Main task 2: With subtasks',\n        task: (ctx, task) =>\n          task.newListr(\n            [\n              {\n                title: 'Subtask 2.1: Fetching data',\n                task: async (_, subtask) => {\n                  subtask.output = 'Fetching from external API...';\n                  await new Promise((resolve) => setTimeout(resolve, 1500));\n                  // Simulate an error for demonstration\n                  if (Math.random() > 0.7) {\n                    throw new Error('Failed to fetch data!');\n                  }\n                }\n              },\n              {\n                title: 'Subtask 2.2: Transforming data',\n                task: async (_, subtask) => {\n                  subtask.output = 'Applying transformations.';\n                  await new Promise((resolve) => setTimeout(resolve, 800));\n                }\n              }\n            ],\n            { concurrent: true, exitOnError: false }\n          )\n      },\n      {\n        title: 'Main task 3: Generating output',\n        task: async (ctx, task) => {\n          ctx.output = `Processed: ${ctx.input.toUpperCase()}`;\n          task.output = `Final output: ${ctx.output}`;\n          await new Promise((resolve) => setTimeout(resolve, 500));\n        },\n        options: { persistentOutput: true }\n      }\n    ],\n    {\n      concurrent: false,\n      exitOnError: true,\n      renderer: ListrDefaultRenderer,\n      rendererOptions: {\n        collapse: false,\n        clearOutput: true\n      }\n    }\n  );\n\n  try {\n    const context = await tasks.run();\n    console.log('\\nAll tasks completed successfully!');\n    console.log('Final Context:', context);\n  } catch (e: any) {\n    console.error('\\nOne or more tasks failed:', e.message);\n  }\n}\n\nrunTasks();","lang":"typescript","description":"Demonstrates creating a new Listr instance with main tasks and subtasks, handling context, displaying output, and managing errors with both sequential and concurrent execution."},"warnings":[{"fix":"Upgrade your Node.js environment to version 22.13.0 or newer. Consider using a Node.js version manager like `nvm` or `volta`.","message":"Listr2 requires Node.js version 22.13.0 or higher. Older Node.js versions are not supported and will result in errors.","severity":"breaking","affected_versions":">=10.0.0"},{"fix":"Refer to the official Listr2 documentation for a comprehensive guide on the new API and migration path from `listr`.","message":"Listr2 is a complete rewrite of the original `listr` package. It introduces a new API, different configuration options, and a more opinionated structure. Direct migration from `listr` without code changes is not possible.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Ensure your project is configured for ESM by setting `\"type\": \"module\"` in your `package.json` and using `import` statements. If you must use CJS, you might need to use dynamic `import()` or adjust your build pipeline.","message":"Listr2 is primarily designed for ES Modules (ESM). While tools may transpile it for CommonJS (CJS) compatibility, direct `require()` calls may lead to unexpected behavior or `TypeError: Listr is not a constructor`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Install the required prompt adapter, e.g., `npm install @listr2/prompt-adapter-inquirer`.","message":"When using prompt adapters (e.g., `@listr2/prompt-adapter-inquirer`), ensure the specific adapter package is installed alongside `listr2`. Failure to do so will result in runtime errors when a prompt task is encountered.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"No direct action required for most users. If you had custom renderer logic tied to `colorette`, you may need to update it to use `util.styleText` or another coloring library if you desire custom styling.","message":"Internal color styling utility `colorette` has been replaced with Node.js's native `util.styleText` for internal styling. While this is primarily an internal change, users who were relying on or overriding `colorette`'s behavior within Listr2 might notice differences.","severity":"deprecated","affected_versions":">=10.2.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Switch to ES Module import syntax: `import { Listr } from 'listr2';`. Ensure your `package.json` has `\"type\": \"module\"` if your entire project is ESM, or use a bundler if mixing CJS and ESM.","cause":"Attempting to import Listr2 using CommonJS `require()` syntax in an environment where it's treated as an ES Module.","error":"ERR_REQUIRE_ESM: require() of ES Module ... listr2.js from ... is not supported."},{"fix":"Verify that you are using `import { Listr } from 'listr2';` and that your environment supports ES Modules for this package. Avoid `const Listr = require('listr2').Listr;` as it might not work reliably.","cause":"This usually happens when trying to `new Listr()` after a CJS `require()` that incorrectly resolves the ESM export, or if an incorrect symbol is imported.","error":"TypeError: Listr is not a constructor"},{"fix":"Wrap your task logic in `try...catch` blocks to gracefully handle errors, or set `exitOnError: false` in the Listr options to allow other tasks to continue running even after a failure.","cause":"One of the tasks or subtasks threw an unhandled error, and the `exitOnError` option (defaulting to `true`) caused Listr2 to stop execution.","error":"ListrError: A task has failed and `exitOnError` is enabled, exiting."}],"ecosystem":"npm","meta_description":null}