Bashly: generate a standalone bash CLI from a YAML file
Bash command line framework and CLI generator
At a glance
- What is it?
- Bashly is a Ruby command line tool that turns a YAML description of commands, arguments and flags into one shellcheck-compliant bash script. It suits people who want a real CLI without writing an argument parser by hand.
- Who is it for?
- Adopt Bashly when you need a distributable bash tool with real argument parsing, help screens and man pages, and you accept that the generated script is the artifact you ship. Skip it if your tool is a handful of lines, if you cannot add Ruby to your build step, or if you need to edit the parser by hand, because the generator owns that code.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Bashly solves for people who ship shell tools
Writing a bash script is easy. Writing a bash script that accepts sub-commands, validates required flags, prints a usable help screen, handles --version, and does all of that consistently across twenty commands is not. That work is normally done by a framework in other languages. Bashly is that framework for bash, and the README states the goal plainly: it lets you focus on your specific code, without worrying about command line argument parsing, usage texts, error messages and other functions that are usually handled by a framework in any other programming language.
The audience is narrow but real. It is for engineers who must deliver a tool as a shell script, usually because the target machines have nothing but bash, and who still want the ergonomics of a generated CLI. The output is a single, standalone bash script, so the consumer of your tool installs one file. Bashly itself is written in Ruby and is distributed as a gem and as a Docker image, which means the build machine needs Ruby or Docker, but the machine running your generated script does not.
The YAML to bash data flow
The mechanism is a code generator, not a runtime library. Nothing from Bashly is sourced when your script runs. The README describes three steps. You provide a YAML configuration file describing commands, sub-commands, arguments and flags. Running bashly init creates an initial sample YAML file for you. Then bashly generate produces the bash script, which parses and validates user input, provides help messages, and runs your code for each command.
The part that matters for day to day work is where your code lives. Each command's implementation is kept in a separate file, and Bashly merges those files back into the final script. The README points at examples/minimal/src/root_command.sh as an example of that layout. So the repository you maintain has a src directory of small shell files plus one YAML file, and the generated script is a build artifact. The README also states that the generated script is human readable, shellcheck-compliant and shfmt-compliant, which is a concrete claim you can check against your own output rather than take on faith.
Beyond parsing, Bashly optionally provides framework-style standard library functions: color output, config file management in INI format, YAML parsing and bash completions. It also auto-generates markdown and man page documentation for your script. The Dockerfile confirms the man page path by installing pandoc specifically to support manpage generation.
Installing Bashly and generating your first CLI
The README lists two distribution channels: a ruby gem and a docker image. With Ruby available, the gem is the direct route.
gem install bashlyAfter that, create a working directory and initialize a sample configuration. The README states that bashly init creates an initial sample YAML file for you.
bashly initYou should now have a bashly.yml in the directory. Edit it to describe your commands, arguments and flags, then generate the script.
bashly generateThe result is a single standalone bash script. Run it with --help to see the usage text Bashly generated from your YAML, and with --version to see the standard version flag. Your per-command code goes into files under src, following the layout shown in examples/minimal, where root_command.sh holds the root command's implementation. If you prefer not to install Ruby, the Docker image dannyben/bashly is the alternative, and the repository's docker-compose.yml shows a bashly service built from the project Dockerfile with an entrypoint of bashly.
Where the generator model gets in the way
The generated script is the product, and that is also the constraint. Because Bashly owns argument parsing, help text and error handling, you do not hand-edit those parts of the output. Any change to the CLI surface goes through bashly.yml and a regeneration. If your requirement is a parsing behaviour the YAML schema does not express, the framework is the wrong tool, and you will spend more time fighting the schema than you would have spent writing the parser.
The build dependency is the second limitation. Bashly is written in Ruby, so the machine that builds the script needs Ruby or Docker. That is a real constraint in environments where the whole point of using bash is that nothing else is installed. The consumer side is unaffected, since the generated script is standalone, but the pipeline that produces releases is not.
The third point is about trust in generated code. The README claims the output is human readable and passes shellcheck and shfmt. That is a claim about the generator's output, not a guarantee about your src files, which are merged in as you wrote them. A reviewer who only reads the generated script will be reading a mix of generated boilerplate and your code, and it is worth being explicit with your team about which parts are regenerated and which are yours to edit.
Bashly compared with Argbash
Argbash appears in the related searches for this project, and the difference in approach is worth stating. Argbash also generates argument parsing for shell scripts, but it works by inserting a parsing block into an existing script rather than owning a separate YAML definition and a src directory of command files. With Bashly you describe the whole CLI, including sub-commands and nested commands, in one configuration file and regenerate a complete script. With an in-script generator the script remains the source of truth and the parser is a section inside it.
The practical consequence is where the complexity sits. Bashly puts it in a YAML schema that must express every command, argument and flag, plus a directory of implementation files that get merged. The in-script approach keeps everything in one file but leaves you maintaining the parser block alongside your own code. If your CLI is a single command with a few flags, the second approach is less machinery. If it is a command tree with sub-commands, help screens per command and generated man pages, Bashly's model is the one that scales, because the YAML is the specification.
Maintenance status, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-27, with v2.0.0 released the same day, v1.4.0 on 2026-07-09 and v1.3.8 on 2026-03-23. A major version bump is the thing to plan around: v2.0.0 landing alongside the current master means the project is willing to make breaking changes, and the CHANGELOG.md in the repository root is where those are recorded. Pin the gem version in your build rather than tracking latest, and read the changelog before moving from 1.x to 2.x.
The licence is MIT, which is permissive and imposes no copyleft obligation on the scripts you generate. That matters here because the generated script is derived from Bashly's generator output, and a permissive licence keeps that straightforward. This is a description of the licence identifier, not legal advice; if your organisation has specific requirements about generated code, raise it with whoever handles licensing.
Upgrade cost is mostly mechanical. Since the generated script is rebuilt from YAML and src files, an upgrade means regenerating and diffing the output. The risk is concentrated in schema changes between major versions, and the mitigation is the same as any code generator: keep the generated script in version control so a regeneration produces a reviewable diff rather than a surprise.
Editorial conclusion
Adopt Bashly when you need a distributable bash tool with real argument parsing, help screens and man pages, and you accept that the generated script is the artifact you ship. Skip it if your tool is a handful of lines, if you cannot add Ruby to your build step, or if you need to edit the parser by hand, because the generator owns that code. Before committing, run bashly init and bashly generate on your own command tree and read the generated script, especially the parts you expected to write yourself.
Frequently asked questions
What is Bashly and what does it generate?
Bashly is a command line application written in Ruby that generates feature-rich bash command line tools from a YAML configuration file. The output is a single, standalone bash script that parses and validates user input and provides help messages.
How do I install Bashly?
The README lists two options: the ruby gem and the docker image dannyben/bashly. With Ruby available, the gem installs with gem install bashly.
Where does my own command code go in a Bashly project?
Each command's code is kept in a separate file and merged back into the final script when you generate. The README points to examples/minimal/src/root_command.sh as the example layout.
Is bashly a word?
The README does not discuss the word itself. Bashly is the name of the Ruby command line framework and CLI generator distributed as a gem and a Docker image.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bashly-framework-bashly)