PHPackages                             henze/cmdr - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. henze/cmdr

Abandoned → [henzeb/cmdr](/?search=henzeb%2Fcmdr)Library[CLI &amp; Console](/categories/cli)

henze/cmdr
==========

A framework in pure bash

v0.0.1(1mo ago)01MITShellPHP &gt;=8.0

Since Apr 18Pushed 1mo agoCompare

[ Source](https://github.com/henzeb/cmdr)[ Packagist](https://packagist.org/packages/henze/cmdr)[ RSS](/packages/henze-cmdr/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)DependenciesVersions (3)Used By (0)

cmdr
====

[](#cmdr)

[![Latest Version](https://camo.githubusercontent.com/8ea107f52ac3454b8b69504fd86edf5deba26e305312d22af3e30287cbead6c1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f68656e7a65622f636d64722e737667)](https://packagist.org/packages/henzeb/cmdr)[![Total Downloads](https://camo.githubusercontent.com/cd88def94855676cb55458bc60a67107385f926da54a196a24e624d526f2918e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f68656e7a65622f636d64722e737667)](https://packagist.org/packages/henzeb/cmdr)[![License](https://camo.githubusercontent.com/0fa91165e1e336da23017c84125e22f631201b5ffc122b2d832ce77c524cbcea/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f68656e7a65622f636d64722e737667)](https://packagist.org/packages/henzeb/cmdr)

A pure Bash framework for crafting beautiful, reusable commands.

Every project accumulates scripts for mundane tasks — spinning up local environments, managing Kubernetes clusters, or running a test suite in a loop to catch flaky tests. They work, but they sprawl. New team members have no idea what exists, what arguments a script expects, or what it will actually do. The answer is usually a wall of `--help` text nobody wrote, or a wiki page nobody updated.

Tools like [bashly](https://bashly.dev/) and [bash-it](https://github.com/Bash-it/bash-it) solve adjacent problems: bashly generates CLI apps from YAML but requires a build step and a Ruby runtime; bash-it is a personal shell framework for customizing your own environment, not for sharing commands with a team. Neither gives you a way to distribute a consistent set of commands through your project's own dependencies.

cmdr does. Install it per-project via Composer, add your functionality in the project's `.cmdr` directory and your whole team gets the same commands after `composer install` — with argument parsing, validation, interactive prompts, tab completion, and help pages built in. No build step. No runtime beyond Bash.

---

Features
--------

[](#features)

- **Modules** — organize commands into namespaced modules; add, override, or extend them per-project or globally
- **No build step** — pure Bash, sourced directly; requires Bash 4.3+
- **Declarative args &amp; options** — define positional arguments and flags with types, defaults, and descriptions
- **Validation** — 30+ built-in rules with support for custom rules and named groups
- **Interactive input** — built-in prompts (text, confirm, select, multiselect) with validation support
- **Shell completion** — tab completion for Bash, Zsh, and Fish
- **Hooks** — event-driven extension points for modules
- **Scaffold generator** — `cmdr make module` bootstraps a new module from a template
- **Composer-distributed** — install globally or per-project like any other package

---

Installation
------------

[](#installation)

**Requirements:** Bash 4.3+. macOS ships with Bash 3.2 — install a modern version via Homebrew (`brew install bash`). Composer is required to install cmdr.

**Global** (available system-wide):

```
composer global require henze/cmdr
```

Make sure Composer's global `bin` directory is on your `PATH`. Run `composer global config bin-dir --absolute` to find the path, then add it to your shell config.

**Per-project** (shared with your team as a Composer dependency):

```
composer require --dev henze/cmdr
./vendor/bin/cmdr alias   # optional: creates a shell alias for this project
```

See [docs/installation.md](docs/installation.md) for full PATH setup instructions and how to combine both approaches.

---

Usage
-----

[](#usage)

```
cmdr help                          # list all available commands
cmdr  help                 # list commands in a module
cmdr           # run a command
cmdr   --help  # show command help
```

---

Documentation
-------------

[](#documentation)

- [Installation](docs/installation.md)
    - [Requirements](docs/installation.md#requirements)
    - [Installing globally](docs/installation.md#installing-globally)
    - [Installing per project](docs/installation.md#installing-per-project)
    - [Combining both](docs/installation.md#combining-both)
- [Configuration](docs/configuration.md)
    - [Config file locations](docs/configuration.md#config-file-locations)
    - [Using global flags](docs/configuration.md#using-global-flags)
    - [Available config variables](docs/configuration.md#available-config-variables)
- [Directory Structure](docs/structure.md)
    - [The project directory](docs/structure.md#the-project-directory)
    - [The global directory](docs/structure.md#the-global-directory)
    - [Load order](docs/structure.md#load-order)
- [Modules](docs/modules.md)
    - [Choosing a layout](docs/modules.md#choosing-a-layout)
    - [Search paths](docs/modules.md#search-paths)
    - [Creating a module](docs/modules.md#creating-a-module)
    - [Adding submodules](docs/modules.md#adding-submodules)
    - [Declaring dependencies with cmdr::use](docs/modules.md#declaring-dependencies-with-cmdrus)
    - [Conditional loading](docs/modules.md#conditional-loading)
    - [Registering aliases](docs/modules.md#registering-aliases)
    - [Locking and hiding](docs/modules.md#locking-and-hiding)
    - [Registering root commands](docs/modules.md#registering-root-commands)
    - [Native help](docs/modules.md#native-help)
    - [Finding the project root](docs/modules.md#finding-the-project-root)
    - [Dynamic tab completion](docs/modules.md#dynamic-tab-completion)
    - [Distributing a module as a Composer package](docs/modules.md#distributing-a-module-as-a-composer-package)
- [Hooks](docs/hooks.md)
    - [Registering a listener](docs/hooks.md#registering-a-listener)
    - [Implementing listeners](docs/hooks.md#implementing-listeners--hookssh)
    - [Firing a hook](docs/hooks.md#firing-a-hook)
    - [Discovering hook files](docs/hooks.md#discovering-hook-files)
    - [Naming hooks](docs/hooks.md#naming-hooks)
    - [Handling return values](docs/hooks.md#handling-return-values)
    - [Bootstrap hooks](docs/hooks.md#bootstrap-hooks)
- [Arguments &amp; Options](docs/args.md)
    - [Declaring arguments](docs/args.md#declaring-arguments)
    - [Retrieving values](docs/args.md#retrieving-values)
    - [Passthrough arguments](docs/args.md#passthrough-arguments)
    - [Using global options](docs/args.md#using-global-options)
- [Output](docs/output.md)
    - [Output helpers](docs/output.md#output-helpers)
    - [Progress bar](docs/output.md#progress-bar)
    - [Task list](docs/output.md#task-list)
    - [Configuring output](docs/output.md#configuring-output)
- [Input](docs/input.md)
    - [Prompt helpers](docs/input.md#prompt-helpers)
    - [The description argument](docs/input.md#the-description-argument)
    - [Using input with validation](docs/input.md#using-input-with-validation)
- [Shell Completion](docs/completion.md)
    - [Installing completion](docs/completion.md#installing-completion)
    - [What gets completed](docs/completion.md#what-gets-completed)
    - [Registering dynamic completers](docs/completion.md#registering-dynamic-completers)
- [Validation](docs/validation.md)
    - [Creating named validator groups](docs/validation.md#creating-named-validator-groups)
    - [Validating interactive input](docs/validation.md#validating-interactive-input)
    - [Built-in rules](docs/validation.md#built-in-rules)
    - [Writing custom rules](docs/validation.md#writing-custom-rules)
    - [Overriding error messages](docs/validation.md#overriding-error-messages)
- [Composer utilities](docs/composer.md)
    - [Checking for a package](docs/composer.md#checking-for-a-package)
    - [Inspecting versions](docs/composer.md#inspecting-versions)
- [JSON utilities](docs/json.md)
    - [Extracting a value](docs/json.md#extracting-a-value)
- [Shell helpers](docs/shell.md)
    - [Writing to the shell config](docs/shell.md#writing-to-the-shell-config)
    - [Checking the environment](docs/shell.md#checking-the-environment)
- [Callers](docs/callers.md)
    - [Re-invoking cmdr](docs/callers.md#re-invoking-cmdr)
    - [Resolving external commands](docs/callers.md#resolving-external-commands)
    - [Registering candidates](docs/callers.md#registering-candidates)
- [Scaffolding](docs/make.md)
    - [Scaffolding a module](docs/make.md#scaffolding-a-module)
    - [Generated files](docs/make.md#generated-files)
    - [Registering a custom scaffold type](docs/make.md#registering-a-custom-scaffold-type)
    - [Using the scaffold API](docs/make.md#using-the-scaffold-api)
    - [Placeholder substitution](docs/make.md#placeholder-substitution)
- Shipped modules
    - [init](docs/modules/init.md)
    - [docker](docs/modules/docker.md)

###  Health Score

33

—

LowBetter than 73% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity30

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

2

Last Release

51d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/15928532?v=4)[henzeb](/maintainers/henzeb)[@henzeb](https://github.com/henzeb)

---

Top Contributors

[![henzeb](https://avatars.githubusercontent.com/u/15928532?v=4)](https://github.com/henzeb "henzeb (1 commits)")

### Embed Badge

![Health badge](/badges/henze-cmdr/health.svg)

```
[![Health](https://phpackages.com/badges/henze-cmdr/health.svg)](https://phpackages.com/packages/henze-cmdr)
```

###  Alternatives

[seld/cli-prompt

Allows you to prompt for user input on the command line, and optionally hide the characters they type

24726.4M22](/packages/seld-cli-prompt)[illuminate/console

The Illuminate Console package.

13045.3M6.1k](/packages/illuminate-console)[php-tui/php-tui

Comprehensive TUI library heavily influenced by Ratatui

596920.8k12](/packages/php-tui-php-tui)[styleci/cli

The CLI tool for StyleCI

70464.1k9](/packages/styleci-cli)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
