myapp/ ├── routes/ │ ├── greet.py → myapp greet │ └── server/ │ ├── start.py → myapp server start │ └── stop.py → myapp server stop
Here's an example of what defining a command looks like in one of these files. Note that it's very similar to Click.
@command() def _(name: str, template: str = "Hello, {}!") -> None: """Greet someone.""" print(template.format(name))
The custom parser is ~25x faster than Click and ~170x faster than Typer for dispatch (2.7 µs vs 72 µs vs 496 µs for a simple command). Also includes Rich-formatted help, WithConfig[T] for config/env/CLI flag layering, agent-optimized help output (auto-detects non-TTY → compact format for LLM tool calls), and an optional manifest compiler to skip route-walking in large codebases.
This started as an exploration of whether file-based routing (inspired by Next.js) could work in the CLI world. It works surprisingly well, especially for projects with lots of subcommands where finding the right add_subcommand call becomes a chore.
I've been using this for many of my other projects like https://codeberg.org/thatxliner/codeberg-cli and https://github.com/ThatXliner/git-worm