Aliases & Catalogs
To avoid remembering long paths and to enable easy launch of jbang scripts there is an alias command
to setup and manage aliases to actual scripts.
If your goal is to publish app commands for others, start with Publishing App Catalogs. It is a shorter, app-focused guide for enabling commands like jbang <cmd>@<your-org>.
|
jbang alias add --name hello https://github.com/jbangdev/jbang-examples/blob/HEAD/examples/helloworld.java
will add an alias named hello pointing to that github url which then can be run using jbang hello.
jbang alias list
will show you all the aliases that are defined locally.
Describe Aliases
When an alias is added to a catalog, it can also include a meaningful description of what the script does. It can be added either through an explicit command-line parameter or by extracting it from the //DESCRIPTION tags present in the script.
Example:
jbang alias add --description="Best hello world application" --name best_hello https://github.com/jbangdev/jbang-examples/blob/HEAD/examples/helloworld.java
If you want the description to be automatically extracted from your script, include one or more //DESCRIPTION tags directly within it.
Example:
//DESCRIPTION Best hello world application
//DESCRIPTION Use to cheer your friends
class helloworld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Implicit Alias Catalogs
The aliases you create are stored locally (see Local Alias Catalogs), but JBang can also use remote catalogs. You can access those catalogs explicitly (see Catalogs) but it is much easier to use what we call "implicit catalogs", which are aliases that have a special format and JBang is smart enough to know where to find their definition.
There are two kinds, one that resolves to a Git backed service (github,gitlab and bitbucket) and one that resolves to https sites.
Examples:
jbang tree@jbang.dev will (because of the dot in the name) will lookup a catalog first at https://jbang.dev/jbang-catalog.json.
jbang hello@jbangdev will run the alias hello as defined in jbang-catalog.json found in https://github.com/jbangdev/jbang-catalog.
This allows anyone to provide a set of jbang scripts defined in their website or in a github, gitlab or bitbucket repositories.
The full format is <alias>@<user/org>(/repository)(/branch)(~path) or <alias>@<hostname>(/path/to/catalog) allowing you to do things like:
| Command | Description |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Version Pinning
The problem it solves
Aliases usually point at something that changes over time — a Maven artifact, a file in a git repo, or another catalog. When the author publishes a new version you are stuck choosing between two bad options: update automatically (and risk a breaking change) or never update (and miss bug/security fixes). You also can’t easily ask for a specific version you know works, run two versions side by side, or reproduce an older invocation.
Version pinning lets you choose the version at invocation time, without editing the catalog and without the catalog author having to anticipate it. The catalog format is unchanged, so it stays fully backward-compatible.
When to use it
-
Run or test a specific version of a tool without touching the catalog — e.g.
jbang mytool:1.4.0@mycatalogto reproduce a report, thenmytool:1.5.0to check the fix. -
Pin a known-good version for reproducible invocations instead of always getting "latest".
-
Serve many versions from a single alias (Maven GAV, a git tag/branch, or a
${jbang.app.version}path) without duplicating alias entries. -
Hand a version to a script that interprets it itself (the version is always passed as
-Djbang.app.version=<version>; see Versions passed to the script).
When not to use it
-
To change the default permanently — if everyone should get a different version, edit the alias
script-ref(or itspropertiesdefault) in the catalog instead; pinning is per-invocation only. -
Through an alias chain — if an alias points at another alias, pin the final target directly (see Alias Chains); pinning the wrapper is rejected.
-
Expecting real immutability from a mutable ref — pinning a git branch name (rather than a tag/commit) or a floating artifact version still resolves to whatever that ref points at today; it is a selector, not a lock file.
-
When nothing consumes the version — for a plain local-file
script-refwith no${jbang.app.version}placeholder and a script that never readsjbang.app.version, pinning only sets the (unused) property and otherwise does nothing.
Syntax
The version pinning syntax is: alias:version@catalog
Examples:
jbang mytool:1.5.0@mycatalog # Pin to version 1.5.0
jbang tool:v2.0.0@jbangdev # Pin to v2.0.0 from jbangdev catalog
jbang app:1.2.3 # Pin to 1.2.3 from local catalog
How It Works
When you specify a version, JBang applies different replacement strategies depending on the alias’s script reference:
Maven GAV Coordinates
For aliases that reference Maven artifacts, the version replaces the version component in the GAV coordinates:
{
"aliases": {
"picocli": {
"script-ref": "info.picocli:picocli-codegen:4.6.0"
}
}
}
Running jbang picocli:4.7.0 resolves to info.picocli:picocli-codegen:4.7.0
This works with:
Alias script-ref |
Invocation | Resolved script-ref |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Git URLs
For aliases that reference GitHub, GitLab, or Bitbucket URLs, the version replaces the branch/tag/ref in the URL:
| Provider | Alias script-ref |
Invocation | Resolved script-ref |
|---|---|---|---|
GitHub |
|
||
GitHub |
|
|
|
GitHub |
|
|
|
GitLab |
|
||
GitLab |
|
||
Bitbucket |
|
||
Bitbucket |
|
Property-Based Versioning
For maximum flexibility, aliases can use property placeholders that get replaced when a version is specified:
{
"aliases": {
"quarkus": {
"script-ref": "io.quarkus:quarkus-cli:${jbang.app.version:3.0.0}"
},
"example": {
"script-ref": "https://downloads.example.com/tools/mytool-${jbang.app.version:latest}.zip"
}
}
}
Running jbang quarkus:3.5.0 resolves to io.quarkus:quarkus-cli:3.5.0
Running jbang example:1.2.3 resolves to https://downloads.example.com/tools/mytool-1.2.3.zip
If no version is specified, the default value (after the colon) is used.
Property replacement takes precedence over automatic version replacement. If your alias uses ${jbang.app.version}, automatic replacement is skipped.
|
Versions passed to the script
Whenever an explicit version is requested (jbang alias:<version>), that version is exposed to the running script as the jbang.app.version system property (-Djbang.app.version=<version>), regardless of whether the script-ref was rewritten by any of the patterns above. The patterns only control whether the script-ref itself changes; the property is always set. The script can read it:
String version = System.getProperty("jbang.app.version", "dev");
This is especially useful when the script-ref matches none of the patterns (Maven GAV, a known Git URL, or a ${jbang.app.version} placeholder): the script-ref is left unchanged, but the script can still act on the requested version itself.
When no version is requested, the property is not set. See the Integration chapter for details on the reserved jbang.app.* namespace.
Alias Chains
Version pinning does not work through alias chains. If an alias references another alias, you must apply the version to the final target alias.
{
"aliases": {
"base-tool": {
"script-ref": "com.example:tool:1.0.0"
},
"tool": {
"script-ref": "base-tool"
}
}
}
Running jbang tool:2.0.0 fails with an error explaining that version pinning cannot be applied to an alias reference. Use the target alias directly, for example: base-tool:2.0.0.
Local Alias Catalogs
JBang will also look in the current directory for a jbang-catalog.json file and if it exists it will look up any aliases
in there too. In fact it will look in several places in the following order:
-
Current directory,
./jbang-catalog.json -
In
./.jbang/jbang-catalog.json -
In the parent directory,
../jbang-catalog.json -
In the parent’s
.jbangdirectory,../.jbang/jbang-catalog.json -
And repeating steps 3 and 4 recursively upwards to the root of the file system
-
As the last step it will look in
$HOME/.jbang/jbang-catalog.json
JBang will use any aliases defined in those files, but on top of that it will also look at the aliases defined in any catalogs mentioned in those files as well. Aliases defined in the file have preference over aliases found in any catalogs defined in the same file.
When you create aliases using jbang alias add, or add catalogs using jbang catalog add the same ordering will be used
to determine where to store the alias or catalog. Btw, this will only take into account existing files!
So if no jbang-catalog.json file exists in the local directory it will not be created for you, but JBang will keep
looking until it finds a file to use (as a last option it will always be written to $HOME/.jbang/jbang-catalog.json).
This means that if you want to write the alias to jbang-catalog.json in your local folder you will either have to create
the file first (eg by running touch jbang-catalog.json) or by explicitly specifying the file location:
jbang alias add -f jbang-catalog.json --name hello https://github.com/jbangdev/jbang-examples/blob/HEAD/examples/helloworld.java
Btw, the flag --show-origin is very useful when listing aliases to find out where exactly an alias is defined:
jbang alias list --show-origin
Catalogs
Catalogs are lists of Aliases as defined in the previous section, but while the alias command is used to manage aliases
within a catalog, the catalog command is for managing references to catalogs. This is mostly useful when dealing with
remote catalogs. You can for example add a catalog like this:
jbang catalog add --name demo https://github.com/jbangdev/jbang-catalog/blob/HEAD/jbang-catalog.json
or simply by using the same "implicit" catalog system described in Implicit Alias Catalogs:
jbang catalog add --name demo jbangdev
The aliases in that catalog are now available by adding @demo to their names. For example:
$ jbang alias list demo env@demo = Dump table of Environment Variables gavsearch@demo = Search search.maven.org for maven artifacts. hello@demo = Script that says hello back for each argument properties@demo = Dump table of System properties $ jbang run hello@demo World! [jbang] Building jar... Hello World!
In fact, it’s possible to run the alias just by using jbang run hello, the @demo part is only necessary when trying to
disambiguate between aliases with the same name from different catalogs.
You can list the available catalogs by running:
jbang catalog list
NB: The output will not only show the catalogs you defined yourself but also the ones that get added implicitly when running aliases as described in the section Implicit Alias Catalogs.