{"id":16212,"library":"shell","title":"Shell CLI Argument Parser and Router","description":"Shell.js is a declarative command-line argument parser and stringifier for Node.js, currently at version 0.12.0, with its latest update published approximately a year ago. It's designed to simplify the creation of complex CLI applications by providing a structured way to define options, commands, and their associated routing logic. Key features include automatic argument discovery, support for multi-level commands (e.g., `git pull origin main`), built-in type conversion for arguments (string, boolean, integer, array), and auto-generated help messages. It differentiates itself through a declarative API that integrates parsing, stringifying, and routing into a single configuration object, making CLI development more intuitive than some imperative alternatives. The package is actively maintained and currently requires Node.js version 20 or later.","status":"active","version":"0.12.0","language":"javascript","source_language":"en","source_url":"git://github.com/adaltas/node-shell","tags":["javascript","shell","cli","arguments","parser","parameters","param","option","command"],"install":[{"cmd":"npm install shell","lang":"bash","label":"npm"},{"cmd":"yarn add shell","lang":"bash","label":"yarn"},{"cmd":"pnpm add shell","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The 'shell' function is a named export, not a default export, since version 0.12.0 and later. Using a default import will result in 'undefined' or a runtime error.","wrong":"import shell from 'shell';","symbol":"shell","correct":"import { shell } from 'shell';"},{"note":"The modern API in 0.12.0+ emphasizes a declarative configuration object passed to the named 'shell' function, followed by '.route()' to process arguments and invoke commands. Direct access to 'parse' or other methods without prior configuration is generally not the intended pattern.","wrong":"const cli = require('shell');\ncli.parse(process.argv.slice(2)); // Old imperative API or partial usage","symbol":"CLI Application Initialization","correct":"const cli = shell({\n  name: 'my-app',\n  description: 'My CLI application',\n  options: { version: { shortcut: 'v', description: 'Show version' } },\n  commands: { start: { description: 'Start the application' } }\n});\ncli.route();"},{"note":"While the project primarily promotes ESM, CommonJS usage requires destructuring the 'shell' named export. Attempting to import the entire module as a default export in CJS will not work as expected with the current API design.","wrong":"const shell = require('shell');","symbol":"CommonJS Require","correct":"const { shell } = require('shell');"}],"quickstart":{"code":"import { shell } from 'shell';\n\nconst myCli = shell({\n  name: 'complex-app',\n  description: 'A robust command-line application demonstrating parsing and routing.',\n  options: {\n    verbose: { shortcut: 'v', description: 'Enable verbose logging', type: 'boolean' },\n    config: { shortcut: 'c', description: 'Path to configuration file', type: 'string', default: './config.json' }\n  },\n  commands: {\n    start: {\n      description: 'Start a service or process.',\n      options: {\n        port: { shortcut: 'p', description: 'Port to listen on', type: 'integer', default: 3000 }\n      },\n      main: async ({ options }) => {\n        console.log(`Starting service on port ${options.port} with config: ${options.config} (verbose: ${options.verbose})`);\n        // Simulate async operation\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Service started successfully.');\n      }\n    },\n    stop: {\n      description: 'Stop a running service.',\n      main: () => {\n        console.log('Stopping service...');\n        console.log('Service stopped.');\n      }\n    }\n  }\n});\n\nmyCli.route().catch(err => {\n  console.error('CLI Error:', err.message);\n  process.exit(1);\n});\n\n// To run this: save as `cli.js`, add `\"type\": \"module\"` to package.json.\n// Then run: `node cli.js start -p 8080 --verbose` or `node cli.js stop -c my-dev-config.json`","lang":"javascript","description":"This quickstart defines a CLI with global options, subcommands, and subcommand-specific options, demonstrating the declarative API for parsing and routing with `shell.js`."},"warnings":[{"fix":"Ensure your project runs on Node.js v20 or a newer compatible version. Update your runtime environment if necessary.","message":"Version 0.12.0 (latest) officially requires Node.js v20 or later. Older Node.js versions, particularly those indicated in outdated `package.json` snippets (like `node >= 0.10.x`), are not supported and will likely lead to runtime errors or unexpected behavior due to modern JavaScript features and API usage.","severity":"breaking","affected_versions":">=0.12.0"},{"fix":"Always use named imports for ESM (`import { shell } from 'shell';`) and destructuring for CommonJS (`const { shell } = require('shell');`).","message":"The `shell` module exports a named function, not a default export. Attempting to `import shell from 'shell'` (default import) or `const shell = require('shell')` (CommonJS default require) will result in `undefined` or a `TypeError` when trying to invoke it as a function.","severity":"gotcha","affected_versions":">=0.12.0"},{"fix":"Structure your CLI definition using the configuration object and call `myCli.route()` to activate parsing and command execution. Refer to the official documentation for the complete declarative API pattern.","message":"The `shell.js` API relies heavily on a declarative configuration object passed to the main `shell()` function. Attempting to directly call methods like `parse` or `stringify` without first defining your CLI structure via the configuration object and `route()` call is not the intended modern usage and may lead to errors or incomplete functionality.","severity":"gotcha","affected_versions":">=0.12.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Change your import statement to `import { shell } from 'shell';` to correctly access the named export.","cause":"Incorrectly importing the `shell` module as a default import when it's a named export, common in TypeScript or Babel setups where transpilation might obscure the direct named import error.","error":"TypeError: (0 , shell_1.shell) is not a function"},{"fix":"If working in an ES module environment, use `import { shell } from 'shell';`. If you must use CommonJS, ensure your file is `.cjs` or your `package.json` does not specify `\"type\": \"module\"` for that context.","cause":"Attempting to use `require()` in a JavaScript file that is treated as an ES module (e.g., due to `\"type\": \"module\"` in `package.json` or `.mjs` extension) without proper CommonJS fallback or ESM compatibility.","error":"ReferenceError: require is not defined in ES module scope"},{"fix":"Ensure that the command you are trying to run is explicitly defined within the `commands` object when you initialize your `shell` instance, or check for typos in the command name.","cause":"Attempting to execute a command that has not been defined in the `commands` object of the `shell()` configuration.","error":"Error: Command 'unknown-command' not found."}],"ecosystem":"npm"}