gg.cmd
is a cross-platform and cross-architecture command-line interface (CLI) that acts as an executable wrapper for
various tools such as Gradle, JDK/JVM, Node.js, and Java. It requires zero external dependencies - works on plain
Alpine and Ubuntu containers without curl/wget or updated CA certificates (all networking is built-in). Similar in
functionality to gradlew (without need for JDK initially installed).
Install with bash (wget):
wget ggcmd.io/gg.cmd
Install with bash (curl):
curl -L ggcmd.io > gg.cmd
Install with PowerShell:
wget ggcmd.io -OutFile gg.cmd
or
Install?
The concept involves placing a copy of gg.cmd
in the root directory of your project.
This is similar to what you would do with gradlew
or mvnw
, except this method is applicable to multiple tools.
As a result, your colleagues would not have to install anything on their host machines.
- Zero dependencies - Works on minimal containers (Alpine, Ubuntu) without curl/wget or CA certificates
- Simplify the management of other executables in your project
- Automatically detect and execute the required executable version using project configuration files (such
as
package.json
for Node.js projects) - Support for chaining multiple executables (e.g.
gradle@6:java@17
) - Cross-platform compatibility (Windows, macOS, and Linux)
- Cross-architecture compatibility (x86_64 and ARM)
- Fast and lightweight
By default, installs tools in a global cache directory ($HOME/.cache/gg
on Unix, %UserProfile%\.cache\gg
on
Windows).
Use the -l
flag to use a local cache (.cache/gg
in current directory) instead.
Adds every dependency into PATH
before executing.
Using gg.cmd
is easy. Simply place the executable in the root of your project and run it with the gg.cmd
command
followed
by the desired executable and its required dependencies:
./gg.cmd [gg options] <executable name>@<version><+include_tags><-exclude_tags>:<dependent executable name>@<version><+include_tags><-exclude_tags> [executable arguments]
sh gg.cmd npm install
Usage: ./gg.cmd [options] <executable name>@<version>:<dependent executable name>@<version> [program arguments]
Options:
-l Use local cache (.cache/gg) instead of global cache
-v Info output
-vv Debug output
-vvv Trace output
-w Even more output
-V, --version Print version
--os <OS> Override target OS (windows, linux, mac)
--arch <ARCH> Override target architecture (x86_64, arm64, armv7)
Built in commands:
update Update gg.cmd
help Print help
check Check for updates
check-update Check for updates and update if available
clean-cache Clean cache (prompts for confirmation)
Version syntax:
@X Any X.y.z version (e.g. node@14 for any Node.js 14.x.y)
@X.Y Any X.Y.z patch version (e.g. [email protected] for any Node.js 14.17.z)
@X.Y.Z Exactly X.Y.Z version (e.g. [email protected] for exactly Node.js 14.17.0)
@^X.Y.Z X.Y.Z or any compatible newer version (caret prefix)
@~X.Y.Z X.Y.Z or any newer patch version (tilde prefix)
@=X.Y.Z Exactly X.Y.Z version (equals prefix, same as X.Y.Z without prefix)
Supported tools:
node (npm, npx will also work, version refers to node version)
gradle
java
jbang
maven (mvn)
bld
openapi
rat (ra)
deno
go
caddy
just
fortio
flutter (dart will also work)
run (any arbitrary command)
gh/<owner>/<repo> (GitHub releases)
Available tags by tools:
java: +jdk, +jre, +lts, +sts, +mts, +ea, +ga, +headless, +headfull, +fx, +normal, +hotspot (defaults: +jdk, +ga)
node: +lts
go: +beta (excluded by default)
openapi: +beta (excluded by default)
flutter: +beta (excluded by default)
Version from:
engines
inpackage.json
- Contents of
.nvmrc
Version from:
distributionUrl
ingradle/wrapper/gradle-wrapper.properties
distributionUrl
ingradle.properties
Download URL from:
distributionUrl
ingradle/wrapper/gradle-wrapper.properties
distributionUrl
ingradle.properties
The Java version is read from the JBang script using the
//JAVA magic comment
.
Version from:
jdkVersion
ingradle/wrapper/gradle-wrapper.properties
jdkVersion
ingradle.properties
Version from:
environment.flutter
inpubspec.yaml
Here are a few examples of how gg.cmd
can make your life easier:
./gg.cmd gradle build
You can replace gradlew
with a single gg.cmd
and gradle.properties
and can
delete these files:
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties
gradlew
gradlew.bat
In this example, bld is used to run an app using bld
for the build process:
./gg.cmd bld run
./gg.cmd jbang script.java
./gg.cmd node@14
./gg.cmd gradle@6:java@17 clean build
./gg.cmd npm init -y
./gg.cmd npx create-react-app my-app
cp gg.cmd my-app
cd my-app
./gg.cmd npm start
gg.cmd
offers a GitHub executor.
It smartly checks the content and the available release files.
For instance, one can run GitHub's CLI tool:
> sh ./gg.cmd gh/cli/cli --version
gh version 2.73.0 (2025-05-19)
https://github.com/cli/cli/releases/tag/v2.73.0
gg.cmd
supports both global and local cache modes:
By default, tools are cached globally and shared across all projects:
- Unix/Linux/macOS:
$HOME/.cache/gg
- Windows:
%UserProfile%\.cache\gg
./gg.cmd node -v # Uses global cache
./gg.cmd gradle build # Uses global cache
Use the -l
flag to cache tools locally in the current project:
./gg.cmd -l node -v # Uses .cache/gg in current directory
./gg.cmd -l gradle build # Uses .cache/gg in current directory
Set the GG_CACHE_DIR
environment variable to use a custom cache location:
export GG_CACHE_DIR="/path/to/custom/cache"
./gg.cmd node -v # Uses /path/to/custom/cache
./gg.cmd -l node -v # Still uses /path/to/custom/cache (ignores -l)
Note: When GG_CACHE_DIR
is set, it takes precedence over both global and local cache modes.
We welcome contributions to gg.cmd
. If you have an idea for a new feature or have found a bug, please open an issue on
the GitHub repository.
gg.cmd
is licensed under the MIT License. See LICENSE for more information.