jbang-offline-downloader
v1.0.0
Published
Create and install reproducible offline JBang packages
Downloads
34
Readme
JBang Offline Packer
A deterministic, reproducible, cross-platform tool for creating fully offline JBang distributions.
It bundles multiple JBang versions, multi-platform JDKs, Maven repositories, pre-warmed caches, catalogs, and scripts — then lets you install, validate, diff, sign, shrink, and serve them.
Quick Start
# Install dependencies and build
pnpm install
pnpm run build
# Create an offline bundle
jbo pack --output jbang-offline.tar.gz --scripts hello.java
# Install on an offline machine
jbo unpack jbang-offline.tar.gz --target /opt/jbang-offline
# Validate the environment
jbo doctorFeatures
| Feature | Description |
|---------|-------------|
| Multi-version JBang | Bundle any number of JBang versions; switch at runtime via jbo jbang use <ver> |
| Multi-platform JDK | Bundle JDKs for Linux, macOS, and Windows side-by-side |
| Maven repository | Automatically includes ~/.m2/repository |
| Bundle manifest | Every bundle carries bundle-manifest.json with checksums and metadata |
| Bundle shrinker | Remove unused Maven artifacts with jbo shrink |
| Diff + diff-tree | Compare bundles textually or as a Mermaid diagram |
| Remote registry | jbo registry list / jbo registry fetch from a JSON index |
| Plugin system | Drop .js files into plugins/pack/ or plugins/unpack/ |
| Profiles | Define dev/test/prod configurations in jbo.toml |
| Offline test harness | Validate all scripts run offline with jbo test-offline |
| Signing + verification | SHA-256 and optional GPG detached signatures |
| Self-update | Update the packer itself from GitHub releases |
| Cross-platform | Windows (PowerShell + setx), macOS, Linux |
Bundle Layout
bundle-root/
jbang/
versions/
0.118.0/
1.0.0/
current -> versions/1.0.0
jdks/
linux/
macos/
windows/
maven-repo/
cache/
catalogs/
bundle-manifest.jsonUsage
# Create an offline package
jbo pack --output jbang-offline.tar.gz --scripts hello.java
# With catalogs and checksum verification
jbo pack --output jbang-offline.tar.gz \
--scripts hello.java \
--catalogs https://example.com/jbang-catalog.json \
--checksum abc123def456 \
--jdk /path/to/jdk
# Bundle multiple JBang versions
jbo pack --output jbang-offline.tar.gz \
--jbang-version 0.118.0 --jbang-version 1.0.0
# Multi-platform JDK bundling
jbo pack --output jbang-offline.tar.gz \
--jdk-linux ~/jdks/linux \
--jdk-macos ~/jdks/macos \
--jdk-windows ~/jdks/windows
# Use a profile from jbo.toml
jbo pack --profile prod
# Enable debug output
jbo --debug pack --output jbang-offline.tar.gz --scripts hello.java
# Install an offline package
jbo unpack jbang-offline.tar.gz --target /opt/jbang-offline
# Validate offline environment
jbo doctor
# List cached artifacts
jbo list
# Prune unused caches
jbo prune
# Self-update the packer
jbo self-update
# Test scripts run offline
jbo test-offline
# Compare two bundles
jbo diff bundleA.tar.gz bundleB.tar.gz
# Sign a bundle
jbo sign jbang-offline.tar.gz
jbo sign --gpg jbang-offline.tar.gz
# Verify a bundle
jbo verify jbang-offline.tar.gz
jbo verify --gpg jbang-offline.tar.gz
# Switch active JBang version
jbo jbang use 1.0.0
# Visual diff as Mermaid diagram
jbo diff-tree bundleA.tar.gz bundleB.tar.gz
# List bundles from remote registry
jbo registry list --registry-url https://example.com/registry.json
# Fetch and install a bundle from registry
jbo registry fetch prod-bundle --registry-url https://example.com/registry.json --target /opt/jbang
# Shrink bundle by removing unused Maven artifacts
jbo shrink --profile prod
jbo shrink --bundle-dir .stagingCommands
pack
Downloads JBang, pre-warms caches, optionally bundles JDKs, and creates a deterministic tar.gz.
| Option | Type | Description |
|--------|------|-------------|
| --output | string | Output tarball path (required) |
| --jdk | string | Path to local JDK to bundle (single) |
| --jdk-linux | string | Path to Linux JDK to bundle |
| --jdk-macos | string | Path to macOS JDK to bundle |
| --jdk-windows | string | Path to Windows JDK to bundle |
| --scripts | array | Scripts to pre-cache |
| --catalogs | array | Catalogs to add (URLs or file paths) |
| --jbang-version | array | JBang versions to bundle (repeatable) |
| --profile | string | Profile from jbo.toml to use |
| --checksum | string | Expected SHA-256 checksum for JBang ZIP |
unpack
Extracts the tarball and installs caches into ~/.jbang. Copies the platform-appropriate JDK. On Windows, adds JBang to PATH via setx.
| Argument | Type | Description |
|----------|------|-------------|
| <tarball> | string | Path to the offline tarball (required) |
| --target | string | Target installation directory (required) |
doctor
Validates the offline JBang environment:
- Checks JBang binary is in PATH
- Verifies cache, JDK, and catalogs directories exist
- Tests that
jbang --offline --versionruns successfully
list
Lists cached JBang artifacts — JDKs, Maven cache entries, and catalogs.
prune
Removes unused JBang caches:
- Keeps only the newest JDK
- Removes cache entries not referenced by scripts in
jbo.toml
self-update
Checks the latest release on GitHub and updates the packer to the latest version.
test-offline
Runs every script defined in jbo.toml with jbang --offline and reports pass/fail results.
diff <a> <b>
Compares two offline bundles — shows which JDKs, cache entries, and catalogs differ between them.
sign <file>
Creates a SHA-256 checksum file (<file>.sha256). With --gpg, also creates a GPG detached signature (<file>.sig).
verify <file>
Verifies the SHA-256 checksum of a bundle (<file>.sha256). With --gpg, also verifies the GPG detached signature.
jbang use <version>
Switches the active JBang version (nvm-style). Versions are expected in ~/.jbang-offline/jbang/versions/.
diff-tree <a> <b>
Extracts both bundles into temp directories and outputs a Mermaid graph TD diagram showing which JDKs, cache entries, Maven artifacts, and catalogs differ. Items only in A are highlighted red; items only in B are highlighted green.
registry list
Fetches a remote registry.json (default https://example.com/jbang/registry.json) and lists available bundles.
registry fetch <name>
Downloads a named bundle from the registry, verifies its SHA-256 checksum, extracts it, and installs caches and platform JDK — same as unpack but with automatic download.
shrink
Prunes unused Maven artifacts from an extracted bundle. Reads bundle-manifest.json (or a --profile from jbo.toml) and removes any artifact version not referenced by the active scripts. Keeps only what your scripts need.
| Option | Type | Description |
|--------|------|-------------|
| --profile | string | Profile from jbo.toml for script references |
| --bundle-dir | string | Path to extracted bundle (default: .staging) |
Global options
| Option | Description |
|--------|-------------|
| --debug | Enable debug output (also via JBO_DEBUG=1) |
Configuration
A jbo.toml file in the project root sets defaults. See jbo.toml.example for the full reference.
[pack]
output = "jbang-offline.tar.gz"
scripts = ["hello.java", "tools/build.java"]
catalogs = ["https://example.com/jbang-catalog.json"]
checksum = "abc123..."
jbang-versions = ["0.118.0", "1.0.0"]
[pack.jdks]
linux = "/opt/jdks/temurin-17"
macos = "/opt/jdks/temurin-17"
windows = "C:\\jdks\\temurin-17"
[unpack]
target = "/opt/jbang-offline"
[profiles.dev]
scripts = ["dev/hello.java"]
jbang-versions = ["0.118.0"]
[profiles.dev.jdks]
linux = "/opt/jdks/dev-linux"
[profiles.prod]
scripts = ["prod/main.java"]
jbang-versions = ["1.0.0"]
[profiles.prod.jdks]
linux = "/opt/jdks/prod-linux"CLI flags override TOML values.
Plugins
Place .js files in plugins/pack/ or plugins/unpack/ to extend behavior:
// plugins/pack/notify.js
module.exports = {
name: "notify",
run: async (context) => {
console.log(`Bundle created at ${context.output}`);
},
};Each plugin exports { name, run(context) }. Plugins run in sorted file order after the main operation completes.
Bundle Manifest
Every pack run produces bundle-manifest.json at the bundle root:
{
"createdAt": "2026-06-01T12:00:00.000Z",
"jbangVersions": ["latest"],
"scripts": ["hello.java"],
"catalogs": [],
"jdks": { "linux": "/opt/jdks/temurin-17" },
"mavenRepo": { "groupCount": 42, "fileCount": 3100 },
"checksums": {
"jbang/versions/1.0.0/bin/jbang": "abc123..."
}
}Used by shrink, diff, verify, and doctor for inspection and validation.
The local Maven repository (~/.m2/repository) is bundled when present and installed to ~/.jbang/maven-repo on unpack. Configure JBang to use it via MAVEN_REPO_LOCAL.
Architecture
flowchart TD
subgraph CLI
A["jbo pack"] --> B[Pack Pipeline]
A2["jbo unpack"] --> C[Unpack Pipeline]
A3["jbo shrink"] --> D[Shrinker]
A4["jbo diff"] --> E[Diff Engine]
A5["jbo diff-tree"] --> F[Mermaid Diff]
A6["jbo registry"] --> G[Registry Client]
end
subgraph Pack
B1[Download JBang]
B2[Bundle JDKs]
B3[Warm Cache]
B4[Bundle Maven Repo]
B5[Generate Manifest]
B6[Run Pack Plugins]
B7[Create Deterministic Tarball]
end
subgraph Unpack
C1[Extract Tarball]
C2[Install JBang]
C3[Install JDK]
C4[Install Maven Repo]
C5[Install Cache]
C6[Run Unpack Plugins]
end
B --> B1 --> B2 --> B3 --> B4 --> B5 --> B6 --> B7
C --> C1 --> C2 --> C3 --> C4 --> C5 --> C6Pack/Unpack sequence
sequenceDiagram
participant User
participant CLI
participant Pack
participant FS as Filesystem
participant Manifest
User->>CLI: jbo pack
CLI->>Pack: Start pack pipeline
Pack->>FS: Download JBang versions
Pack->>FS: Copy JDKs
Pack->>FS: Warm JBang cache
Pack->>FS: Copy Maven repo
Pack->>Manifest: Generate bundle-manifest.json
Pack->>FS: Create deterministic tar.gz
CLI->>User: Bundle created
User->>CLI: jbo unpack bundle.tar.gz
CLI->>FS: Extract tarball
CLI->>FS: Install JBang
CLI->>FS: Install platform JDK
CLI->>FS: Install Maven repo + cache
CLI->>User: Offline environment readyGitHub Actions
A workflow at .github/workflows/offline-jbang.yml builds and validates the offline bundle on push to main. It:
- Installs dependencies with pnpm
- Builds the project
- Creates the offline tarball
- Runs
doctorto validate - Uploads the artifact
Build
pnpm install
pnpm run build