{"id":12980,"library":"commist","title":"Commist","description":"Commist is a JavaScript library designed for building command-line interface (CLI) applications with multiple subcommands. It functions as a lightweight command registry and dispatcher, primarily intended for use alongside `minimist` for parsing arguments within individual command handlers. The current stable version is 3.2.0, with releases occurring periodically to introduce new features (like asynchronous command handling) and address minor improvements or fixes. A key differentiator is its built-in fuzzy matching capabilities, which allow for abbreviated command names (down to three characters) and tolerate minor spelling mistakes, enhancing the user experience. It also provides options for strict command matching when exactness is required, and supports asynchronous command execution via `parseAsync` for modern Node.js applications.","status":"active","version":"3.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/mcollina/commist","tags":["javascript"],"install":[{"cmd":"npm install commist","lang":"bash","label":"npm"},{"cmd":"yarn add commist","lang":"bash","label":"yarn"},{"cmd":"pnpm add commist","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Explicitly recommended and often required for parsing arguments within registered commands.","package":"minimist","optional":false}],"imports":[{"note":"Commist is primarily designed for CommonJS. It exports a factory function that returns the program instance. For ESM, you might need `import * as commistModule from 'commist'; const commist = commistModule.default || commistModule;` but direct CJS `require` is the canonical usage.","wrong":"import commist from 'commist'","symbol":"commist","correct":"const commist = require('commist')"},{"note":"Use `register` for both synchronous and asynchronous command handlers. The choice between `parse` and `parseAsync` determines how they are invoked.","wrong":"program.registerAsync('command-name', async function(args) { /* ... */ })","symbol":"program.register","correct":"program.register('command-name', function(args) { /* ... */ })"},{"note":"Use `parse` for synchronous command execution. If any registered command is `async`, it will return a Promise which will not be awaited. For proper async handling, use `parseAsync`.","wrong":"await program.parse(process.argv.splice(2))","symbol":"program.parse","correct":"const result = program.parse(process.argv.splice(2))"},{"note":"`parseAsync` was added in v3.2.0. It allows registered `async` command handlers to be awaited. Always `await` its return value.","wrong":"const result = program.parseAsync(process.argv.splice(2))","symbol":"program.parseAsync","correct":"const result = await program.parseAsync(process.argv.splice(2))"}],"quickstart":{"code":"import { fileURLToPath } from 'url';\nimport { dirname } from 'path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Minimalist CommonJS emulation for commist in ESM context\n// In a pure CommonJS project, use: const commist = require('commist');\n// and: const minimist = require('minimist');\nimport commistModule from 'commist';\nconst commist = commistModule.default || commistModule;\n\nimport minimistModule from 'minimist';\nconst minimist = minimistModule.default || minimistModule;\n\nasync function executeCommand(args) {\n  console.log(`Executing with args: ${JSON.stringify(args)}`);\n  return new Promise(resolve => setTimeout(resolve, 500));\n}\n\nasync function doOtherStuff() {\n  console.log('Doing other stuff...');\n  return new Promise(resolve => setTimeout(resolve, 200));\n}\n\nconst program = commist();\n\nconst argsToParse = process.argv.splice(2);\n\nasync function main() {\n  const result = await program\n    .register('start', async function(args) {\n      console.log('START command received.');\n      await executeCommand(args);\n      await doOtherStuff();\n      console.log('START command finished.');\n    })\n    .register('stop', function(args) {\n      args = minimist(args);\n      console.log('STOP command received with minimist args:', args);\n    })\n    .register({ command: 'config', strict: true }, async function(args) {\n      console.log('CONFIG command received (strict match).');\n      await executeCommand(args);\n    })\n    .parseAsync(argsToParse);\n\n  if (result) {\n    console.log('No command matched. Remaining arguments:', result);\n    console.log('Try: node your_script.js sta --port 3000');\n    console.log('Or: node your_script.js conf set --user admin');\n  }\n}\n\nmain().catch(err => {\n  console.error('An error occurred:', err);\n  process.exit(1);\n});","lang":"typescript","description":"This quickstart demonstrates how to set up a multi-command CLI using `commist` with `parseAsync` for handling asynchronous operations. It shows command registration, argument parsing with `minimist`, strict command matching, and how to capture unmatched arguments. The example includes both synchronous and asynchronous command handlers."},"warnings":[{"fix":"Ensure you are using `commist` v3.1.2 or newer to reliably use the `maxDistance` option for command matching.","message":"The `maxDistance` option, used for limiting fuzzy matching distance, was introduced in v3.1.0, then immediately reverted in v3.1.1 due to issues, and finally re-added and stabilized in v3.1.2. If you relied on `maxDistance` in v3.1.0, it was likely buggy, and if you used v3.1.1, it was entirely absent.","severity":"gotcha","affected_versions":"v3.1.0, v3.1.1"},{"fix":"For ESM, explicitly handle the default export: `import commistModule from 'commist'; const commist = commistModule.default || commistModule;`. For CommonJS, stick to `const commist = require('commist')`.","message":"Commist is primarily a CommonJS module. While it can be imported into ESM projects using compatibility layers, its intended and most straightforward usage is with `require()`. Attempting direct `import commist from 'commist'` in ESM without proper transpilation or `default` handling may lead to `TypeError` or `undefined` imports.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Upgrade your `commist` package to v3.2.0 or newer: `npm install commist@latest`.","cause":"Attempting to use the `parseAsync` method with an older version of `commist` that predates its introduction.","error":"TypeError: program.parseAsync is not a function"},{"fix":"Install `minimist` (`npm install minimist`) and import it in your application, typically within your command handler functions: `const minimist = require('minimist');`.","cause":"While `commist` is designed to be used with `minimist` for argument parsing, `minimist` is not a direct runtime dependency of `commist` and must be installed and imported separately by the user.","error":"ReferenceError: minimist is not defined"},{"fix":"Double-check command spelling, ensure the command is registered, or remove `strict: true` from the command registration if you intend to use `commist`'s fuzzy matching capabilities.","cause":"This message indicates that `commist` could not find a matching command. This could be due to a typo, using a command that isn't registered, or using `strict: true` on a command when the input doesn't match exactly, disabling fuzzy matching.","error":"No command called, args [ 'your', 'command', 'and', 'args' ] (or similar output)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}