# balena-io/balena-cli architecture

> Architecture diagram of the GitHub repository balena-io/balena-cli, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-03). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/balena-io/balena-cli
- Repository: https://github.com/balena-io/balena-cli

## Overview

#### Purpose and Runtime
This is the TypeScript/Node.js implementation of the cross-platform balena CLI. It provides interactive and scriptable access to balenaCloud or self-hosted openBalena: fleet/device administration, application deployment, OS image management, authentication, and local device operations.

Primary launchers are `bin/balena`, `bin/run.js`, and development launcher `bin/balena-dev`. The command framework application is rooted at `src/app.ts`.

#### CLI Dispatch and Lifecycle
The CLI uses an oclif-style command layout: command path segments map to modules under `src/commands/`. Startup preprocessing, global behavior, and invalid-command suggestions form the command boundary.
- `src/app.ts`
- `src/preparser.ts`
- `src/hooks/prerun.ts`
- `src/hooks/command-not-found/suggest.ts`

Commands receive normalized arguments/flags, configuration, authentication state, and shared SDK/network facilities rather than directly owning those concerns.

#### Cloud API and Authentication Boundary
Cloud-facing commands communicate through the balena SDK/API abstraction, supporting balenaCloud and openBalena. Login starts a local authentication flow/server and persists usable credentials; logout and identity commands consume the same session state.
- `src/auth/index.ts`
- `src/auth/server.ts`
- `src/utils/sdk.ts`
- `src/commands/login/index.ts`
- `src/commands/logout/index.ts`

The local auth HTTP server and EJS success/error pages are a contained browser callback boundary, not an application web server.

#### Deployment and Build Pipeline
`push`, `deploy`, and `build` turn a local Dockerfile or Compose project into deployable images/releases. Compose parsing and validation determine service definitions; Docker and/or remote build facilities create images; release utilities publish and promote artifacts through the cloud API.
- `src/commands/push/index.ts`
- `src/commands/deploy/index.ts`
- `src/commands/build/index.ts`
- `src/utils/compose.ts`
- `src/utils/docker.ts`
- `src/utils/remote-build.ts`

This pipeline crosses local filesystem/Docker daemon boundaries and remote builder/API boundaries. Legacy deployment remains isolated in `src/utils/deploy-legacy.ts`.

#### Fleet, Device, and Release Control Plane
Most commands are thin CLI adapters over a common cloud control plane: applications/fleets, devices, releases, environment variables, tags, organizations, SSH keys, and release assets. Device-specific operations additionally support logs, SSH, tunnels, restart/state actions, and local-mode workflows.
- `src/commands/fleet/index.ts`
- `src/commands/device/index.ts`
- `src/commands/release/index.ts`
- `src/utils/device/api.ts`
- `src/utils/device/live.ts`
- `src/utils/tunnel.ts`

The important distinction is cloud resource mutation/query versus direct/live device connectivity.

#### Local OS and Device Provisioning
The CLI can discover drives/devices, download/configure/initialize balena OS images, flash local media, and inject configuration. These workflows depend on host OS capabilities, privileged operations, disk mounting/unmounting, compression/image handling, and optional emulation tooling.
- `src/commands/os/configure.ts`
- `src/commands/local/flash.ts`
- `src/commands/config/inject.ts`
- `src/utils/image-manager.ts`
- `src/utils/qemu.ts`
- `src/utils/umount.ts`

#### Shared Environment and External Dependencies
Cross-cutting services centralize persisted configuration, proxy selection/exclusion, logging, terminal interaction, update/version enforcement, and platform command discovery.
- `src/config.ts`
- `src/utils/config.ts`
- `src/utils/proxy.ts`
- `src/utils/update.ts`
- `src/utils/tty.ts`

Material external dependencies are Node.js, Docker, the balena SDK/API, balena remote builders, local SSH/proxytunnel, and host disk/OS utilities. Release packaging produces standalone binaries via `automation/build-bin.ts`; npm remains another distribution route.

