---
title: "The <code class=\"docutils literal notranslate\"><span class=\"pre\">pbl</span></code> CLI"
canonical_url: https://developer.repebble.com/pebbleos/docs/pbl/
last_updated: 2026-10-21
sdk_version: 4.33.1
---
# The <code class="docutils literal notranslate"><span class="pre">pbl</span></code> CLI

Source: https://developer.repebble.com/pebbleos/docs/pbl/

`pbl` is the developer command line for this repository: it configures and builds the firmware, puts the result on a device or an emulator, and hosts the operational commands around that.

It is a Python package, installed along with the rest of the project’s dependencies (see the [Getting started guide](https://developer.repebble.com/pebbleos/docs/getting_started.md)):

```
pip install -r requirements.txt
```

After that `pbl` is on the `PATH` whenever the virtual environment is active. Run it from anywhere inside the checkout:

```
pbl configure --board asterix
pbl build
pbl flash
```

`pbl --help` lists every command, grouped; `pbl <command> --help` shows one command’s own options.

## Commands

| 

Build

 | 

Device

 | 

Emulator

 |
| --- | --- | --- |
| 

[pbl configure](https://developer.repebble.com/pebbleos/docs/pbl/configure.md)

 | 

[pbl flash](https://developer.repebble.com/pebbleos/docs/pbl/flash.md)

 | 

[pbl qemu](https://developer.repebble.com/pebbleos/docs/pbl/qemu.md)

 |
| 

[pbl build](https://developer.repebble.com/pebbleos/docs/pbl/build.md)

 | 

[pbl console](https://developer.repebble.com/pebbleos/docs/pbl/console.md)

 | 

[pbl screenshot](https://developer.repebble.com/pebbleos/docs/pbl/screenshot.md)

 |
| 

[pbl bundle](https://developer.repebble.com/pebbleos/docs/pbl/bundle.md)

 | 

[pbl debug](https://developer.repebble.com/pebbleos/docs/pbl/debug.md)

 | 

[pbl touch](https://developer.repebble.com/pebbleos/docs/pbl/touch.md)

 |
| 

[pbl menuconfig](https://developer.repebble.com/pebbleos/docs/pbl/menuconfig.md)

 | 

[pbl image\_resources](https://developer.repebble.com/pebbleos/docs/pbl/image_resources.md)

 | 

[pbl swipe](https://developer.repebble.com/pebbleos/docs/pbl/swipe.md)

 |
| 

[pbl clean](https://developer.repebble.com/pebbleos/docs/pbl/clean.md)

 | 

[pbl image\_recovery](https://developer.repebble.com/pebbleos/docs/pbl/image_recovery.md)

 | 

[pbl feed](https://developer.repebble.com/pebbleos/docs/pbl/feed.md)

 |
| 

[pbl test](https://developer.repebble.com/pebbleos/docs/pbl/test.md)

 | 

[pbl reset](https://developer.repebble.com/pebbleos/docs/pbl/reset.md)

 | 

 |
| 

[pbl itest](https://developer.repebble.com/pebbleos/docs/pbl/itest.md)

 | 

[pbl run](https://developer.repebble.com/pebbleos/docs/pbl/run.md)

 | 

 |
| 

 | 

[pbl erase](https://developer.repebble.com/pebbleos/docs/pbl/erase.md)

 | 

 |
| 

 | 

[pbl bork](https://developer.repebble.com/pebbleos/docs/pbl/bork.md)

 | 

 |
| 

 | 

[pbl openocd](https://developer.repebble.com/pebbleos/docs/pbl/openocd.md)

 | 

 |

## Shared options

Two options are accepted by every command, before or after the command name:

- `-b, --build-dir DIR` — use a different build directory. It defaults to the one `pbl.yml` names (`build/`, or `build-test/` for `pbl test`), and `PBL_BUILD_DIR` overrides that in turn.

- `--dry-run` — print the commands that would run instead of running them.

Separate build directories let several boards be built side by side:

```
pbl -b build-qemu configure --board qemu_emery
pbl -b build-asterix configure --board asterix
pbl -b build-asterix flash
```

## Where its knowledge comes from

`pbl` holds no facts about the checkout of its own:

- The **workspace** is wherever `pbl.yml` is, found by walking up from the current directory. That file also names the build and test directories.

- The **build** is read back from its own byproducts: `.config` for every `CONFIG_` symbol, `CMakeCache.txt` for the board, the variant and the project name the artifacts are named after. Configuring is therefore the only way to tell `pbl` about a build, and reconfiguring is enough to change its mind.

- The **board** contributes the rest through `boards/<board>/<board>.yml`: its revisions, the binary runners it supports, and the SDL decorations the emulator can draw around its screen.

## Runners

Device commands reach a watch through a binary runner. A board lists the ones it supports in its manifest, and the first one is the default; `-r/--runner` picks another.

| 

Runner

 | 

Boards

 | 

Operations

 |
| --- | --- | --- |
| 

`openocd`

 | 

asterix

 | 

flash (with resources), run, reset, erase (with ranges), debug, debug server

 |
| 

`nrfutil`

 | 

asterix

 | 

flash (with resources), run, reset, erase (with ranges)

 |
| 

`sftool`

 | 

obelix, getafix

 | 

flash (with resources), erase (with ranges)

 |

For the OpenOCD runner, the probe and target configuration lives in the board’s `support/openocd.cfg`, and how to write the resources and erase ranges, if it can, in `support/flash.cfg`.

The `nrfutil` runner needs a J-Link probe. To write the resources it takes the external flash configuration from the board’s `support/nrfutil_ext_mem.json`.

Generated from PebbleOS [3a7b71785](https://github.com/coredevices/pebbleos/commit/3a7b71785fd439666c4a8bc116f561140e8dec01). This page is maintained in the pebbleos repository: [docs/pbl/index.md](https://github.com/coredevices/pebbleos/blob/3a7b71785fd439666c4a8bc116f561140e8dec01/docs/pbl/index.md).
