The package & dependency manager for IBM i. Reusable RPG/ILE business-logic modules — declared, resolved, built, and deployed from one CLI.
by Escalia Technologies
IBM i has no unified, open package manager for native ILE objects (service programs, modules, RPG business logic). Teams reinvent the same plumbing: copy service programs by hand, juggle binding directories, hand-edit library lists, and re-run DDL from memory.
yum/RPM covers the PASE/open-source side. Bindle covers the native ILE side — the gap.
Bindle lets you package a unit of business logic as a module (think: an Odoo module for IBM i), publish it to a registry, and install it into any project with its dependencies resolved automatically.
1 module = 1 library (*LIB)
public API = *SRVPGM + /copy prototype member
state = versioned DB migrations
manifest = bindle.json
# 1. scaffold a module or project (creates bindle.json)
bindle init --module --name modgreet
# 2. build the module on the IBM i host (compile → signature → SAVF)
bindle build --profile prod
# 3. publish the artifact + metadata to the registry
bindle publish --artifact .bindle/build/GREETSRV.savf
# --- in a consumer project ---
bindle add modgreet # pin ^latest from the registry
bindle install # resolve → lock → fetch → verify (local)
bindle install --deploy --profile prod # + restore onto IBM i, verify signature, wire *LIBLThat's the loop: build → publish → add → install (→ deploy). No hand-written
binder source, no manual RSTOBJ, no guessing which DDL to run.
Try it now (no IBM i needed) — these already resolve a real dependency graph, write a reproducible lock, and fetch + verify artifacts:
go run ./cmd/bindle list -f examples/miapp/bindle.json --registry examples/registry go run ./cmd/bindle list tree -f examples/miapp/bindle.json --registry examples/registry go run ./cmd/bindle install -f examples/miapp/bindle.json --registry examples/registrySee
examples/.
Full spec: docs/MANIFEST_SPEC.md · Package layout: docs/PACKAGE_ANATOMY.md
bindle install bindle install --deploy
│ │ (everything on the left, then:)
├─ read bindle.json + lock ├─ upload SAVF over SFTP
├─ resolve graph (vers + sigs) ├─ CPYFRMSTMF → RSTOBJ into target lib
├─ fetch artifacts from registry ├─ verify *SRVPGM signature == lock
├─ verify sha256 against the lock └─ wire the library list (*LIBL)
└─ cache locally │
│ ▼
▼ ✓ module installed & bindable on IBM i
✓ reproducible, verified cache
Internal component view (manifest · resolver · registry · builder · installer · transport) lives in
docs/ARCHITECTURE.md.
Modules are published to a registry — an index of versioned artifacts (SAVF + metadata) that install reads from.
publish: bindle build → package SAVF → push artifact + metadata → registry
store: registry/<name>/<version>/{ MODFACT.savf, bindle.json, index.json }
consume: bindle add → resolve → fetch from registry → install
MVP backend is pluggable (IFS directory / SAVF host / S3-compatible bucket). Details: docs/REGISTRY.md.
Each tool solves a different slice. Bindle fills the native-ILE package management gap.
| Tool | Scope | Native ILE objects | Dep resolution | Registry / publish | DB migrations |
|---|---|---|---|---|---|
| yum / RPM | PASE / open-source pkgs | ❌ | ✅ (PASE only) | ✅ | ❌ |
| Git | Source version control | ❌ (source, not objects) | ❌ | ❌ | ❌ |
| ACS | GUI client (5250, DB, transfer) | ❌ | ❌ | ❌ | ❌ |
| Bob (ibmi-bob) | Build / compile | ✅ (build) | ❌ | ❌ | |
| ARCAD / Merlin | Full ALM (commercial, heavy) | ✅ | ✅ | ✅ | |
| Bindle | ILE package management | ✅ | ✅ (version + signature) | ✅ | ✅ |
Bindle is complementary: it can wrap Bob for builds and lives alongside Git for source.
The hard part of a tool like this is not the code — it's adoption in conservative IBM i shops. Bindle is designed to slot into existing processes, not replace them:
- No big-bang rewrite. Adopt one module at a time; the rest of the system keeps building the traditional way.
- Coexists with CL / existing change management. Bindle generates standard objects (
*SRVPGM,*BNDDIR, SAVF) and CL you can inspect and run yourself. - Wraps, doesn't fight, the toolchain. Uses Bob for builds, Git for source, standard
RSTLIB/library lists for deploy. - Reversible. Everything Bindle produces is a normal IBM i object — you are never locked in.
cmd/bindle/ entrypoint
internal/
manifest/ read & validate bindle.json / bindle.lock
resolver/ dependency graph, version + signature resolution
registry/ fetch / publish artifacts (SAVF + metadata)
builder/ compile RPG, generate binder + deterministic signature, SAVF
installer/ local install (lock/fetch/verify) + deploy (RSTOBJ/sig-check/wire)
config/ host-agnostic connection profiles (~/.bindle/config.json)
transport/ SSH: run CL/PASE, SFTP upload/download
docs/ VISION · ARCHITECTURE · MANIFEST_SPEC · PACKAGE_ANATOMY · REGISTRY · CONNECTION · BUILD · ROADMAP
examples/ runnable demo registry, consumer, and a buildable module
assets/ logo & banner
🛠️ Working alpha. All CLI commands are implemented (no stubs). The local flow and on-host build run end-to-end; full deploy is implemented but not yet proven on an unrestricted host.
Verified working (the last two live against a real IBM i, 7.5):
| Area | State |
|---|---|
init · add · list · list tree |
✅ |
install (resolve → lock → fetch → sha256 verify → cache) |
✅ |
publish (artifact + metadata to registry) |
✅ |
profile · ping · exec · put · get |
✅ |
build (compile RPG → *SRVPGM → SAVF) |
✅ live |
| deterministic, signature-controlled binder builds | ✅ live |
callable — a program binds the built *SRVPGM and runs its export |
✅ live |
sql · migrate (SQL channel, control table, idempotent) |
✅ live |
| SQL backends: db2util (CLI over SSH) and mapepire (WebSocket over an SSH tunnel) | ✅ live |
| migrations packaged into the registry artifact (publish → fetch → cache) | ✅ live |
Live end-to-end on pub400 (IBM i 7.5):
build→ a caller binds the result →CALLprintsBINDLE-RESULT: Hello, Bindle! (from Bindle). Seeexamples/modules/modgreet/test.
Implemented, not yet fully proven end-to-end:
install --deploy(RSTOBJ + signature check + wire*LIBL) — code + unit tests; the test host (pub400, shared) deniesRSTOBJ, so the real restore awaits a host with restore authority.install --deploy'sRSTOBJrestore — this is the one gap. Upload, signature check, library-list wiring, and auto-migrations are all built and tested; the restore step needs a host withRSTOBJauthority (pub400, being shared, denies it). Everything around it is verified live.- Job-log diagnostics via
QSYS2.JOBLOG_INFO— now feasible on the persistent mapepire connection; not yet wired (docs/SQL_CHANNEL.md).
Docs: VISION · ARCHITECTURE · MANIFEST_SPEC · PACKAGE_ANATOMY · REGISTRY · CONNECTION · BUILD · SQL_CHANNEL · ROADMAP
With Go (installs bindle onto your PATH at $(go env GOPATH)/bin):
go install github.com/ElVatoEste/Bindle/cmd/bindle@latest
bindle --helpPrebuilt binaries — every release ships archives for Linux, macOS, Windows,
and IBM i PASE (aix/ppc64) on the
Releases page (built by
GoReleaser, with checksums.txt). Download, extract, and put bindle on your PATH:
# example: IBM i PASE
curl -LO https://github.com/ElVatoEste/Bindle/releases/latest/download/bindle_0.1.0_aix_ppc64.tar.gz
tar xzf bindle_0.1.0_aix_ppc64.tar.gz
./bindle --versionFrom source:
git clone https://github.com/ElVatoEste/Bindle.git
cd Bindle
go install ./cmd/bindle # global, or: go build ./...Early days — issues and discussion welcome. The MVP "definition of done" is in docs/ROADMAP.md.
Bindle is licensed under the GNU General Public License v3.0.
You may use, study, modify, and redistribute it freely. Any distributed derivative must remain open under the GPLv3 — it cannot be taken closed-source.
© Escalia Technologies. Copyright is retained by the author. Commercial licensing (for use without GPLv3 obligations) is available — contact Escalia Technologies.
{ "schema": "bindle/v0", "name": "modfact", "version": "2.3.0", "library": "MODFACT", // 1 module = 1 library (*LIB) "exports": { "srvpgm": "FACTSRV", // public service program "copy": "FACTPR" // /copy member = the public API "header" // Bindle generates the binder source + a deterministic signature. // Optionally pin the export symbols: "symbols": ["CALCFACT", "APPLYTAX"] }, "dependencies": { "modbase": ">=1.0.0 <2.0.0", "modimp": "^1.2.0" }, "build": { "engine": "native", "src": "src/", "objects": ["FACTMOD"] }, "migrations": { "dir": "migrations/", "schema": "MODFACT" }, "runtime": { "libraryList": ["MODFACT", "MODBASE", "MODIMP"] } }