Building and distributing your CLIs¶
To build and distribute you own CLI I recommend you use uv..
In this quick walkthrough we'll be creating a CLI called zit, a basic clone of git.
Creating a new CLI¶
First, you'll want to create a project. For that, follow uv's most up to date documentation about creating a new project.
A quick summary at the time of writing is:
-
Create a project directory:
mkdir zitcd zit -
Initialize a project:
uv init -
Install clypi:
uv add clypi -
Code your CLI.
uvcreated amain.pyfile but you should create your own python package inside a subdirectory calledzit. Inside that subdirectory create an empty file called__init__.pyand a file calledmain.pywith the following content:tree.
├── README.md
├── pyproject.toml
├── uv.lock
└── zit
├── init.py
└── main.py# zit/main.py import clypi from clypi import Command, arg class Zit(Command): """ A git clone, but much slower ;) """ verbose: bool = arg(False, short="v") async def run(self): clypi.cprint("Sorry I don't know how to use git, it's too hard!", fg="yellow") if self.verbose: clypi.cprint("asdkjnbsvaeusbvkajhfnuehfvousadhvuashfqei" * 100) def main(): """ This will be the entrypoint for our CLI """ zit = Zit.parse() zit.start() if __name__ == "__main__": main() -
Test out your new CLI. You can run it locally with:
uv run ./zit/main.py -
You'll need to add a build system so that
uvunderstands this is a package you want to distribute and people to install. Add the following to yourpyproject.toml -
Add an entrypoint to your Python package. This tells Python how to execute your program. Add the following lines to your
pyproject.toml -
Install your package locally and run it
Building and distributing your CLI¶
I highly recommend you follow uv's guide on building an publishing packages.
The TLDR is uv build then uv publish, but you'll want to set up your project with the right metadata. The official packaging Python guide is really good to configure all you'll need for distributing a quality package.
[Advanced] Pre-built binaries (Shivs 🔪)¶
Shiv's provide an easy way to bundle Python code into an executable file. Shiv's are, essentially, an executable zip file with Python files inside.
To build a shiv with uv and clypi given the above zit example, run:
You now have a binary (zit-bin) that you can distribute and run like any other binary. You'll have to manually add it to a $PATH location though (What is $PATH?).