# comfy-cli: A Command Line Tool for ComfyUI
[](https://github.com/Comfy-Org/comfy-cli/actions/workflows/pytest.yml)
[](https://codecov.io/github/Comfy-Org/comfy-cli)
[](https://pypi.org/project/comfy-cli/)
[](https://pepy.tech/project/comfy-cli)
[](https://pypi.org/project/comfy-cli/)
[](https://github.com/Comfy-Org/comfy-cli/blob/main/LICENSE)
comfy-cli is a command-line tool for installing, running, and extending
[ComfyUI](https://github.com/comfyanonymous/ComfyUI) β the open-source
generative-media engine. Set up ComfyUI, install custom nodes and models, run
workflows, and call hosted partner image models, all from your terminal.
## Demo
## Features
- π One-command ComfyUI install and launch
- π¨ Direct calls to partner image and video nodes (Flux, Ideogram, DALLΒ·E, Recraft, Reve, Gemini/nano-banana, Kling, Luma, Runway, Pika, Vidu, Hailuo, Seedance, β¦) via `comfy generate`, no workflow JSON required
- π§ Custom node management β install, update, snapshot, bisect
- π¦ Fast dependency resolution with `uv` (`--fast-deps`, `--uv-compile`)
- ποΈ Model downloads from CivitAI, Hugging Face, and direct URLs
- π¬ Run workflows against a local ComfyUI server, including auto-conversion of UI-format JSON
- π§ͺ Test ComfyUI and frontend pull requests with one flag
- π» Cross-platform: Windows, macOS, Linux
- βοΈ Route any workflow to **Comfy Cloud** with `--where cloud` (no GPU required)
- π€ Agent-friendly: every command emits structured `--json` envelopes
- π Bundled skills teach Claude / Cursor to drive comfy natively
## Quick Start
```bash
pip install comfy-cli
comfy setup
```
`comfy setup` walks you through everything β local or cloud routing, authentication, and agent skill installation β in one interactive wizard. Pass `-y` for non-interactive (CI/scripted) installs.
## Run a workflow in the cloud
No local GPU? Route any API-format workflow to [Comfy Cloud](https://www.comfy.org/) with `--where cloud`:
```bash
comfy cloud login # sign in via your browser (OAuth)
comfy run --workflow ./workflow.json --where cloud # submits, prints a prompt_id, returns immediately
comfy jobs wait --where cloud # block until the job finishes (or: jobs status for a one-shot check)
comfy download --where cloud -o ./outputs # save the results locally
```
`comfy run` submits asynchronously and prints the `prompt_id` you feed to `jobs`/`download`; add `--wait` to block inline instead. Check your sign-in anytime with `comfy cloud whoami`. Export the workflow JSON from ComfyUI via **File β Export (API)** (UI-format JSON is auto-converted). Set cloud as your default target so you can drop the flag: `comfy set-default --where cloud`.
**Credits:** cloud generation (`comfy run --where cloud`, `comfy generate`) consumes Comfy Cloud credits and needs an active subscription. Discovery and inspection commands β `comfy cloud whoami`, `comfy cloud status`, `comfy jobs status/ls`, `comfy templates ls`, `comfy generate list` β don't. Check your balance and tier with `comfy cloud status`.
## Installation
1. (Recommended) Activate a virtual environment ([venv](https://docs.python.org/3/library/venv.html) or [conda](https://conda.io/projects/conda/en/latest/user-guide/getting-started.html)).
2. Install with `pip` (requires Python 3.10+):
```bash
pip install comfy-cli
```
### Shell Autocomplete
Install shell completion so `comfy ` expands commands and options:
```bash
comfy --install-completion
```
## Usage
### Installing ComfyUI
To install ComfyUI using comfy, simply run:
`comfy install`
This command will download and set up the latest version of ComfyUI and ComfyUI-Manager on your
system. If you run in a ComfyUI repo that has already been setup. The command
will simply update the comfy.yaml file to reflect the local setup
- `comfy install --skip-manager`: Install ComfyUI without ComfyUI-Manager.
To use a custom Manager fork or specific version, skip the default installation
and install your own into the workspace venv:
```bash
comfy install --skip-manager
# Then install your custom Manager:
pip install -e /path/to/your-manager-fork # editable install
# or
pip install comfyui-manager==4.1b8 # specific version
```
- `comfy --workspace= install`: Install ComfyUI into `/ComfyUI`.
- `comfy install --fast-deps`: Use `uv` instead of `pip` for faster dependency resolution
during initial ComfyUI installation. comfy-cli's built-in resolver compiles all requirements (core + custom nodes)
into a single lockfile and installs from it. Also handles GPU-specific PyTorch wheel selection automatically.
- For `comfy install`, if no path specification like `--workspace, --recent, or --here` is provided, it will be implicitly installed in `/comfy`.
#### Python environment handling
When you run `comfy install`, comfy-cli picks a Python environment for ComfyUI
dependencies using the following precedence:
1. An **active virtualenv or conda** environment (`VIRTUAL_ENV` / `CONDA_PREFIX`) is used as-is.
2. An **existing `.venv` or `venv`** directory inside the workspace is reused.
3. Otherwise the choice depends on how comfy-cli was installed:
- **`pip install comfy-cli`** (global / system Python): dependencies go
directly into the same Python environment. This is the typical Docker setup.
- **`pipx install comfy-cli`** or **`uv tool install comfy-cli`** (isolated
tool environment): a `.venv` is created inside the ComfyUI workspace.
Use `comfy launch` to start ComfyUI with the correct Python.
### Updating ComfyUI
`comfy update` brings an existing workspace up to date:
- `comfy update` (or `comfy update comfy`): pull the branch the workspace is currently on and reinstall `requirements.txt`.
- `comfy update all`: also update every installed custom node.
- `comfy update cli`: upgrade comfy-cli itself.
By default `comfy update all` exits 0 even when the custom-node update step fails β the error is printed, but the exit code says success, so scripts and wrappers can't tell. Pass `--exit-on-fail` (the same flag name and default as `comfy node install --exit-on-fail`) to have that failure exit non-zero instead. The flag only changes the `all` target; `comfy update comfy` and `comfy update cli` already exit non-zero when they fail, and accept the flag as a no-op so it can be forwarded unconditionally.
One limit worth knowing: `--exit-on-fail` can only surface what ComfyUI-Manager's `cm-cli update` reports. `cm-cli` currently handles a *single* pack failing to update by printing `ERROR: ...` and carrying on, still exiting 0, so that particular case stays invisible until ComfyUI-Manager propagates it. Unlike `comfy node install`, the flag is not forwarded to `cm-cli` β only its `install` subcommand accepts `--exit-on-fail`; its `update` subcommand has no such option and would reject it.
When the flag does fire, the exit code is `cm-cli`'s own, normalized so it is always usable: a process killed by a signal becomes `128+N` rather than a truncated value, an exit code that would truncate to 0 becomes 1, and 2 becomes 1 so it can't be mistaken for a CLI usage error. In `--json` mode the failure is also reported as an `update_custom_nodes_failed` error envelope carrying `cm-cli`'s raw status in `details.cm_cli_returncode`.
#### Switching to a specific version
`comfy update comfy --version ` moves an existing workspace to a specific ComfyUI version β a downgrade (rollback) or an upgrade β without prompting for anything, so it is safe to run headlessly or from a script. `` is `nightly` (the repo's default branch), `latest` (the newest stable release), or a version number such as `0.3.0` (a leading `v` is optional).
```bash
comfy update comfy --version 0.3.0 # roll back to the v0.3.0 release
comfy update comfy --version latest # newest stable release
comfy update comfy --version nightly # roll forward to the default branch
```
Behavior worth knowing:
- **The target is validated before anything is touched.** An unknown version exits non-zero, lists the nearest available versions, and leaves the working tree exactly as it was.
- **Uncommitted changes are stashed by default** (`git stash push -u`) and are *never* popped or dropped automatically β the stash ref is printed so you can restore them with `git stash pop`. Pass `--no-stash` if you would rather the command refuse to run on a dirty tree.
- **A version number checks out a tag, which leaves a detached HEAD.** That is expected. Roll forward again with `comfy update comfy --version nightly` (or `--version latest`); a plain `comfy update` cannot advance a detached HEAD.
- **Dependencies are reinstalled** from the target version's `requirements.txt`. PyTorch is deliberately left alone: the ComfyUI version doesn't determine your torch build, your machine does. If the dependency install fails, the command exits non-zero and says so β the tree is already on the new version, and re-running the same command is safe.
- `--version` and `--no-stash` apply only to target `comfy`; combining `--version` with `all` or `cli` is an error.
### Specifying execution path
- You can specify the path of ComfyUI where the command will be applied through path indicators as follows:
- `comfy --workspace=`: Run from the ComfyUI installed in the specified workspace.
- `comfy --recent`: Run from the recently executed or installed ComfyUI.
- `comfy --here`: Run from the ComfyUI located in the current directory.
- --workspace, --recent, and --here options cannot be used simultaneously.
- If there is no path indicator, the following priority applies:
- Run from the default ComfyUI at the path specified by `comfy set-default `.
- Run from the recently executed or installed ComfyUI.
- Run from the ComfyUI located in the current directory.
- Example 1: To run the recently executed ComfyUI:
- `comfy --recent launch`
- Example 2: To install a package on the ComfyUI in the current directory:
- `comfy --here node install comfyui-impact-pack`
- Example 3: To update the automatically selected path of ComfyUI and custom nodes based on priority:
- `comfy node update all`
- You can use the `comfy which` command to check the path of the target workspace.
- e.g `comfy --recent which`, `comfy --here which`, `comfy which`, ...
### Default Setup
The default sets the option that will be executed by default when no specific workspace's ComfyUI has been set for the command.
`comfy set-default ?[--launch-extras=""]`
- `--launch-extras` option specifies extra args that are applied only during launch by default. However, if extras are specified at the time of launch, this setting is ignored.
### Launch ComfyUI
Comfy provides commands that allow you to easily run the installed ComfyUI.
`comfy launch`
- To run with default ComfyUI options:
`comfy launch -- `
`comfy launch -- --cpu --listen 0.0.0.0`
- When you manually configure the extra options, the extras set by set-default will be overridden.
- To run background
`comfy launch --background`
`comfy --workspace=~/comfy launch --background -- --listen 10.0.0.10 --port 8000`
- Instances launched with `--background` are displayed in the "Background ComfyUI" section of `comfy env`, providing management functionalities for a single background instance only.
- Background-running ComfyUI can be stopped with `comfy stop`.
- To point **every** command (not just one) at a ComfyUI on a non-default
address β e.g. a server you started _outside_ comfy-cli on `:8189` β export
the `COMFY_LOCAL_URL` environment variable:
`export COMFY_LOCAL_URL=http://127.0.0.1:8189`
- Accepts `http://host:port`, `host:port`, or `http://host` (the port
defaults to `8188`; the scheme is optional and, if present, must be
`http`). IPv6 literals are bracketed: `COMFY_LOCAL_URL=http://[::1]:8189`.
- Honored by `comfy env`, `comfy run`, `comfy jobs`, `comfy upload`/`download`,
`comfy nodes`, and every other local-targeting command, so `comfy env`'s
"Comfy Server Running" line now probes and reports the resolved address.
- Precedence (per command): a per-command `--host`/`--port` flag wins, then
`COMFY_LOCAL_URL`, then a comfy-cli-launched background server, then the
`127.0.0.1:8188` default. A malformed value is ignored with a one-line
stderr warning rather than breaking the command.
- to run ComfyUI with a specific pull request:
`comfy install --pr "#1234"`
`comfy install --pr "jtydhr88:load-3d-nodes"`
`comfy install --pr "https://github.com/comfyanonymous/ComfyUI/pull/1234"`
- If you want to run ComfyUI with a specific pull request, you can use the `--pr` option. This will automatically install the specified pull request and run ComfyUI with it.
- Important: The --pr option cannot be combined with --version or --commit and will be rejected if used together.
- To test a frontend pull request:
```
comfy launch --frontend-pr "#456"
comfy launch --frontend-pr "username:branch-name"
comfy launch --frontend-pr "https://github.com/Comfy-Org/ComfyUI_frontend/pull/456"
```
- The `--frontend-pr` option allows you to test frontend PRs by automatically cloning, building, and using the frontend for that session.
- Requirements: Node.js and npm must be installed to build the frontend.
- Builds are cached for quick switching between PRs - subsequent uses of the same PR are instant.
- Each PR is used only for that launch session. Normal launches use the default frontend.
**Managing PR cache**:
```
comfy pr-cache list # List cached PR builds
comfy pr-cache clean # Clean all cached builds
comfy pr-cache clean 456 # Clean specific PR cache
```
- Cache automatically expires after 7 days
- Maximum of 10 PR builds are kept (oldest are removed automatically)
- Cache limits help manage disk space while keeping recent builds available
- To check VRAM/RAM usage: `comfy system-stats` (add `--where cloud` to target Comfy Cloud instead of local)
- To unload models / free the executor cache: `comfy free` (pass `--free-memory` to also reset the executor cache)
### Managing Custom Nodes
comfy provides a convenient way to manage custom nodes for extending ComfyUI's functionality. Here are some examples:
- Show custom nodes' information:
```
comfy node [show|simple-show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list]
?[--channel ]
?[--mode [remote|local|cache]]
```
- `comfy node show all --channel recent`
`comfy node simple-show installed`
`comfy node update all`
`comfy node install comfyui-impact-pack`
> **Note:** the argument is the node's **Comfy Registry ID**, which is
> lowercase (e.g. `comfyui-impact-pack`), not the GitHub repository name
> (`ComfyUI-Impact-Pack`). Passing the repo-name casing fails to resolve with
> an error like `Node 'ComfyUI-Impact-Pack@unknown' not found`. Find a node's
> ID on its [Comfy Registry](https://registry.comfy.org) page or via
> `comfy node show all`.
- Managing snapshot:
`comfy node save-snapshot`
`comfy node restore-snapshot `
- Install dependencies:
`comfy node install-deps --deps=`
`comfy node install-deps --workflow=`
- Generate deps:
`comfy node deps-in-workflow --workflow= --output=