Main entry points: [`src/commands/fleet/index.ts`](https://github.com/balena-io/balena-cli/blob/master/src/commands/fleet/index.ts) (Command surface), [`src/app.ts`](https://github.com/balena-io/balena-cli/blob/master/src/app.ts) (Command application), [`src/utils/sdk.ts`](https://github.com/balena-io/balena-cli/blob/master/src/utils/sdk.ts) (Cloud SDK client), [`src/auth/index.ts`](https://github.com/balena-io/balena-cli/blob/master/src/auth/index.ts) (Authentication session)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["CLI runtime"]
  node_launchers["CLI launchers<br/>Node entrypoints"]
  node_app["Command application<br/>oclif app<br/>[app.ts]"]
  node_preparser["Startup preprocessing<br/>argument normalization<br/>[preparser.ts]"]
  node_prerun["Global prerun hook<br/>lifecycle hook<br/>[prerun.ts]"]
  node_suggest["Invalid command suggestions<br/>not-found hook<br/>[suggest.ts]"]
  node_shared_env["Shared environment<br/>[config.ts]"]
  node_command_surface["Command surface<br/>oclif commands<br/>[index.ts]"]
  node_packaging["Standalone binary packaging<br/>release packaging<br/>[build-bin.ts]"]
end

subgraph group_cloud["Cloud control plane"]
  node_auth["Authentication session<br/>credential management<br/>[index.ts]"]
  node_auth_server["Local auth callback<br/>HTTP callback server<br/>[server.ts]"]
  node_sdk{{"Cloud SDK client<br/>balena API abstraction<br/>[sdk.ts]"}}
  node_cloud_api{{"balenaCloud / openBalena<br/>remote control plane"}}
  node_device_api["Device cloud operations<br/>device API utilities<br/>[api.ts]"]
end

subgraph group_deploy["Deployment pipeline"]
  node_compose["Compose project parsing<br/>compose validation<br/>[compose.ts]"]
  node_docker["Local Docker build<br/>Docker integration<br/>[docker.ts]"]
  node_remote_build["Remote build<br/>[remote-build.ts]"]
  node_release_publish["Release publishing<br/>release API workflow<br/>[index.ts]"]
end

subgraph group_local["Local device &amp; OS"]
  node_live_device["Live device connectivity<br/>SSH, logs &amp; tunnels<br/>[live.ts]"]
  node_image_manager["OS image workflow<br/>image download &amp; configuration<br/>[image-manager.ts]"]
  node_flash["Media flashing<br/>privileged disk writer<br/>[flash.ts]"]
  node_host_tools{{"Host OS tools"}}
end

node_launchers -->|"starts"| node_app
node_app -->|"normalizes input"| node_preparser
node_app -->|"runs lifecycle"| node_prerun
node_app -.->|"handles unknown commands"| node_suggest
node_app -->|"dispatches"| node_command_surface
node_app -->|"uses"| node_shared_env
node_command_surface -->|"login/logout session"| node_auth
node_auth -->|"browser callback flow"| node_auth_server
node_auth -->|"persists credentials"| node_shared_env
node_command_surface -->|"cloud commands"| node_sdk
node_sdk -->|"API requests"| node_cloud_api
node_command_surface -->|"device resource operations"| node_device_api
node_device_api -->|"uses"| node_sdk
node_command_surface -->|"logs, SSH &amp; tunnels"| node_live_device
node_live_device -->|"local networking"| node_host_tools
node_command_surface -->|"push/build/deploy"| node_compose
node_compose -->|"service definitions"| node_docker
node_docker -->|"Docker daemon"| node_host_tools
node_compose -->|"remote build input"| node_remote_build
node_docker -->|"built images"| node_release_publish
node_remote_build -->|"build artifacts"| node_release_publish
node_release_publish -->|"publishes releases"| node_sdk
node_command_surface -->|"OS configure/inject"| node_image_manager
node_image_manager -->|"configured image"| node_flash
node_flash -->|"writes media"| node_host_tools
node_packaging -.->|"packages"| node_launchers

click node_launchers "https://github.com/balena-io/balena-cli/blob/master/bin/balena"
click node_app "https://github.com/balena-io/balena-cli/blob/master/src/app.ts"
click node_preparser "https://github.com/balena-io/balena-cli/blob/master/src/preparser.ts"
click node_prerun "https://github.com/balena-io/balena-cli/blob/master/src/hooks/prerun.ts"
click node_suggest "https://github.com/balena-io/balena-cli/blob/master/src/hooks/command-not-found/suggest.ts"
click node_shared_env "https://github.com/balena-io/balena-cli/blob/master/src/config.ts"
click node_command_surface "https://github.com/balena-io/balena-cli/blob/master/src/commands/fleet/index.ts"
click node_auth "https://github.com/balena-io/balena-cli/blob/master/src/auth/index.ts"
click node_auth_server "https://github.com/balena-io/balena-cli/blob/master/src/auth/server.ts"
click node_sdk "https://github.com/balena-io/balena-cli/blob/master/src/utils/sdk.ts"
click node_device_api "https://github.com/balena-io/balena-cli/blob/master/src/utils/device/api.ts"
click node_live_device "https://github.com/balena-io/balena-cli/blob/master/src/utils/device/live.ts"
click node_compose "https://github.com/balena-io/balena-cli/blob/master/src/utils/compose.ts"
click node_docker "https://github.com/balena-io/balena-cli/blob/master/src/utils/docker.ts"
click node_remote_build "https://github.com/balena-io/balena-cli/blob/master/src/utils/remote-build.ts"
click node_release_publish "https://github.com/balena-io/balena-cli/blob/master/src/commands/deploy/index.ts"
click node_image_manager "https://github.com/balena-io/balena-cli/blob/master/src/utils/image-manager.ts"
click node_flash "https://github.com/balena-io/balena-cli/blob/master/src/commands/local/flash.ts"
click node_packaging "https://github.com/balena-io/balena-cli/blob/master/automation/build-bin.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_launchers,node_app,node_preparser,node_prerun,node_suggest,node_shared_env,node_command_surface,node_packaging toneBlue
class node_auth,node_auth_server,node_sdk,node_cloud_api,node_device_api toneAmber
class node_compose,node_docker,node_remote_build,node_release_publish toneMint
class node_live_device,node_image_manager,node_flash,node_host_tools toneRose
```

## Components

### CLI runtime

- [CLI launchers](https://github.com/balena-io/balena-cli/blob/master/bin/balena): Node entrypoints · `bin/balena`
- [Command application](https://github.com/balena-io/balena-cli/blob/master/src/app.ts): oclif app · `src/app.ts`
- [Startup preprocessing](https://github.com/balena-io/balena-cli/blob/master/src/preparser.ts): argument normalization · `src/preparser.ts`
- [Global prerun hook](https://github.com/balena-io/balena-cli/blob/master/src/hooks/prerun.ts): lifecycle hook · `src/hooks/prerun.ts`
- [Invalid command suggestions](https://github.com/balena-io/balena-cli/blob/master/src/hooks/command-not-found/suggest.ts): not-found hook · `src/hooks/command-not-found/suggest.ts`
- [Shared environment](https://github.com/balena-io/balena-cli/blob/master/src/config.ts): config, proxy, updates & TTY · Centralizes persisted settings and host-facing CLI behavior. · `src/config.ts`
- [Command surface](https://github.com/balena-io/balena-cli/blob/master/src/commands/fleet/index.ts): oclif commands · Fleet, device, release, login, deployment, and OS command adapters. · `src/commands/fleet/index.ts`
- [Standalone binary packaging](https://github.com/balena-io/balena-cli/blob/master/automation/build-bin.ts): release packaging · `automation/build-bin.ts`

### Cloud control plane

- [Authentication session](https://github.com/balena-io/balena-cli/blob/master/src/auth/index.ts): credential management · `src/auth/index.ts`
- [Local auth callback](https://github.com/balena-io/balena-cli/blob/master/src/auth/server.ts): HTTP callback server · Handles browser login callbacks and success/error pages. · `src/auth/server.ts`
- [Cloud SDK client](https://github.com/balena-io/balena-cli/blob/master/src/utils/sdk.ts): balena API abstraction · Targets balenaCloud or self-hosted openBalena. · `src/utils/sdk.ts`
- **balenaCloud / openBalena**: remote control plane
- [Device cloud operations](https://github.com/balena-io/balena-cli/blob/master/src/utils/device/api.ts): device API utilities · `src/utils/device/api.ts`

### Deployment pipeline

- [Compose project parsing](https://github.com/balena-io/balena-cli/blob/master/src/utils/compose.ts): compose validation · `src/utils/compose.ts`
- [Local Docker build](https://github.com/balena-io/balena-cli/blob/master/src/utils/docker.ts): Docker integration · `src/utils/docker.ts`
- [Remote build](https://github.com/balena-io/balena-cli/blob/master/src/utils/remote-build.ts): remote builder client · `src/utils/remote-build.ts`
- [Release publishing](https://github.com/balena-io/balena-cli/blob/master/src/commands/deploy/index.ts): release API workflow · `src/commands/deploy/index.ts`

### Local device & OS

- [Live device connectivity](https://github.com/balena-io/balena-cli/blob/master/src/utils/device/live.ts): SSH, logs & tunnels · Direct connectivity for logs, SSH, tunnels, and local-mode operations. · `src/utils/device/live.ts`
- [OS image workflow](https://github.com/balena-io/balena-cli/blob/master/src/utils/image-manager.ts): image download & configuration · `src/utils/image-manager.ts`
- [Media flashing](https://github.com/balena-io/balena-cli/blob/master/src/commands/local/flash.ts): privileged disk writer · Flashes configured OS images using host disk utilities. · `src/commands/local/flash.ts`
- **Host OS tools**: Docker, disks, SSH & QEMU

## Connections

- CLI launchers → Command application: starts
- Command application → Startup preprocessing: normalizes input
- Command application → Global prerun hook: runs lifecycle
- Command application → Invalid command suggestions: handles unknown commands
- Command application → Command surface: dispatches
- Command application → Shared environment: uses
- Command surface → Authentication session: login/logout session
- Authentication session → Local auth callback: browser callback flow
- Authentication session → Shared environment: persists credentials
- Command surface → Cloud SDK client: cloud commands
- Cloud SDK client → balenaCloud / openBalena: API requests
- Command surface → Device cloud operations: device resource operations
- Device cloud operations → Cloud SDK client: uses
- Command surface → Live device connectivity: logs, SSH & tunnels
- Live device connectivity → Host OS tools: local networking
- Command surface → Compose project parsing: push/build/deploy
- Compose project parsing → Local Docker build: service definitions
- Local Docker build → Host OS tools: Docker daemon
- Compose project parsing → Remote build: remote build input
- Local Docker build → Release publishing: built images
- Remote build → Release publishing: build artifacts
- Release publishing → Cloud SDK client: publishes releases
- Command surface → OS image workflow: OS configure/inject
- OS image workflow → Media flashing: configured image
- Media flashing → Host OS tools: writes media
- Standalone binary packaging → CLI launchers: packages
