User Documentation v1.0.0
Everything you need to know about installing, configuring, and using Nuts Package Manager.
1 Introducing Nuts
nuts is the runtime package manager Java never had. It shifts dependency resolution from build-time to runtime, offering a streamlined and efficient way to manage libraries, tools, and dependencies across any OS.
Designed to fill the role that uv / uvx serves for Python or npx serves for JavaScript, nuts uses standard Maven POM descriptors to seamlessly provision Java applications and JDK runtimes. It allows you to run any Maven artifact instantly, side-by-side with other versions, without the bloat of fat JARs.
This documentation covers everything from installation and basic setup to advanced usage patterns and customization. Explore how nuts can elevate your Java workflows and simplify execution.
1.1 Overview
nuts (Network Updatable Things Services) is a portable runtime package manager for Java and the JVM. Think of nuts as the Java equivalent to Python's uv (or Node's npx): an all-in-one runtime package manager that transparently provisions JDKs, manages isolated workspaces, and executes any Maven artifact instantly on demand, side-by-side with other versions, without the bloat of fat JARs.
If you publish to Maven Central, your application is already a nuts package—no special registry or packaging format required.
The Problem
For years, Java has lacked a true runtime package manager. To distribute an application, developers typically build "fat JARs" (shadow JARs) containing all dependencies. This approach has significant drawbacks:
Bloat: Bundling dependencies inflates file sizes, wasting disk space and network bandwidth.
No side-by-side versioning: Running multiple versions of the same tool locally often involves brittle scripts or environment variable juggling.
Complex runtime setup: Users must manually ensure the correct JDK version is installed before they can run a Java application.
Poor CLI experience: There is no simple
install and runworkflow native to the ecosystem.
The Solution
nuts shifts dependency resolution from build-time to runtime. It natively understands standard Maven POM descriptors, dynamically fetching and resolving required dependencies precisely when an application is executed.
nuts install org.example:myapp
nuts myapp
Core Concepts
Artifacts: A package or application. In nuts, any standard Maven coordinate (
groupId:artifactId#version) is a valid artifact. Beyond JARs and WARs, nuts supports multiple artifact formats adapted to target operating systems.Repositories: Storage locations for artifacts. A repository can be local or remote (such as Maven Central). nuts can proxy remote repositories to cache artifacts locally.
Workspaces: Isolated environments managing a set of repositories and configurations, much like Python's uv workspaces or virtualenv. Workspaces isolate dependencies on a per-project basis.
Descriptors: Metadata defining an artifact's dependencies. nuts parses descriptors at runtime and gracefully resolves dependencies over the network.
Key Differentiators
Zero External Dependencies: The nuts bootstrap JAR is entirely self-contained.
Cross-Platform: Operates with identical behavior across Linux, macOS, and Windows.
Workspace Isolation: Supports isolated environments, keeping your global setup clean.
JDK Auto-Provisioning: Automatically detects, downloads, and configures the appropriate JDK version (and vendor) required by the application.
Structured Output: Built-in support for generating output in JSON, YAML, XML, TSON, and plain text formats.
Self-Hosting: nuts manages itself—using the same mechanisms to install, update, and uninstall its own binaries.
What Nuts is NOT
Not a build tool: You still use Maven, Gradle, or Ant to compile and package your code. nuts is used to install, update, and run the resulting artifacts.
Not a replacement for Maven Central: nuts seamlessly consumes artifacts from Maven Central and standard repositories rather than replacing them.
Command-Line Verbs Overview
nuts provides a rich CLI with intuitive command verbs:
| Command Verb | Description |
|---|---|
exec | Execute an artifact or a system command. |
which | Detect the proper artifact or system command path to execute. |
install / uninstall | Install or remove an artifact using its deployed installer. |
update / check-updates | Search the repository for newer versions of installed artifacts. |
deploy / undeploy | Manage artifacts (and artifact installers) within local repositories. |
fetch / push | Download artifacts from, or upload artifacts to, remote repositories. |
search | Query and discover existing or installable artifacts. |
welcome | Bootstraps the environment and displays a welcome message. |
Nuts Application Framework (NAF)
nuts is built upon the Nuts Application Framework (NAF), a robust foundation for building feature-rich Java applications. If you are developing applications that deeply integrate with nuts, refer to the NAF documentation.
1.2 Installation
Interactive Download Center
For interactive platform selection, custom release channels, standalone executables, GUI installers, bundled JRE packages, and Docker commands:
Interactive Download Wizard
Visit the official Nuts Download & Release Hub to choose your version, platform, and preferred installation package.
Quick Terminal Install
If you prefer installing directly from your command line:
# Linux / macOS (Stable Release)
curl -s https://thevpc.net/nuts/install-stable.sh | bash
# Linux / macOS (Latest Release)
curl -s https://thevpc.net/nuts/install-latest.sh | bash
# Windows (Command Prompt / PowerShell)
# Download nuts-app-latest.jar and run:
java -jar nuts-app-latest.jar -Zy
After installation, restart your terminal session so that environment paths and shell integration take effect.
System Requirements
nuts is lightweight and designed to run on any major operating system:
Java: Requires Java Runtime Environment (JRE) or Java Development Kit (JDK) version 8 or higher (tested up to Java 25). For Java 1.8, update 150+ is required.
Disk Space: ~15MB for the minimal nuts installation. Additional space is used for your local package cache (typically 100MB to 500MB depending on usage).
Memory: Operates comfortably in ~300MB RAM when JVM heap is capped (e.g.
NUTS_JAVA_OPTIONS=-Xmx32m). By default, HotSpot dynamically sizes memory according to total system RAM.Operating System: Linux (all distributions), macOS (Intel & Apple Silicon), Windows 7 and later.
Verify your local Java version before installing:
java -version
Verifying Installation
To verify that nuts is correctly installed and accessible in your PATH, open a new terminal and run:
nuts --version
Output will display the installed API and runtime implementation versions:
1.0.0/1.0.0.0
Next Steps
Now that nuts is installed, proceed to the First App guide to install and launch your first package.
1.3 First App
Now that nuts is installed on your system, let's walk through installing, running, and managing your first applications.
Note: If you have not installed nuts yet, see the Installation Guide or visit the Download Page.
1. Running a GUI Application
Let's install jedit, a popular open-source text editor built for Java.
Install jedit in your workspace:
nuts install org.jedit:jedit
Once installed, launch it directly using its application name:
nuts jedit
nuts automatically resolves the required dependencies, provisions the execution environment, and launches the application window.
2. Running a CLI Tool
nuts manages command-line tools just as effortlessly as desktop apps. Let's install nsh (Nuts Shell), a portable bash-compatible shell environment:
nuts install net.thevpc.nuts.toolbox:nsh
Launch the shell:
nuts nsh
You are now inside the Nuts Shell session. Type exit to return to your standard terminal.
3. Managing Packages
List Installed Packages
To view all packages installed in your current workspace:
nuts search --installed
Search for Packages
To discover packages available in remote repositories:
nuts search netbeans
Update Packages
To check for and apply updates across all installed packages:
nuts update
Uninstall a Package
To cleanly remove a package when it is no longer needed:
nuts uninstall org.jedit:jedit
Next Steps
Congratulations! You've learned how to install, launch, and manage applications with nuts.
Explore the Tutorials for in-depth guides on workspace configuration, aliases, and custom repositories.
Check out the How-To Guides for practical solution recipes.
1.4 Quick Reference
Quick Reference
| Task | Command |
|---|---|
| Install an app | |
| Run an app | |
| Run a specific version | |
| List installed apps | |
| Update all apps | |
| Create a workspace | |
| Provision a JDK | |
| Create an offline bundle | |
| Run on a remote host | |
| Reset workspace | |
| Enable secure mode | |
2 Tutorials
Step-by-step tutorials to help you get started with nuts. These guides will walk you through common workflows and scenarios to build your proficiency.
2.1 Running Nuts
What You'll Learn In this section, you will learn the fundamentals of using the nuts package manager to run Java applications. We will cover:
- Running remote and deployed artifacts seamlessly.
- Understanding and using artifact long IDs (Maven coordinates).
- Installing applications before running them.
- Searching your workspace for installed artifacts.
- Executing local JAR files with auto-provisioned dependencies.
- Using different execution modes (spawn, embedded, system).
In this section, we will explore the core usage of the nuts package manager: running applications. Because nuts is designed to act as a runtime package manager for Java, it handles dependencies, classpaths, and JVM arguments dynamically.
Running a Deployed Artifact
You can run any JAR using nuts, provided the JAR is accessible from one of your configured repositories. By default, nuts supports:
- Maven Central
Local Maven folder (
~/.m2/repository)
You can also configure additional repositories (like Nexus or Artifactory) or implement your own if you need to.
When you run an artifact, the JAR is parsed to check its Maven descriptor (pom.xml properties). nuts will resolve and download all necessary dependencies on the fly. After resolving dependencies, all executable classes (classes containing a public static void main method) are enumerated. If there are multiple entry points, you can choose which one to run when prompted.
Any standard JAR built with Maven or Gradle can be executed by referencing its artifact ID.
Artifact Long IDs
nuts uses "Long IDs" to uniquely identify artifacts. These strings follow the standard Maven coordinate format:
groupId:artifactId#version
For instance, to install and run netbeans-launcher (a simple UI utility that helps launch multiple instances of NetBeans), you can execute:
nuts net.thevpc.app:netbeans-launcher#1.2.2
Typing out the full groupId and version every time can be cumbersome. To simplify this, you can omit them when running commands:
nuts netbeans-launcher
When you use this short form, nuts auto-detects both the groupId and the version. The group ID is resolved if it matches an imported prefix (we will cover imports in detail later). By default, several group IDs are automatically imported:
net.thevpc(contains various core applications)net.thevpc.nuts.toolbox(contains companion tools like nsh, ndb, etc.)
Because netbeans-launcher belongs to an imported group ID, the prefix can be safely omitted. Additionally, if no version is provided, nuts automatically selects the best version to execute. If you already have one or more versions installed, the default installed version will be used. If you have not installed it yet, the most recent stable version will be resolved and fetched for you.
Artifact Installation
Any Java application can run using nuts, but it must be downloaded and installed first. If you attempt to run an application that is not yet installed in your local workspace, you will be prompted to confirm the installation.
To explicitly install an application without immediately running it, use the install command:
nuts install netbeans-launcher
If you try to run the application directly via nuts netbeans-launcher, the installation happens automatically (after you confirm the prompt).
Searching Artifacts
To view the artifacts currently installed in your workspace, use the search command:
nuts search --installed
This lists all installed artifacts. For a more detailed view, you can use the long format flag -l:
nuts search --installed -l
The output will look similar to this:
I-X 2024-03-15 14:30:22 anonymous vpc-public-maven net.thevpc.app:netbeans-launcher#1.2.0
i-X 2024-03-15 14:28:05 anonymous vpc-public-maven net.thevpc.app:netbeans-launcher#1.2.2
Here is how to interpret the output columns:
Status Flags (Column 1): The first column provides compact status information.
I (uppercase) means "installed and default".
i (lowercase) means "installed".
X (uppercase) stands for "executable application aware of nuts" (meaning it uses the nuts API for features like OnInstall or OnUninstall hooks).
x (lowercase) simply means "executable" (a standard Java application with a main method).
Date and Time (Columns 2 & 3): When the artifact was installed.
User (Column 4): The user who performed the installation. If secure mode is disabled (the default), this shows as anonymous.
Repository (Column 5): The source repository from which the package was fetched.
Long ID (Column 6): The full artifact identifier.
Running Local JAR Files
Let's suppose you have a file named my-app.jar built with Maven. Even if it is just a local file, nuts is capable of reading its embedded META-INF/maven files, resolving its external dependencies on the fly, and running it.
If a Main-Class attribute is present in a valid MANIFEST.MF, it will be executed. If multiple classes have a main method and no primary class is specified, nuts will list them and ask which one you want to run.
To run a local file, simply provide the path (which must contain a / or \ to be recognized as a file path rather than an artifact ID):
nuts ./my-app.jar some-argument-of-my-app
Dependencies defined in the JAR's internal POM will be downloaded and cached in your workspace automatically.
Passing JVM Arguments
If you need to pass JVM arguments (such as memory limits or system properties), you must prefix them with the exec command. For instance, to set the initial and maximum heap size:
nuts exec -Xms1G -Xmx2G ./my-app.jar argument-1 argument-2
You can also use this syntax to dynamically provision and select a specific Java version for the execution:
nuts exec --java-version=17 ./my-app.jar
Execution Modes
When running applications, nuts supports different execution modes to control how the process is launched. These can be specified using flags:
--spawn (Default): Launches the application in a completely new JVM process. This provides maximum isolation and ensures the application's environment variables and memory space are separate from the nuts process itself.
--embedded: Runs the application within the same JVM process as nuts. This is faster since it avoids the overhead of starting a new JVM, but it provides less isolation. It is useful for trusted plugins or small utilities.
--system: Delegates the execution directly to the underlying operating system. This is typically used when running native commands or system scripts rather than Java applications.
For example, to force an application to run in embedded mode:
nuts --embedded netbeans-launcher
2.2 Versions
What You'll Learn In this section, you will learn how nuts handles artifact versioning. We will cover:
- Installing and running multiple side-by-side versions of the same application.
- Understanding version syntax (exact versions, version ranges, and latest).
- Managing the default version for an artifact.
- Listing all installed versions of an application.
- Uninstalling specific versions to clean up your workspace.
Multiple Artifact Version Installation
One of the key features of nuts is its ability to install multiple versions of the same application side-by-side without conflicts. This is particularly useful when testing updates or when different projects require different versions of a tool.
We can, for instance, install two separate versions of netbeans-launcher:
nuts install netbeans-launcher#1.2.2
# then
nuts install netbeans-launcher#1.2.0
Now we have two versions installed simultaneously. You can run either one by explicitly specifying its version in the command:
nuts netbeans-launcher#1.2.2 &
# or
nuts netbeans-launcher#1.2.0 &
Default Versions
When you have multiple versions installed for the same artifact and you try to run it without specifying the version, nuts needs to know which one to pick. Every artifact has a default version assigned to it.
By default, the last version you installed becomes the default version.
In our earlier example, since #1.2.0 was installed after #1.2.2, it became the default. If you type:
nuts netbeans-launcher &
The 1.2.0 version will be invoked.
Switching the Default Version
If you want to switch the default back to version 1.2.2, you simply re-install it:
nuts install netbeans-launcher#1.2.2
Don't worry—no files will be downloaded again. nuts will detect that the version is already cached but is not currently marked as default, and it will immediately update the default pointer.
Version Syntax
When specifying versions in nuts, you have several options beyond just exact version numbers. nuts supports standard Maven versioning syntax:
Exact Versions: Specify the exact version number after the
#symbol. Example:nuts install my-app#1.2.3Version Ranges: Use mathematical interval notation to specify acceptable ranges. Brackets
[]are inclusive, while parentheses()or reversed brackets][are exclusive. Example:nuts install my-app#[1.0,2.0[(Installs the highest available version that is >= 1.0 and < 2.0).Latest Version: Simply omit the version entirely. nuts will query the repositories to find the highest stable release. Example:
nuts install my-app
Listing Installed Versions
If you want to see all the versions of a specific artifact that you currently have installed, you can use the search command combined with the --installed flag:
nuts search --installed netbeans-launcher
To see which version is marked as default, add the -l (long format) flag. The default version will be marked with a capital I in the first column, while non-default installed versions will be marked with a lowercase i.
nuts search --installed -l netbeans-launcher
Uninstalling a Specific Version
To keep your workspace clean, you may eventually want to remove older versions of an application. You can use the uninstall command and specify the exact version you want to remove:
nuts uninstall netbeans-launcher#1.2.0
If you omit the version (nuts uninstall netbeans-launcher), nuts will prompt you to select which version(s) you wish to remove or confirm if you want to remove all of them.
Summary of Version Commands
| Goal | Command |
|---|---|
| Install a specific version | |
| Run a specific version | |
| Run the default version | |
| Change the default version | |
| List all installed versions | |
| Uninstall a specific version | |
2.3 Workspace
What You'll Learn In this section, you will learn how to manage and isolate your environments using nuts workspaces. We will cover:
- What workspaces are and how they provide isolation (similar to Python's virtualenv).
- How to create, switch, and delete workspaces.
- The differences between Exploded and Standalone storage strategies.
- Practical use cases for using multiple workspaces.
What is a Workspace?
A workspace in nuts is a completely isolated environment. It contains its own set of installed artifacts, configuration files, caches, configured repositories, and even its own automatically provisioned JDKs.
If you are familiar with Python's virtualenv or Node's nvm, a nuts workspace serves a similar purpose for Java and JVM applications. By default, anything you install, configure, or run happens inside a workspace. There is no system-wide bleeding of state unless explicitly shared.
The Default Workspace
When you run nuts for the first time, it automatically creates the default workspace. On most systems, the configuration for this default workspace is located at:
~/.config/nuts/default-workspace
If you do not specify a workspace in your commands, nuts will always use this default environment.
Creating and Switching Workspaces
You do not need a special command to "create" a workspace. You simply specify the workspace name using the -w (or --workspace) flag, and nuts will create it automatically if it does not exist.
For example, to install an artifact into a brand new workspace named my-workspace:
nuts -w my-workspace install netbeans-launcher
To run a command within that workspace, you simply include the flag again:
nuts -w my-workspace netbeans-launcher
Because each workspace is a complete sandbox, applications installed in the default workspace will not be available in my-workspace (and vice versa) unless you explicitly install them there.
Storage Strategies
When you create a new workspace, you can choose how its files are stored on your disk. nuts offers two primary storage strategies:
1. Exploded Strategy (Default)
The Exploded strategy strictly follows the XDG Base Directory Specification on Linux (and equivalent native patterns on Windows and macOS). Files are dispersed across appropriate system directories based on their purpose:
Configurations go to
~/.config/nuts/Caches and downloads go to
~/.cache/nuts/Installed binaries and libraries go to
~/.local/share/nuts/Logs go to
~/.local/state/nuts/(or similar logging directories)
This is the recommended strategy for standard desktop usage, as it respects OS-level backup policies and disk usage tools. To explicitly create a workspace with this strategy:
nuts -w my-workspace --exploded
2. Standalone Strategy
The Standalone strategy keeps everything related to the workspace strictly confined to a single directory folder.
This strategy is ideal for portability. You can create a standalone workspace on a USB flash drive, take it to another computer, and all your applications, settings, and Java runtimes will function identically without polluting the host machine.
To create a standalone workspace, use the --standalone flag and provide a path:
nuts -w /path/to/portable-workspace --standalone
Workspace Isolation
Each workspace is completely self-contained. When you switch workspaces, you are switching:
- The list of installed applications and their specific versions.
- Repository configurations and credentials.
- Aliases, launchers, and imported group IDs.
- Local Maven/dependency caches.
- Automatically provisioned JDKs.
Practical Use Cases
Workspaces are incredibly powerful tools for developers and system administrators:
Environment Separation: Maintain separate dev, staging, and prod workspaces to test different configurations or application versions side-by-side.
CI/CD Ephemeral Workspaces: In a Continuous Integration pipeline, you can use a temporary workspace (e.g.,
nuts -w temp-$$ ...) to guarantee a pristine, reproducible environment that is destroyed after the job finishes.Testing Upgrades: Safely test a new version of a tool in a sandbox workspace without breaking your daily workflow in the default workspace.
This will output a list of available workspaces, along with their paths and storage strategies.
Resetting a Workspace
If you are whant to reset all of workspace config and files you can use the reset mode (-Z flag) combined with the workspace flag.
nuts -ZQ -w my-workspace
Deleting a Workspace
If you are done with a workspace and want to reclaim disk space, you can delete it using the reset-quit mode (-ZQ flags) combined with the workspace flag.
nuts -ZQ -w my-workspace
Deleting all common Workspaces, Uninstalling nuts
This performs a hard reset/deletion of the specified workspace, removing all installed artifacts, caches, and configurations associated with it. Ensure you are targeting the correct workspace before running this command.
nuts --reset-hard
2.4 Aliases, Imports & Launchers
What You'll Learn In this section, you will learn how to create shortcuts and simplify command execution in nuts. We will cover:
Imports: How to omit group IDs when running artifacts.
Aliases: How to create custom commands with preset arguments.
Launchers: How to generate desktop icons and system menu entries for applications.
Command Precedence: How nuts resolves what to execute when you type a command.
By default, Maven artifacts are uniquely identified by their full Long ID, consisting of a groupId, artifactId, version, and sometimes a classifier. For instance, to invoke the nsh shell, you would theoretically need to type:
nuts net.thevpc.nsh:nsh#1.0.0.0
This is cumbersome for daily use. nuts provides three features—Imports, Aliases, and Launchers—that allow you to call artifacts with simple words or clicks instead of typing full coordinates.
Imports
Imports allow you to discard the groupId and call or install artifacts using only their artifactId. When you add an import for com.my-company, any artifact belonging to that group ID will be resolved automatically.
For example, without imports, running nsh looks like this:
nuts net.thevpc.nsh:nsh#1.0.0.0
If we import the group ID, we can omit it entirely:
nuts settings add import net.thevpc.nsh
# Now call it simply with the artifactId:
nuts nsh#1.0.0.0
# Or, if you want the default/latest version, even simpler:
nuts nsh
Note: By default, nuts already imports a few core group IDs, including net.thevpc, which is why many built-in companion tools work immediately without requiring you to configure imports manually.
Aliases
Aliases allow you to define your own custom commands by wrapping existing artifacts and pre-defining specific arguments. This is very similar to standard shell aliases (e.g., where ll is defined as an alias for /bin/ls -l).
Let's say you frequently run a tool with a specific set of verbose flags and custom parameters:
nuts settings add alias ll='net.thevpc.nsh:nsh#1.0.0.0 -c ls -l'
Now, instead of typing the full artifact ID and its arguments, you can simply call your alias:
nuts ll
Aliases are powerful because they are stored securely in your workspace configuration and persist across sessions, unlike standard shell aliases which are often bound to a specific terminal profile (like .bashrc).
Launchers
Launchers take the concept of an alias one step further by integrating directly with your Operating System's desktop environment. Launchers allow you to create Desktop Environment shortcuts, system menu entries, and icons (whenever a GUI is applicable).
To create a launcher that adds a shortcut to your OS applications menu and your desktop:
nuts settings add launcher --menu --desktop 'net.thevpc.nsh:nsh#1.0.0.0'
After running this command, you no longer need the terminal to start the application. You can simply click on the new desktop icon or open it via your OS application menu.
Command Precedence
When you type a short command like nuts build, how does nuts know exactly what you mean? nuts resolves commands using a strict order of precedence:
1. Built-in Commands: First, nuts checks if the word is a core command (e.g., install, search, settings).
2. Aliases: If it's not a built-in command, it checks your configured workspace aliases.
3. Imported Artifacts: Next, it appends your configured Imports (group IDs) to see if an installed artifact matches the name.
4. Full Artifact ID: It checks if the string itself is a valid, resolvable Long ID in your configured repositories.
5. System Commands: Finally, if all else fails, it may attempt to delegate to the underlying operating system path, depending on your execution mode.
Managing Configurations
You can easily manage your aliases, imports, and launchers using the settings command.
Listing
To view what is currently configured in your workspace:
nuts settings list imports
nuts settings list aliases
nuts settings list launchers
Removing
To remove a configuration, use the remove subcommand:
nuts settings remove import net.thevpc.nsh
nuts settings remove alias ll
Summary Comparison
| Feature | Purpose | Scope | Example |
|---|---|---|---|
Import | Omits the groupId so you can use the artifactId directly. | Workspace-wide resolution | |
Alias | Creates a custom shorthand command for an artifact + arguments. | Workspace CLI command | |
Launcher | Integrates an application into the OS UI (desktop/menus). | OS Desktop Environment | |
2.5 Repositories
What You'll Learn In this section, you will learn how nuts resolves and fetches artifacts. We will cover:
- What repositories are and the default configuration.
- How to add and remove repositories.
- Supported repository types (Local, HTTP/HTTPS, SSH).
- How repository search priority works.
- Using proxy repositories and authenticated private repositories.
What are Repositories?
Repositories are the source locations where nuts looks for artifacts (JAR files, POM descriptors, and other dependencies) when you attempt to install or run an application. Because nuts uses standard Maven POM descriptors, any Maven repository can act as a nuts repository.
By default, every nuts workspace is pre-configured with two standard repositories:
1. Local Maven Repository: Your local
~/.m2/repositorydirectory (if it exists).2. Maven Central: The public global Maven repository.
This means that out of the box, any Java application or library published to Maven Central is immediately executable via nuts.
Listing Repositories
To see the repositories currently configured in your workspace, use the settings list repos command:
nuts settings list repos
This will output a list showing the internal name of each repository, its URL or path, and its active status.
Adding a Repository
If your team uses a private Nexus, Artifactory, or a custom remote repository, you can add it to your workspace. Use the settings add repo command, providing a unique name and the repository's URL:
# Add a public remote repository
nuts settings add repo my-company-repo https://repo.mycompany.com/maven2/
# Add a local directory as a repository
nuts settings add repo my-local-repo /path/to/local/repo/
Once added, nuts will immediately begin querying this new repository whenever you search for, install, or run an artifact.
Removing a Repository
To remove a repository from your workspace configuration, use its assigned name with the remove command:
nuts settings remove repo my-company-repo
Repository Types
nuts supports several repository protocols to accommodate different network environments and deployment strategies:
Local Folders: Standard file paths on your local machine (e.g.,
/var/lib/maven/repo). Ideal for offline development or testing locally built artifacts.HTTP/HTTPS: Standard web-based Maven repositories (e.g., Nexus, Artifactory, Maven Central). This is the most common format.
SSH Remote Paths: You can configure nuts to fetch artifacts securely over SSH. This is highly useful for small teams or private deployments that do not want to manage a full Nexus server.
Repository Priority
When you request an artifact, nuts does not broadcast the request to all repositories simultaneously. Instead, it searches them in a strict order of priority.
1. Local Workspace Cache: First, it checks if the artifact is already cached in the current workspace.
2. Local Repositories: Next, it checks local directory repositories (like
~/.m2/repository).3. Remote Repositories: Finally, it queries remote HTTP/HTTPS/SSH repositories in the order they were added to the workspace.
This priority system ensures that local builds are always preferred over remote downloads, saving bandwidth and speeding up execution.
Proxy Repositories
nuts natively caches downloaded artifacts in your workspace. When it downloads an artifact from a remote HTTP repository, that artifact is stored locally. This effectively makes the workspace act as a proxy cache. If you run the command again, or if another application depends on the same library, nuts will serve it from the local cache rather than re-downloading it from the remote repository.
Private and Authenticated Repositories
Many corporate environments secure their repositories behind authentication. nuts supports credential management for accessing these private repositories.
While the deep dive into the security model is covered in the Security documentation, you can securely configure credentials for a repository so that nuts can authenticate seamlessly:
nuts settings add repo private-nexus https://nexus.corp.com/repository/maven-releases/
nuts security add credentials --repo private-nexus --username myuser --password mytoken
Once configured, nuts will automatically inject these credentials whenever it communicates with private-nexus.
2.6 Structured Output
What You'll Learn In this section, you will learn how to extract machine-readable data from nuts. We will cover:
- How to format command output using standard data structures (JSON, YAML, XML, etc.).
- Using Bot Mode for automation and CI/CD environments.
Piping formatted output to command-line processing tools like jq and yq.
Overview
A core philosophy of nuts is that it should be just as easy for a script to use as it is for a human. To support this, every built-in nuts command can emit its output in multiple structured formats.
Instead of writing complex grep and awk commands to parse plain text, you can ask nuts to output JSON or YAML directly, making integration with other tools and scripts completely frictionless.
Available Formats
You can change the output format of any command by passing the format flag before the command name. The supported formats are:
--plain (Default): Human-readable text format.
--json: Standard JSON array/object format.
--yaml: Standard YAML format.
--xml: Standard XML format.
--table: Tabular text format (great for terminal readability).
--tree: Hierarchical tree format (useful for dependency graphs).
--props: Java properties format (
key=value).--tson: Typed String Object Notation (a custom compact format).
Examples in Action
Let's look at how the same command behaves when we change the output format. We will use nuts search --installed, which lists the artifacts currently installed in the workspace.
JSON Output
nuts --json search --installed netbeans-launcher
Output:
[
{
"id": "net.thevpc.app:netbeans-launcher#1.2.2",
"name": "netbeans-launcher",
"version": "1.2.2",
"status": "installed"
}
]
YAML Output
nuts --yaml search --installed netbeans-launcher
Output:
- id: "net.thevpc.app:netbeans-launcher#1.2.2"
name: "netbeans-launcher"
version: "1.2.2"
status: "installed"
Table Output
nuts --table search --installed netbeans-launcher
Output:
ID Version Status
-- ------- ------
net.thevpc.app:netbeans-launcher 1.2.2 installed
Bot Mode for CI/CD
When you are writing scripts for a Continuous Integration/Continuous Deployment (CI/CD) pipeline, you want to ensure that the CLI tool never hangs waiting for user input and doesn't pollute the logs with ANSI color codes.
nuts provides a dedicated --bot mode for this exact scenario. When you include the --bot flag:
- 2. All interactive prompts are disabled (it assumes "yes" or default answers).
- 2. Terminal color formatting is stripped out.
- 3. Progress bars are disabled.
nuts --bot --json install my-automated-tool
(Alternatively, you can also use --yes or -y if you just want to auto-confirm prompts without stripping colors).
Piping to Processing Tools
Because nuts generates standard structured data, you can seamlessly pipe its output into popular command-line JSON/YAML processors.
Using jq for JSON
If you want to extract just the artifact IDs from your installed applications, you can pipe the JSON output directly to jq:
nuts --json search --installed | jq -r '.[].id'
Using yq for YAML
Similarly, if you are querying workspace configurations and prefer YAML, you can use yq:
nuts --yaml settings list repos | yq '.[].url'
Using xmlstarlet for XML
For legacy systems or enterprise environments that rely heavily on XML:
nuts --xml search --installed | xmlstarlet sel -t -v "//id"
Practical Use Cases
Structured output enables powerful automation workflows:
Monitoring Scripts: A cron job can run
nuts --json update --checkand send the resulting JSON to a monitoring dashboard or Slack bot to alert the team about available updates.CI/CD Pipelines: A GitHub Action can dynamically resolve the latest version of a tool using
nuts --json search my-tooland parse the output to configure the rest of the build matrix.Workspace Auditing: Security teams can run
nuts --json search --installedto generate a machine-readable Software Bill of Materials (SBOM) of everything currently active in the workspace.
3 How-To Guides
Goal-oriented guides focusing on specific tasks and features. Find practical solutions for everyday challenges when using nuts in your development environment.
3.1 Provision JDK
Provision a JDK
One of the most powerful features of nuts is its ability to manage its own runtime environment. In traditional Java development, you must manually install, configure, and switch between different JDK versions across projects. With nuts, you can auto-provision JDKs on demand, ensuring your applications always run with the correct Java version without manual intervention.
Auto-detect Local JDKs
If you already have Java installed on your system, you can instruct nuts to scan your local machine and register any existing JDK installations. This allows nuts to utilize your existing toolchains:
nuts settings add java --search
Download a Specific JDK
When an application requires a Java version that is not installed on your system, you can provision it directly. nuts will download the JDK, verify it, and register it in the workspace:
nuts settings add java --download --jdk --version=21
Download Only JRE (Smaller Footprint)
If you only need to run Java applications and do not require compilation tools (like javac), you can provision a Java Runtime Environment (JRE). This significantly reduces download size and disk footprint:
nuts settings add java --download --jre --version=21
Select a Specific Vendor
By default, nuts provisions Java from the Eclipse Temurin (Adoptium) distribution. However, the provisioning system is SPI-extensible, allowing you to choose your preferred vendor:
nuts settings add java --download --vendor=temurin --version=21
Supported Vendors
The following vendors are commonly supported for auto-provisioning:
| Vendor ID | Distribution | Notes |
|---|---|---|
temurin | Eclipse Temurin (Adoptium) | Default open-source distribution. Highly recommended. |
oracle | Oracle JDK | Official Oracle distribution. |
graalvm | GraalVM | High-performance JDK with AOT compilation capabilities. |
zulu | Azul Zulu | Certified builds of OpenJDK. |
corretto | Amazon Corretto | No-cost, multiplatform, production-ready distribution. |
Using a Specific JDK for Execution
Once your JDKs are provisioned (or even if they aren't yet), you can instruct nuts to execute an application using a specific Java version. If the requested version is not currently available in the workspace, nuts will automatically attempt to provision it before running the app:
nuts exec --java-version=11 my-app
Listing Available JDKs
To view all JDKs currently registered in your nuts workspace, use the settings command. This will output a list of available environments, their versions, and their local paths:
nuts settings list java
3.2 Create Bundles
Create an Air-Gapped Bundle
A bundle is a self-contained, highly portable package of a nuts workspace that includes one or multiple applications and all its dependencies. Bundles are designed to run on machines without internet access or an existing nuts installation, solving the "fat-JAR" problem while keeping the target workspace isolated.
Creating a Bundle
To create a bundle, use the nuts bundle command with one or more application ids:
nuts bundle myapp#1.2.3
By default this produces a single executable jar named after the resolved application name and version (e.g. myapp-1.2.3-bundle.jar) in the current directory. You can set an explicit destination with --target:
nuts bundle myapp#1.2.3 --target myapp-bundle.jar
Multiple Applications
You can bundle multiple distinct applications into a single bundle artifact:
nuts bundle app-core#1.0.0 app-cli#1.0.0 app-admin#2.1.0 --target my-suite-bundle.jar
When multiple applications are bundled, each application gets its own dedicated OS launcher script in unpacked formats (--exploded / --dir).
Adding Non-Executable Libraries
Use --lib to include dependencies or runtime plugins without generating dedicated launcher scripts or entry points for them:
nuts bundle myapp#1.2.3 --lib org.postgresql:postgresql#42.7.2
Anatomy of a Bundle
A jar/zip bundle packages everything required to execute the application:
A minimal embedded nuts bootstrap runner (NutsBundleRunner)
The application artifact(s) and all resolved dependencies, laid out under
META-INF/bundlePer-OS launcher scripts (
.shfor Linux/macOS/Unix,.batfor Windows)Bundle metadata (
nuts-bundle-info.config,nuts-bundle-files.config) describing what to install and where
A generated bundle contains all resources required for autonomous bootstrapping:
my-bundle.jar (or unpacked folder)
├── META-INF/
│ ├── MANIFEST.MF
│ └── bundle/
│ ├── nuts-bundle-info.config # Application descriptor & entry points
│ ├── nuts-bundle-files.config # Inventory of packaged artifacts
│ └── repo/ # Local repository containing application jars & dependencies
├── bin/ (in exploded/dir formats)
│ ├── myapp # POSIX launcher script (Linux / macOS)
│ └── myapp.bat # Windows Command script
└── org/vpc/nuts/... # Embedded bootstrap runner (NutsBundleRunner)
Bundle Packaging Formats
Choose the output layout with one of:
--jar / --as-jar (default) — a single executable jar
--zip / --as-zip — a zip archive with the same contents
--exploded / --as-exploded — an unpacked folder that still carries the bundle metadata files, so it can be cleaned (--clean) and rebuilt in place
--dir / --as-dir — a plain unpacked folder with no bundle metadata files
nuts bundle myapp#1.2.3 --exploded --target ./myapp-bundle --clean
Naming and Metadata
The default bundle name is derived from the resolved application name and version, but can be overridden:
--app-name / --name — application name used in the default file/folder name
--app-version — application version used in the default file/folder name
--app-title / --title — title stored in the bundle info
--app-desc / --desc — description stored in the bundle info
Runtime Behavior Flags
A few options control how the embedded workspace behaves when the bundle is later executed on the target host:
--embedded — run the embedded workspace in embedded mode
-y, --yes — auto-confirm prompts on execution
-z, --reset — reset the embedded workspace on execution
-l, --verbose — run the embedded workspace verbosely on execution
Execution on Target Systems
The target machine only requires a standard Java Virtual Machine (matching the application's bytecode requirements).
1. Running a JAR Bundle
Execute the archive directly using the JVM:
java -jar myapp-bundle.jar [application arguments...]
2. Running from Directory / Exploded Formats
Run the target application's launcher script:
Linux / macOS:
./myapp [application arguments...]Windows:
myapp.bat [application arguments...]
Workspace Initialization Lifecycle
Upon first execution on the host:
The bundle detects its runtime environment and sets up an isolated workspace directory (
.nuts-bundle/) adjacent to the bundle or launcher.Embedded dependencies from
META-INF/bundle/repo/are registered in the local repository cache (.nuts-bundle/lib/).The embedded workspace is initialized (
.nuts-bundle/ws/) without altering the host's existing user configuration or requiring elevated system privileges.- Subsequent executions skip unpacking and boot directly from the prepared local workspace cache.
Use Cases
Air-Gapped & Offline Deployments: Deploy mission-critical services to isolated networks with zero internet connectivity.
Firewalled Corporate Hosts: Bypass restrictive corporate proxy configurations that interfere with dynamic dependency resolution.
Frictionless Distribution: Ship CLI tools or desktop utilities as single self-contained binaries to users without requiring them to install or configure package managers.
Predictable Demos & Testing: Distribute deterministic, reproducible snapshots of multi-service suites for testing and offline presentations.
3.3 Remote Execution
Run on a Remote Host
nuts provides seamless, transparent remote execution capabilities. You can execute nuts commands and launch applications on remote servers via SSH, completely bypassing the need to manually install nuts, configure workspaces, or manage deployments on the target machine.
Basic Usage
To run an application remotely, use the exec command with the --target flag specifying the SSH connection string:
nuts exec --target=ssh://user@host myapp
How It Works Under the Hood
When you trigger a remote execution, nuts orchestrates a complex deployment sequence entirely automatically:
1. Local Bundling: It analyzes the requested application and its dependencies, creating an air-gapped bundle on your local machine.
2. Secure Transfer: It securely SCPs the self-contained bundle to a temporary location on the remote host.
3. Self-Installation: It bootstraps a temporary, isolated nuts workspace on the remote host using the transferred bundle (no internet connection required on the remote server).
4. Execution: It launches the application within the remote environment.
5. Stream Redirection: It connects the remote standard output, standard error, and standard input streams directly back to your local terminal, making it feel like a local execution.
Prerequisites
To utilize remote execution, ensure the following conditions are met:
SSH Key-based Authentication: You must have SSH access to the remote host configured with key-based authentication. Password prompts during the automated transfer phase are not supported.
Remote Java: The remote host must have a compatible Java Runtime Environment installed and available on the system PATH. Alternatively, you can use a bundle that includes a JRE (though this significantly increases transfer times).
Passing Arguments
You can pass arguments to the remote application exactly as you would locally. Everything following the application name is securely forwarded:
nuts exec --target=ssh://user@host myapp --config prod.json --verbose
Security Considerations
Remote execution is designed with security in mind:
No Additional Daemons: It uses your existing SSH daemon (sshd). No custom nuts ports or agents need to be exposed.
Native Authentication: It inherits your standard SSH authentication, respecting authorized keys, jump hosts, and network policies.
Ephemeral Footprint: Temporary files and workspaces generated during execution can be configured to be ephemeral, leaving no trace after the process terminates.
Troubleshooting
If remote execution fails, check the following common issues:
SSH Connectivity: Verify you can manually connect to the server without a password using
ssh user@host.Missing Remote Java: Ensure Java is installed remotely. Run
ssh user@host java -versionto verify.Path Issues: If Java is installed but not on the default path, you may need to update the remote
.bashrcor specify the Java path explicitly.Transfer Timeouts: For very large applications on slow connections, the SCP phase might time out. Consider pre-bundling or installing nuts natively on the remote host for heavy workloads.
3.4 Using Docker
Running nuts in a containerized environment
If you want to run nuts in a containerized Docker environment without creating a dedicated Dockerfile, you can bootstrap it directly within a standard OpenJDK container.
On your bash terminal, run:
docker run -it --rm eclipse-temurin:21-jre bash -c "$(curl -sSL https://thevpc.net/nuts/bootstrap-container-latest.sh)"
Once inside the container, you can use nuts normally, such as installing and running applications with the auto-confirm flag (-y):
nuts -y <your-app>...
For example, you can run net.thevpc.nuts.toolbox:noapi to process a configuration file named myrest-apis.json. noapi is an OpenAPI documentation tool that generates a PDF file based on an API definition in JSON, YAML, or TSON formats.
nuts -Zy net.thevpc.nuts.toolbox:noapi myrest-apis.json
Creating your app Dockerfile
If you are deploying your application in an isolated Docker environment, you can build a custom image. Here is a basic example Dockerfile that bootstraps nuts and installs your app:
FROM eclipse-temurin:21-jre
RUN curl -sSL https://thevpc.net/nuts/bootstrap-container-latest.sh | bash
RUN nuts -Zy install <your application>
CMD nuts -y <your application>
Alternatively, here is a more explicit approach that downloads the nuts JAR directly. This example packages the noapi OpenAPI tool:
FROM eclipse-temurin:21-jre
RUN wget https://maven.thevpc.net/net/thevpc/nuts/nuts-app/1.0.0/nuts-app-1.0.0.jar -qO nuts.jar
RUN java -jar nuts.jar -Zy install net.thevpc.nuts.toolbox:noapi
CMD java -jar nuts.jar -y net.thevpc.nuts.toolbox:noapi
Multi-stage Docker Build
For production deployments, it is best practice to use a multi-stage Docker build. This approach allows you to use a full JDK for dependency resolution and packaging, while creating a minimal JRE-based image for the final runtime, resulting in significantly smaller container sizes:
# Stage 1: Build and Resolve
FROM eclipse-temurin:21-jdk AS builder
RUN wget https://maven.thevpc.net/net/thevpc/nuts/nuts-app/1.0.0/nuts-app-1.0.0.jar -qO nuts.jar
# Install and resolve all dependencies in the builder stage
RUN java -jar nuts.jar -Zy install com.mycompany:my-server
# Stage 2: Production Runtime
FROM eclipse-temurin:21-jre
COPY --from=builder /root/.nuts /root/.nuts
COPY --from=builder /nuts.jar /nuts.jar
CMD java -jar nuts.jar -y com.mycompany:my-server
Using Docker Compose
You can easily manage nuts-powered applications as services using Docker Compose. Here is an example docker-compose.yml for running a web service:
version: '3.8'
services:
my-nuts-service:
build: .
ports:
- "8080:8080"
volumes:
- nuts-workspace:/root/.nuts
environment:
- NUTS_PROFILE=production
volumes:
nuts-workspace:
Volume Mounts and Persistence
By default, nuts stores its workspace (including downloaded artifacts, caches, and configuration) in the user's home directory (e.g., /root/.nuts). When running in Docker, this data is lost when the container stops unless you use volume mounts.
To persist the workspace and avoid re-downloading dependencies on every container restart, mount a volume to the workspace location:
docker run -it --rm -v nuts-data:/root/.nuts my-nuts-image
Best Practices
Layer Caching: Place your
RUN nuts -Zy install ...command high up in your Dockerfile so Docker can cache the downloaded dependencies layer, speeding up subsequent builds.Workspace Pre-warming: Always run the install command during the Docker build phase. This pre-warms the workspace, ensuring the container starts instantly without needing to fetch artifacts at runtime.
Base Images: Prefer official JRE images (like
eclipse-temurin:21-jre) over JDK images for the final runtime to minimize security surface area and image size.
3.5 CI/CD Integration
Overview
Integrating nuts into Continuous Integration and Continuous Deployment (CI/CD) pipelines allows you to reliably manage build tools, run test suites, and deploy applications across various environments. Because nuts ensures deterministic dependency resolution and workspace isolation, it is an ideal fit for automated workflows.
Key Flags for CI/CD
When running nuts in non-interactive pipeline environments, certain flags are essential to ensure commands complete successfully without waiting for user input:
--bot: Enables bot mode. This disables all interactive prompts, progress bars, and ANSI color codes, ensuring logs are clean and machine-readable.
--yes or -y: Automatically confirms all prompts with a affirmative response. Essential for unattended installations and updates.
--json: Outputs command results in structured JSON format, making it easy to parse data using tools like jq in your pipeline scripts.
CI/CD Platform Examples
GitHub Actions
Here is a complete GitHub Actions workflow that sets up a Java environment, initializes a nuts workspace, caches it for performance, and executes a tool:
name: Nuts CI Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Nuts Workspace
uses: actions/cache@v4
with:
path: ~/.nuts
key: $-nuts-$4400442f1173272fd6799bc3c508ab071aca486dfd27b58b28736db448a525ed
restore-keys: |
$-nuts-
- name: Install and Run Tool
run: |
curl -sSL https://thevpc.net/nuts/bootstrap-container-latest.sh | bash
nuts --bot --yes install my.group:my-tool
nuts --bot --yes my-tool --test
GitLab CI
For GitLab CI, you can leverage a base image and caching definitions in your .gitlab-ci.yml:
image: eclipse-temurin:21-jdk
variables:
NUTS_WORKSPACE: "$CI_PROJECT_DIR/.nuts-workspace"
cache:
paths:
- .nuts-workspace/
before_script:
- curl -sSL https://thevpc.net/nuts/bootstrap-container-latest.sh | bash
- export PATH="$PATH:$HOME/.local/share/nuts/apps/bin"
test_job:
stage: test
script:
- nuts --bot -y -w $NUTS_WORKSPACE install my.group:my-tool
- nuts --bot -y -w $NUTS_WORKSPACE exec my.group:my-tool --validate
Jenkins
In a Jenkinsfile, you can run nuts inside a shell step, ensuring you pass the necessary non-interactive flags:
pipeline {
agent { docker { image 'eclipse-temurin:21-jdk' } }
stages {
stage('Initialize Nuts') {
steps {
sh 'curl -sSL https://thevpc.net/nuts/bootstrap-container-latest.sh | bash'
}
}
stage('Execute Tool') {
steps {
sh 'nuts --bot -y install my.group:my-tool'
sh 'nuts --bot -y my-tool --report=target/report.xml'
}
}
}
}
Caching Strategies
To speed up CI/CD execution times, you should heavily cache the nuts workspace directory. By default, this is located at ~/.nuts (or the equivalent XDG data directories on Linux). Caching this directory prevents your pipeline from re-downloading Java artifacts and bootstrap engines on every commit.
Ephemeral Workspaces
If you require strict isolation between jobs running on the same persistent runner, you can instruct nuts to use a temporary, isolated workspace using the -w (workspace) flag:
nuts -w /tmp/workspace-$BUILD_ID --bot -y my-tool
This guarantees that the execution starts from a clean slate, unaffected by previous pipeline runs, while still benefiting from any globally configured repositories.
Structured Output for Parsing
When writing bash scripts for your pipelines, parsing raw text output is fragile. Instead, use the --json flag to retrieve structured data and process it with jq:
# Check if an artifact is installed
IS_INSTALLED=$(nuts search --installed my.group:my-tool --json | jq 'length > 0')
if [ "$IS_INSTALLED" = "true" ]; then
echo "Tool is ready!"
fi
Artifact Verification
CI/CD pipelines are excellent places to enforce security and integrity checks. You can use nuts to verify deployed artifacts or check for configuration drift before executing critical deployment scripts:
# Display detailed information about the resolved artifact before execution
nuts info my.group:my-tool --json
3.6 Troubleshooting
Whenever an installation fails, it is highly likely there is a misconfiguration, a network interruption, or invalid library bundles were used. nuts provides robust mechanisms to circumvent these issues, ranging from targeted diagnostics to various levels of workspace reinitialization.
Common Error Messages
If you encounter issues during execution, check these common scenarios:
"Artifact not found"
Cause: The artifact ID is incorrect, or the required repository is not configured.
Solution: Verify the
groupId:artifactId#versionsyntax. Check your configured repositories usingnuts settings list reposto ensure the source repository is available.
"Java version incompatible"
Cause: The application requires a different JDK version than the one currently active.
Solution: You can instruct nuts to auto-provision the correct version by using
nuts exec --java-version=<required-version> <app>. Alternatively, manually provision it withnuts settings add java --download --jdk --version=<version>.
"Permission denied"
Cause: The active user lacks write access to the workspace directories.
Solution: Verify ownership of the workspace directory (usually
~/.nutsor XDG equivalents). Never mix sudo and standard user execution within the same workspace, as this causes file ownership conflicts.
"Repository unreachable"
Cause: Network connectivity issues, corporate firewalls, or proxy misconfigurations.
Solution: Check your internet connection. If you are behind a corporate proxy, configure the HTTP proxy settings in your environment variables or directly within the nuts configuration.
Diagnostic Commands
Before attempting to reset your workspace, use these commands to gather diagnostic information:
nuts info— Displays deep metadata about the active workspace environment.nuts version— Shows version information for the bootstrap, runtime, and Java environment.nuts settings list repos— Lists all configured repositories and their status.nuts search --installed— Lists all artifacts currently installed in the workspace.
Workspace Recovery Modes
If diagnostic commands do not resolve the issue, you can use the built-in recovery and reset modes to repair the workspace.
Recover Mode
Recover mode applies best efforts to correct configurations without losing them. It deletes all cached data and downloaded libraries, forcing them to be re-downloaded, and searches for valid nuts installation binaries to run (acting as a forced update).
To run nuts in recover mode, type:
nuts -z
Newer Mode
Newer mode applies best efforts to reload cached files and libraries from disk, useful if the cache has fallen out of sync.
To run nuts in newer mode, type:
nuts -N
Reset Mode
Reset mode applies all efforts to correct configuration by actually deleting it (and all workspace files) to create a fresh workspace. This is a radical action. Do not invoke this unless you understand the consequences.
To run nuts in reset mode, type:
nuts -Z
Hard-Reset Mode
Hard-reset mode deletes all nuts configuration files across all workspaces on the system. This is an extreme action. Do not invoke this unless you understand the consequences.
To run nuts in hard-reset mode, type:
nuts --hard-reset
Kill Mode
Kill mode is a special variant of reset mode where the workspace will not be recreated after deletion. This effectively uninstalls the workspace. It is achieved by combining reset mode with the --skip-boot (-Q) option.
To run nuts in kill mode, type:
nuts -ZQ
You can run hard-reset in kill mode too, which removes nuts entirely from the system:
nuts --hard-reset
Recovery Mode Summary
| Mode | Flag | What it does | When to use |
|---|---|---|---|
| Recover | -z | Deletes corrupted cache, forces dependency re-download | App won't start, suspect bad download |
| Newer | -N | Reloads cached files from disk | Cache out of sync with disk |
| Reset | -Z or --reset | Deletes workspace config and apps, keeps global settings | Workspace is broken beyond repair |
| Hard Reset | --hard-reset | Deletes ALL workspaces and global config | Complete uninstall/reinstall |
| Kill | -ZQ | Deletes workspace, does not recreate it | Removing Nuts entirely |
After Invoking Reset Mode
After invoking a reset mode (-Z or --hard-reset), the nuts shell launchers (installed by nuts settings) will not be available anymore. The PATH environment variable will temporarily point to a non-existing folder.
You must use the JAR-based invocation at least once to reinstall these commands and restore your environment:
java -jar nuts.jar
4 Concepts & Architecture
Deep dives into the core concepts and design philosophy behind nuts. Learn how the package manager works under the hood and why certain architectural decisions were made.
4.1 Architecture & Design
Architecture & Design
nuts (Network Updatable Things Services) is built on a modular, secure, and extensible architecture. Its primary goal is to shift dependency resolution from build-time to runtime, enabling highly efficient, multi-version package management for the Java ecosystem.
Design Constraints
The design of nuts is driven by three core constraints:
1. Zero External Dependencies
The nuts bootstrap JAR is designed to be completely self-contained. At approximately 500KB, it includes its own minimal CLI parser, expression engine, text formatter, and secure network client. No external libraries or tools (not even Maven or curl) are required to start the engine, download dependencies, and boot the runtime. This zero-dependency footprint guarantees a pristine installation and bootstrapping process across any environment.
2. Maven-Native Package Format
nuts does not invent a new packaging format. Every existing Maven artifact with a valid pom.xml descriptor is automatically a valid nuts package. The system uses standard Maven coordinates (groupId:artifactId#version) for artifact resolution. By directly consuming Maven Central and private repositories, nuts instantly taps into the world's largest ecosystem of Java libraries and applications.
3. Cross-Platform Consistency
nuts guarantees identical behavior and feature sets across Linux, macOS, and Windows. This includes consistent CLI semantics, XDG-compliant file system layouts, shell integration, and OS-level desktop launchers. The goal is to provide a reliable, predictable developer and deployment experience, eliminating platform-specific edge cases in installation scripts or CI/CD pipelines.
Three-Tier Architecture
To achieve extreme modularity and version flexibility, nuts is structured into three distinct tiers — each independently versioned and resolvable at runtime:
┌─────────────────────────────────────────────┐
│ Applications & Companion Tools │
│ (CLI tools, Desktop apps, nsh, nmvn) │
├─────────────────────────────────────────────┤
│ nuts-runtime (Engine) │
│ ~3MB · POM Solver · Repo Manager · NTF │
├─────────────────────────────────────────────┤
│ nuts-api (Contract Layer) │
│ Interfaces · SPIs · Data Model │
├─────────────────────────────────────────────┤
│ nuts-boot (Bootstrap Layer) │
│ ~500KB · CLI Parser · Version Resolver · Boot │
└─────────────────────────────────────────────┘
1. nuts-boot (Bootstrap Layer): The entry point — the JAR you download and run with
java -jar nuts.jar. It contains a minimal CLI parser, Maven repository client, and version resolver. Its sole job is to locate the best nuts-api version, then find the best nuts-runtime compatible with that API. It has zero dependencies and can bootstrap the entire system from scratch.2. nuts-api (Contract Layer): Defines the public interfaces, SPIs, and data model that all nuts components program against. Applications and companion tools depend only on this layer. By keeping the API separate, the runtime implementation can evolve independently without breaking applications.
3. nuts-runtime (Engine): The full implementation of all SPIs defined in nuts-api. It provides the Maven POM dependency solver, repository manager, security enforcement, process execution engine, and advanced terminal formatting (NTF). This tier is loaded dynamically by nuts-boot — it is never bundled statically.
4. Applications: The top layer consisting of companion tools (like nsh, nmvn) and user applications installed via nuts. They consume the nuts-api interfaces to interact with the workspace.
Bootstrap Process
The bootstrap sequence, implemented in NBootWorkspaceImpl, is the critical path that turns a single JAR into a fully operational package manager. When you run java -jar nuts.jar or use a native launcher:
Step 1 — Parse & Configure
The boot JAR parses command-line arguments, reads inherited system env (NUTS_BOOT_ARGS) and propertu (nuts.args), detects the current OS, architecture, and shell environment, and resolves the workspace location (default, named, or path-based).
Step 2 — Resolve the Best API Version
The boot JAR determines which nuts-api version to load. "Best" here means the latest available version, determined by comparing version numbers from the Maven maven-metadata.xml across all configured repositories:
- If a specific version is pinned (via workspace config or CLI), that exact version is used.
If the version is set to LATEST or RELEASE, the boot JAR queries all boot repositories, parses their
maven-metadata.xmlfiles, and selects the highest version number found.If no version is specified at all (blank), the boot JAR falls back to its own embedded version — NUTS_BOOT_VERSION — which is the API version it was compiled against.
If the session is inherited (embedded mode), the boot JAR always uses its own NUTS_BOOT_VERSION to avoid version conflicts within the same JVM.
This means the boot JAR can bootstrap a different (newer or older) API version than the one it was built with — the boot layer and the API layer are independently versioned.
Step 3 — Resolve the Best Runtime
With the API version determined (say 0.8.4), the boot JAR searches for the
best compatible nuts-runtime
. The compatibility rule is a version prefix match: only runtime versions that start with the API version followed by a dot are considered. For example, if the API is0.8.4, the runtime must be 0.8.4.x (e.g., 0.8.4.0, 0.8.4.1, 0.8.4.5). Among all matching versions, the highest version number wins.The resolution follows a local-first strategy:
1. Local workspace lib cache — checked first for fast startup without network access.
2. Remote repositories (Maven Central, configured repos) — queried only if no valid local version is found (or if the fetch strategy is ANYWHERE).
3. Fallback cache — if both local and remote fail, the boot JAR scans the workspace's lib directory for any previously downloaded runtime JAR with a matching version prefix.
Once the runtime artifact is identified, its dependency tree is resolved from the .nuts descriptor (a lightweight JSON format) or the standard Maven pom.xml.
Step 4 — Build the Classworld
The bootstrapper downloads any missing JARs (the runtime and its transitive dependencies) and constructs an isolated NBootClassLoader — a custom classloader hierarchy that keeps the runtime's classpath fully isolated from the boot layer and from the application's own dependencies.
Step 5 — Discover the Workspace Factory
Using Java's ServiceLoader mechanism on the newly constructed classloader, nuts-boot discovers implementations of the NBootWorkspaceFactory SPI. The factories are sorted by priority, and the best one is used to create the workspace instance.
Step 6 — Handoff
The workspace factory creates a NWorkspaceBase instance, which takes full control. From this point on, nuts-boot is no longer involved — the runtime handles all CLI commands, dependency resolution, installation, execution, and configuration.
Recovery & Resilience
If the loaded runtime binaries are incompatible (e.g., due to a corrupted cache or a version mismatch causing IncompatibleClassChangeError), the bootstrap automatically detects this, expires the cache, and retries the entire resolution from Step 2 with fresh downloads — without requiring user intervention.
For the full step-by-step sequence, classloader hierarchy, and recovery mechanisms, see Appendix: Bootstrap Deep Dive.
Self-Hosting and Updating
nuts uses its own package management engine to manage itself. Because nuts-boot dynamically resolves both the API and runtime versions, the update process is elegant:
nuts update
This resolves newer versions of the API and runtime, downloads them, updates the workspace configuration, and on the next launch, nuts-boot will load the new versions automatically. The boot JAR itself rarely needs updating — it delegates all real work to the runtime it resolves.
Extension Model
nuts provides a powerful Service Provider Interface (SPI) extension model. Developers can seamlessly inject custom capabilities into the runtime without modifying the core system. Extensions can provide:
Custom Repositories: Integration with specialized artifact stores (e.g., S3, Git, internal HTTP endpoints).
Custom Executors: Support for executing non-Java artifacts (e.g., Python scripts, native binaries, shell scripts).
Custom Descriptors: Parsers for metadata formats other than standard
pom.xml.
Extensions are discovered via ServiceLoader and loaded into the workspace's classloader, maintaining full isolation from other extensions and the core runtime.
Isolation Levels
nuts supports multiple isolation levels for different use cases:
| Level | Behavior |
|---|---|
System (default) | Standard workspace, full persistence, shared config |
User | Per-user isolation |
Confined | Restricted operations |
Sandbox | Temporary workspace in a temp directory, standalone strategy forced, deleted on exit |
Memory | In-memory workspace, no disk persistence |
Sandbox and Memory modes are particularly useful for CI/CD pipelines and automated testing where no state should persist between runs.
Nuts Text Format (NTF)
To ensure high-quality CLI output, nuts includes its own terminal rendering engine known as the Nuts Text Format (NTF). NTF provides a robust, cross-platform markup language for:
- ANSI colorization and syntax highlighting.
- Responsive table drawing with ASCII and Unicode borders.
- Tree structures for dependency graphs.
- Structured output rendering tailored to terminal widths.
NTF gracefully falls back to plain text if a non-interactive console is detected, ensuring logs and piped data remain clean and parseable.
4.2 Nuts and Maven
nuts is not a build tool. It is a runtime package manager that consumes Maven artifacts. It serves the role that npm or pip play in the JavaScript and Python ecosystems, but tailored specifically for Java.
| Feature | Nuts | Maven | SDKMAN | jbang | Homebrew |
|---|---|---|---|---|---|
| Installs apps | ✅ | ❌ | ⚠️ (JDKs only) | ⚠️ (scripts) | ✅ |
| Uses Maven metadata | ✅ | ✅ | ❌ | ✅ | ❌ |
| Side-by-side versions | ✅ | ❌ | ✅ | ❌ | ❌ |
| Zero dependencies | ✅ | ❌ | ❌ | ❌ | ❌ |
| Cross-platform | ✅ | ✅ | ⚠️ | ✅ | ❌ (macOS/Linux only) |
| JDK provisioning | ✅ | ❌ | ✅ | ❌ | ❌ |
| Fat JAR overhead | ❌ (Shared libs) | ✅ (Fat JARs) | N/A | ❌ | N/A |
| Dependency deduplication | ✅ (System-wide) | ❌ | N/A | N/A | N/A |
Build Time vs Runtime
Maven is designed for the build phase. When building an application for distribution without a package manager, developers typically resort to creating "Fat JARs" (or Uber JARs) — a single massive archive containing the application code and every single dependency. This results in bloated binaries, slow downloads, and wasted disk space when multiple applications share the same libraries.
nuts resolves dependencies at runtime or install time. When you distribute an application with nuts, you only publish the thin application JAR (often just a few kilobytes). When the user installs or runs the application, nuts reads the pom.xml, computes the dependency tree, and downloads the required libraries into a shared local cache. If ten different applications depend on commons-lang3, the library is downloaded and stored only once.
Complementary Tools
Maven and Nuts are not competitors; they are highly complementary tools that form a complete CI/CD pipeline:
1. Build Phase (Maven/Gradle): Developers use Maven or Gradle to compile source code, run unit tests, and package the thin artifact.
2. Publish Phase (Maven/Gradle): The thin artifact and its
pom.xmlare deployed to Maven Central or a private repository (e.g., Nexus, Artifactory).3. Distribution Phase (Nuts): On the target system (servers, developer machines, CI agents), users execute
nuts install my.group:my-appto resolve, download, and launch the application.
When to Use What
Use Maven or Gradle when you are writing code, compiling Java files, running tests, or generating documentation. They are build lifecycle managers.
Use Nuts when you want to install an application, run a command-line tool, manage multiple versions of a Java application side-by-side, or automate deployment scripts on target servers.
Technical Relationship
nuts natively understands Maven repositories and the pom.xml descriptor format. It communicates directly with Maven Central to resolve coordinates, parse dependency scopes, and handle version conflict resolution.
Importantly, nuts does NOT require Maven to be installed on the system. The nuts runtime contains its own highly optimized, lightweight POM solver and repository client.
4.3 Workspace
Workspace
A fundamental concept in nuts is the Workspace. A workspace is a self-contained, isolated environment that manages repositories, installed applications, downloaded libraries, configurations, and security settings.
If you are familiar with Python's virtualenv or Node's node_modules, a nuts workspace provides a similar, but more comprehensive, level of isolation for the Java ecosystem.
What is a Workspace?
A workspace acts as the root boundary for execution. When you run a command via nuts, the runtime operates exclusively within the context of the active workspace. It dictates:
- Which repositories are queried for packages.
- Which versions of Java (JDKs/JREs) are available or auto-provisioned.
- Where downloaded JARs and artifacts are stored.
- What configurations and aliases are available.
- What security permissions and authentication rules apply.
By default, nuts operates in the default-workspace, providing a seamless "just works" experience without needing upfront configuration.
Workspace Anatomy
Internally, a workspace consists of several distinct logical areas, heavily inspired by the XDG Base Directory Specification:
Config: Stores workspace settings, secure credentials, aliases, and custom repositories.
Bin: Holds installed application binaries, boot scripts, and launchers.
Lib: The central repository cache for downloaded dependencies (JARs, POMs).
Var: Application-specific persistent data.
Log: Centralized logging for the package manager and managed applications.
Cache: Ephemeral storage for optimized downloads and index caches.
Run: Runtime files, sockets, and named pipes (often cleared on reboot)
Storage Strategies
nuts allows you to configure how a workspace's internal anatomy maps to the host operating system's file system. It offers two primary strategies:
Exploded Strategy (Default)
In the Exploded strategy, nuts scatters the workspace directories across the host OS using standard conventions (XDG on Linux/macOS, AppData on Windows).
Configuration goes to
~/.config/nuts/...Cache goes to
~/.cache/nuts/...Logs go to
~/.local/log/nuts/...
Why use it? It integrates perfectly with OS backup tools, allows cache directories to be placed on faster ephemeral storage, and respects native platform conventions.
Standalone Strategy
In the Standalone strategy, the entire workspace is confined to a single directory tree. Everything (config, cache, apps, logs) is stored directly under one root folder.
Why use it? It is ideal for portability. You can create a Standalone workspace on a USB drive, within a Docker volume, or in a roaming profile. Deleting or moving the workspace is as simple as deleting or moving the root folder.
Workspace Lifecycle
1. Creation: A workspace is initialized either automatically on first use or explicitly via
nuts -w <name> workspace init.2. Configuration: Repositories are added, Java environments are scanned or provisioned, and security settings are established.
3. Usage: Applications are installed, updated, and executed within the boundary.
4. Maintenance/Reset: A workspace can be completely wiped clean without affecting other workspaces or the host OS.
Isolation Guarantees
Workspaces provide strict isolation guarantees.
No Cross-Contamination: Installing an artifact in Workspace A has absolutely no effect on Workspace B. They maintain separate caches, configurations, and runtime classpaths.
Environment Targeting: You can configure a dev workspace pointing to snapshot repositories, and a prod workspace locked to stable internal repositories.
Safe Experimentation: If an application installation breaks or corrupts a workspace, you can simply delete the workspace without risking system stability.
System-Wide vs Per-User
By default, workspaces are per-user, isolated within the user's home directory. This allows standard users to install and manage software without requiring sudo or Administrator privileges.
For server environments or system-wide software distribution, nuts can run in system-mode using the -g flag. This initializes a system-wide workspace (e.g., in /etc/nuts and /var/lib/nuts), allowing all users on the OS to access the installed tools.
Named and Temporary Workspaces
You can easily switch between workspaces using the -w or --workspace flag:
# Execute in a specific named workspace
nuts -w testing-env install my-app
# Create and use a temporary, ephemeral workspace
nuts -w temp-$$ run my-experimental-app
Temporary workspaces are incredibly powerful in CI/CD pipelines, ensuring every pipeline run executes in a pristine, guaranteed-clean environment, avoiding tricky cache-poisoning issues.
4.4 Command Line Arguments
nuts employs a robust and highly structured command-line argument parser. This format is standardized across the nuts Application Framework (NAF), meaning all NAF-built applications share the same predictable argument syntax.
In nuts, arguments are broadly categorized as either Options (prefixed with hyphens) or Non-options (arguments like application names or paths).
Quick Reference
| Prefix | Type | Example | Description |
|---|---|---|---|
- | Short Option | -w, -y | Single character flags |
-- | Long Option | --workspace, --bot | Verbose flags for scripts |
--- | Custom Option | ---perf | Internal or experimental flags |
-X / -D | Executor | -Xmx2G, | Passed directly to the JVM |
| Comment | | Ignored by the parser |
Short vs Long Options
Options can be long (starting with a double hyphen --) or short (starting with a single hyphen -). Many arguments support both forms for convenience. For instance, -w and --workspace are equivalent ways to specify the workspace location.
Valued / Non-valued Options
Options can accept values (strings, integers, etc.). The value can be supplied immediately after the option separated by a space, or joined using an = sign.
All of the following are equivalent:
nuts -w=/opt/workspace
nuts -w /opt/workspace
nuts --workspace /opt/workspace
nuts --workspace=/opt/workspace
Boolean Options
Boolean options are special. If provided without a value, they are implicitly evaluated as true. Therefore, --bot and --bot=true are functionally identical.
However, notice that --bot true is not equivalent. Because the option expects a boolean binding, passing true as a separated token will result in the parser treating true as a separate non-option argument.
To explicitly pass false to a boolean option, you can suffix it with =false or use a logical NOT prefix (! or ~). The ~ symbol is provided as a safe alternative to ! because some shells (like Bash) intercept ! for history expansion.
The following are equivalent ways to disable an option:
nuts --bot=false
nuts --!bot
nuts --~bot
Combo Simple Options
Short options can be clustered together in a single block. For example, -ls is parsed identically to -l -s.
Note: For standard portability, -version is treated as a single special short option, not a combination of -v -e -r...
Ignoring Options / Comments
Sometimes you need to temporarily disable an option in a script or pass explanatory text. Any option starting with -// or --// is treated as a comment and is completely ignored by the parser.
Nuts Option Types
Options processed by the core nuts engine fall into specific behavioral categories.
Create Options
These options define configuration when a workspace is newly initialized. If the workspace already exists, these options are ignored.
| Option | Example | Description |
|---|---|---|
--archetype | | Sets the initial workspace template (default, minimal, server) |
--store-strategy | | Defines the file system layout (exploded, standalone) |
--install-companions | --install-companions | Installs tools like nmvn and nsh |
--java-home | | Specifies the Java installation path to run the workspace |
--solver | | Configures dependency solver (maven, gradle, descriptor, maven-first, gradle-first) |
Isolation Levels
Isolation options define the workspace boundary and disk persistence behavior.
| Option | Example | Description |
|---|---|---|
--sandbox | --sandbox | Runs in a temporary location with a fresh instance each time. No disk persistence on exit. |
--in-memory | --in-memory | Runs the workspace entirely in memory without creating any disk configuration. Only temporary downloads folder used. |
--confined | --confined | Runs in a specific location as regular user without modifying global shortcuts, |
--isolation-level | | Explicitly sets workspace isolation level (system, user, confined, sandbox, memory) |
Open Modes
Open mode flags control workspace creation vs opening behavior.
| Option | Example | Description |
|---|---|---|
--open-or-create | --open-or-create | Default mode: opens existing workspace or creates a new one if missing |
--open | --open | Opens existing workspace; throws an error if workspace does not exist |
--create | --create | Creates a new workspace; throws an error if workspace already exists |
--open-or-null | --open-or-null | Opens existing workspace; exits quietly without error if workspace does not exist |
Runtime & Execution Options
These control the execution environment of the current command.
| Option | Example | Description |
|---|---|---|
--reset / -Z | | Clears cache and re-bootstraps workspace before running |
--reset-hard | | Wipes all workspace directories and configuration files |
--reset-options | | Resets all previously supplied option flags to default values |
--recover / -z | | Recovers corrupted workspace by ignoring cache and re-resolving |
--read-only / -R | | Runs workspace in read-only mode; changes are not saved to disk |
--offline / -F | | Disables remote repository access during execution |
--dry / -D | | Simulates the command without performing side effects |
--stacktrace / -d | | Prints full Java stacktrace on errors |
--debug | | Enables JDWP debugging for current process and spawned child processes |
Exported Options
These options affect both the current process and any sub-processes spawned by nuts (such as running nsh or an application).
| Option | Example | Description |
|---|---|---|
--workspace / -w | | Targets a specific workspace location or name |
--bot / -B | --bot | Enables non-interactive automation mode with structured output |
--color / -c | | Forces colored output down the process tree |
--global / -g | --global | Runs in global system-wide context ( |
Executor Options
These are intercepted and passed directly to the underlying package executor (usually the Java Virtual Machine).
| Option | Example | Description |
|---|---|---|
| -Xmx1G | Sets JVM memory limits |
| | Sets JVM system properties |
Custom / Internal Options
Special options used for internal profiling, debugging, or experimental features. They begin with a triple hyphen (---). The parser will never throw an error for these; if they are unrecognized, they are safely ignored.
| Option | Example | Description |
|---|---|---|
---perf | | Outputs execution performance metrics |
---show-command | | Prints the exact JVM command used to launch the app |
---init-java | | Initializes Java environment bindings |
| | Enables internal telemetry |
Application Options
Standard options processed by the application built on the framework.
| Option | Example | Description |
|---|---|---|
--help | | Displays command usage and reference |
--version | | Outputs application version information |
All nuts options are thoroughly described in the built-in command help. Just type:
nuts --help
4.5 Security Model
Security Model
nuts incorporates a robust security framework designed to safely execute third-party applications, manage credentials, and control access to environments in both single-user systems and shared enterprise architectures.
Default Mode (Unsecured)
Out of the box, nuts operates in an unsecured mode. It runs with the privileges of the underlying OS user and does not enforce internal authentication. This provides a frictionless developer experience, structurally identical to running standard package managers like pip, npm, or brew.
In this mode, any local user with filesystem access to the workspace can install packages, modify settings, or execute applications.
Enabling Secure Mode
For production environments, CI/CD agents, or multi-tenant systems, you can activate the internal security manager:
nuts settings secure true
Once secure mode is enabled, nuts enforces strict internal access controls. The system transitions to require:
Authentication: Users must log in via a local credential database or external provider.
Authorization: Actions require specific, granular permissions.
Auditability: Critical actions are logged for compliance.
Permission Model
The authorization system is built on granular permissions. When secure mode is active, executing a command or altering configuration requires the active session to hold the relevant permission node.
| Permission | Description |
|---|---|
admin | Grants full administrative access to all workspace operations. |
install | Allows the user to install new artifacts into the workspace. |
uninstall | Allows the user to remove installed artifacts. |
deploy | Allows pushing artifacts to local or remote repositories. |
update | Permits updating existing packages to newer versions. |
settings | Grants access to modify workspace configuration (repos, security, paths). |
execute | Allows running installed applications. |
User Management
nuts maintains an internal user directory within the workspace to handle authentication and permission mapping.
# Create a new user
nuts settings add user developer --password=secret
# Grant install and execute permissions to the user
nuts settings add permission developer install
nuts settings add permission developer execute
# Remove a user
nuts settings remove user developer
Workspaces as Security Boundaries
It is critical to understand that security settings are scoped to the workspace. A user with admin privileges in workspace-dev has zero implied privileges in workspace-prod.
This strict boundary allows operators to create high-security, locked-down workspaces for production workloads while simultaneously allowing open, unauthenticated workspaces for local development on the same host machine.
Audit Logging
When operating in secure environments, visibility is paramount. nuts maintains comprehensive audit logs for lifecycle events.
Audit logs track:
Who: The authenticated identity making the request.
What: The command and arguments executed.
When: High-precision timestamp.
Result: Success, failure, or security denial.
These logs are safely stored in the workspace's designated log location and are formatted in parseable JSON or plain text for easy ingestion by centralized logging systems like ELK or Splunk.
System-Wide vs Per-User Isolation
Security is also enforced by the underlying OS file system.
Per-User (Default): Workspaces are located in the user's home directory (e.g.,
~/.config/nuts). The OS inherently prevents other local users from modifying or accessing these files.System-Wide (--global | -g)
: When nuts is executed with the -g flag (usually requiring OS-level sudo privileges), the workspace is initialized in protected system directories (/etc,/var/lib). The OS prevents non-root users from modifying the binaries, while nuts internal security governs execution rights.
Best Practices for Production
1. Always use Secure Mode in shared environments or production servers.
2. Apply the Principle of Least Privilege: Create a specific user account with only execute permissions for running daemonized applications.
3. Use Ephemeral Workspaces in CI/CD pipelines to guarantee clean, unpoisoned execution environments.
4. Isolate Credentials: Never hardcode API keys for private repositories in scripts; use the nuts secure credential vault.
4.6 Automation
nuts has been designed and implemented with automation, DevOps, and scripting in mind. It empowers users and platform engineers to automate application management, deployment workflows, and toolchains with a platform-independent, secure, and extensible architecture.
The nuts Application Framework provides seamless support for process automation through structured output, non-interactive execution modes, workspace isolation, and dependency-driven classloading.
You can invoke standard system commands and retrieve output directly in structured formats such as JSON, XML, YAML, or TSON. This enables powerful data manipulation using pipes, just as in POSIX shell environments — but enriched with structured data semantics.
Beyond command automation, nuts dynamically resolves and loads dependencies at runtime. For example, installing a specific Tomcat version compatible with your current JRE is as simple as one automated call — no manual download or configuration needed.
Install Automation
Installation commands in nuts are inherently scriptable and perfectly suited for CI/CD pipelines. You can install, update, or remove packages using declarative commands with predictable outputs.
Example:
nuts --bot --yes install tomcat --sudo
This command will automatically:
- Resolve the appropriate version of Tomcat for your current Java environment.
- Download and install the binary securely from configured repositories.
- Provision the appropriate JDK to run the tomcat version
Elevate privileges if required (--sudo) to register system-level services.
Using the --bot (non-interactive mode) and --yes (auto-confirm) flags guarantees that the process will never hang waiting for a user prompt, making it safe for headless automation.
Structured Output
Unlike traditional CLI tools that emit raw string data requiring fragile grep and awk parsing, every command in nuts can emit results in highly structured formats:
- --json
- --yaml
- --xml
--tson (Typed Superset of JSON)
--plain (default)
Example:
nuts --bot --json - ls . | jq '.[] | select(.size > 1024)'
This capability enables robust, failure-resistant pipelines by piping exact data models directly into JSON processors like jq, YAML processors like yq, or custom deployment scripts.
Environment Sensitive
nuts intelligently detects and adapts to the surrounding hardware and OS environment, including:
Architecture: x86_64, ARM, aarch64, Itanium.
Operating System: Linux, Windows, macOS, BSD.
Shell: Bash, Zsh, CMD, PowerShell.
Runtime Platforms: Java versions (8 through 24).
Desktop Environments: GNOME, KDE, Windows Shell.
This environmental awareness allows you to write a single portable automation script that behaves correctly whether it runs on an M-series Mac developer laptop, a Windows VM, or an ARM-based Linux container.
Multi Platform
Because nuts runs on the JVM, it executes consistently across virtually any platform:
- Linux, macOS, Windows, BSD, etc.
- CLI-compatible on both GUI and headless server systems.
Cross-platform consistency ensures that your automation logic avoids complex branching in your deployment scripts.
Workspace Isolation
Workspaces provide strictly isolated environments containing their own repositories, installed tools, and configurations.
This isolation is a superpower for automation. It ensures that different applications, teams, or pipeline stages (e.g., build vs integration testing) can coexist on the same CI agent without classpath contamination or version collisions.
nuts -w ci-pipeline-123 install my-build-tool
Security Mechanisms
nuts includes several mechanisms to ensure secure automation:
Permission model for restricting access to repositories, settings, and installations.
Execution contexts that support privilege separation (e.g., user vs system installs).
Sandboxing of downloaded tools and runtime dependencies.
Authentication and Authorization for protected resources (private registries, remote configs).
These features are especially valuable in enterprise, CI/CD, or public/shared environments.
Design Patterns for Automation
To maximize reliability in automated environments, adopt these standard nuts patterns:
1. Ephemeral Workspaces
In CI/CD environments, always generate a unique, temporary workspace for the job to avoid cache poisoning:
export NUTS_WORKSPACE="temp-$GITHUB_RUN_ID"
nuts -w $NUTS_WORKSPACE run my-test-suite
2. Version Pinning for Reproducibility
Avoid floating versions in scripts. Always specify exact coordinates to ensure builds are deterministic over time:
nuts --bot install org.company:server-app#2.4.1
3. Idempotent Executions
Use the --dry flag in pre-flight checks to safely evaluate what an installation command will do before it mutates the system state, allowing scripts to verify dependencies dynamically.
Pipeline Examples
GitHub Actions:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install toolchain via Nuts
run: |
nuts -w temp-$ --bot install my.group:toolchain#1.2.0
nuts -w temp-$ --bot run toolchain build
Bash Script Deployment:
#!/bin/bash
set -e
WORKSPACE="prod-env"
APP="com.company:web-service#3.1.2"
echo "Deploying $APP to workspace $WORKSPACE..."
nuts -w "$WORKSPACE" --bot --yes install "$APP"
nuts -w "$WORKSPACE" --bot run "$APP" start
4.7 File system
nuts is capable of managing multiple independent workspaces on a single machine. The default workspace is located at ~/.config/nuts (where ~ is the user's home directory).
Each workspace manages an internal database and strict directory layouts for configurations, applications, and logs. To ensure standard behavior across environments,
nuts
implements file system strategies heavily inspired by the XDG Base Directory Specification.
Store Locations
The nuts file system divides workspace data into specific functional categories, known as Store Locations:
| Store Location | Description |
|---|---|
config | Base directory for application-specific configuration files (XML, properties, YAML). |
apps | Base directory for executable application binaries and native wrappers. |
lib | Central cache for non-executable binaries (JARs, POMs, shared libraries). |
var | Persistent application data files (embedded databases, indices). |
log | Centralized directory for application and system trace/log files. |
temp | Ephemeral application-specific temporary files. |
cache | Download caches and non-essential binary data used to optimize network bandwidth. |
run | Runtime files, sockets, and named pipes (often cleared on reboot). |
Path Construction
Within these store locations, nuts structures files predictably using the artifact's Maven coordinates. Paths are constructed by expanding the groupId into directory segments, followed by the artifactId and version.
Format: <Store-Location>/id/<group-id-path>/<artifact-id>/<version>/
For example, the configuration folder for the artifact net.thevpc.app:netbeans-launcher#1.2.4 is constructed as:<Config-Store>/id/net/vpc/app/netbeans-launcher/1.2.4/
Platform Default Paths
nuts adapts its Store Locations automatically based on the host operating system conventions.
Linux, Unix, macOS, and POSIX
| Store | Default Path |
|---|---|
| config | |
| bin | |
| lib | |
| var | |
| log | |
| cache | |
| temp | |
| run | |
Windows
| Store | Default Path |
|---|---|
| bin | |
| lib | |
| config | |
| var | |
| log | |
| temp | |
| cache | |
| run | |
Visual Directory Tree
A standard Exploded workspace on a Linux machine roughly visualizes as:
~ (Home Directory)
├── .config/
│ └── nuts/
│ └── default-workspace/
│ └── config/id/net/vpc/app/... (Configurations)
├── .local/
│ ├── share/nuts/bin/ws/default-workspace/id/... (Binaries & Launchers)
│ ├── share/nuts/lib/ws/default-workspace/id/... (JARs and dependencies)
│ ├── share/nuts/var/ws/default-workspace/id/... (Application Data)
│ └── log/nuts/ws/default-workspace/id/... (Application Logs)
└── .cache/nuts/ws/default-workspace/
└──id/... (Downloads & Indexes)
└──repos/... (Repos Downloads & Indexes)
Store Location Strategies
When you initialize a workspace, you can define how these Store Locations are mapped to the file system using two strategies:
1. Exploded Strategy (Default)
In the Exploded strategy, nuts scatters the top-level folders across the host system according to XDG/AppData specifications (as shown above).
Advantage: This optimizes performance by aligning with OS expectations. For example, .cache can be excluded from cloud backups, and .local/share can reside on a high-speed SSD partition.
2. Standalone Strategy
In the Standalone strategy, the entire workspace is contained within a single root folder.
Advantage: Ideal for portability. You can create a roaming workspace on a USB thumb drive or easily mount it as a Docker volume.
Example path for a log file in a Standalone workspace:/home/me/.config/nuts/default-workspace/log/id/net/vpc/app/netbeans-launcher/1.2.4/app.log
Notice that the log folder resides inside the default-workspace directory, rather than being mapped to .local/log.
Custom Store Locations
You can override the default layouts to meet specialized infrastructure requirements.
Selecting Strategies:
# Create an exploded workspace (Default)
nuts -w my-workspace --exploded
# Create a standalone workspace
nuts -w my-workspace --standalone
Finer Customization:
You can individually remap specific stores. For instance, to keep an exploded workspace but map configurations to a dedicated mounted SSD:
nuts -w my-workspace --system-conf-home=/mnt/fast-ssd/configs
To see all available store customization arguments, consult the built-in help:
nuts help
4.8 Bootstrap Process & Architecture
Bootstrap Process & Architecture
At the core of nuts lies an intelligent, zero-dependency bootstrap mechanism implemented by nuts-boot (specifically orchestrated by NBootWorkspaceImpl). The bootstrap layer is responsible for turning a minimal executable JAR (~500KB) into a fully functional, modular runtime environment by resolving, caching, verifying, and launching the appropriate nuts-api and nuts-runtime components.
┌──────────────────────────────────────────────────────────────────┐
│ CLI / Launcher │
│ java -jar nuts.jar [options] [args] │
└─────────────────────────────────┬────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ nuts-boot (NBootWorkspace) │
│ ┌────────────────────────┐ ┌──────────────────────────┐ │
│ │ 1. Parse Args & Config │ ────► │ 2. Resolve Workspace │ │
│ └────────────────────────┘ └─────────────┬────────────┘ │
│ │ │
│ ┌────────────────────────┐ ┌─────────────▼────────────┐ │
│ │ 4. Resolve Runtime │ ◄──── │ 3. Resolve API Version │ │
│ └───────────┬────────────┘ └──────────────────────────┘ │
│ │ │
│ ┌───────────▼────────────┐ ┌──────────────────────────┐ │
│ │ 5. Build ClassLoader │ ────► │ 6. Factory SPI Discovery │ │
│ └────────────────────────┘ └─────────────┬────────────┘ │
└──────────────────────────────────────────────────┼───────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ nuts-runtime (NWorkspace) │
│ Full Package Management Engine │
└──────────────────────────────────────────────────────────────────┘
Core Design Principles
1. Zero External Dependencies: The bootstrap JAR embeds its own lightweight CLI argument tokenizer (NBootCmdLine), JSON parser (NBootJsonParser), Maven coordinate solver (NReservedMavenUtilsBoot), and repository communication layer. It requires only a standard Java Virtual Machine (Java 8+). 2. Three-Tier Modularity: nuts-boot, nuts-api, and nuts-runtime are strictly decoupled and independently versioned. The bootstrapper can dynamically load any compatible API/runtime version without modifying the bootstrap JAR itself. 3. Local-First Caching: Boot assets (the runtime JAR and its direct dependencies) are cached under the workspace's LIB store (<workspace-lib>/id/net/thevpc/nuts/nuts-runtime/<version>/). Startup is instantaneous once cached, requiring no network round-trips. 4. Self-Healing & Fallbacks: If binary incompatibilities (IncompatibleClassChangeError, LinkageError) or corrupted cache entries occur, the bootstrap layer automatically invalidates cache descriptors and retries resolution.
Nuts uses a three-tier bootstrap: nuts-boot (~500KB) resolves the best nuts-api and nuts-runtime versions from Maven repositories, constructs an isolated classloader, and hands off to the runtime. If cached binaries are corrupted, the bootstrap automatically invalidates the cache and retries.
For the full step-by-step sequence, classloader hierarchy, and recovery mechanisms, see the Bootstrap Deep Dive.
5 Nuts Commands
nuts provides a comprehensive suite of commands for package management, execution, and configuration.
| Command | Description |
|---|---|
install | Installs an artifact and its dependencies into the local workspace |
uninstall | Removes an installed artifact from the workspace |
reinstall | Reinstalls an existing artifact, repairing its state and dependencies |
update | Checks for and applies updates to installed artifacts |
check-updates | Checks for newer versions of artifacts without applying them |
fetch | Downloads and caches an artifact and its dependencies without installing it |
push | Synchronizes a local repository to its remote peer |
deploy | Deploys a local artifact into a local repository |
undeploy | Removes a deployed artifact from a local repository |
bundle | Creates a standalone bundle as a complete workspace for an application |
search | Searches for available or installed artifacts across repositories |
exec | Executes an artifact or command with specific arguments |
which | Resolves the appropriate artifact or internal command without executing it |
settings | Manages workspace configuration, repositories, aliases, and security |
info | Displays detailed configuration and environment information |
version | Displays the current API and runtime versions |
help | Provides documentation and usage instructions |
welcome | Bootstraps nuts and displays a welcome message |
license | Displays the nuts open-source license |
5.1 Nuts Commands
For raw command syntax, see the Command Line Help.nuts provides a rich set of commands to manage artifacts, repositories, and workspace configurations. Commands are categorized into internal commands (built into the runtime) and external commands (provided by downloaded artifacts).
Command Categories
Package Management
install: Installs an artifact and its dependencies into the workspace.
uninstall: Removes an installed artifact.
reinstall: Reinstalls an existing artifact, re-resolving dependencies.
update: Checks for and applies updates to installed artifacts.
check-updates: Checks for newer versions without applying them.
Artifact Transfer
fetch: Downloads and caches artifacts without installing them.
deploy: Deploys a local artifact into a local repository.
undeploy: Removes an artifact from a local repository.
push: Synchronizes a local repository to its remote peer.
bundle: Creates an air-gapped standalone bundle containing a complete workspace.
Discovery & Execution
search: Searches for artifacts across local and remote repositories.
which: Resolves the appropriate application or command for execution.
exec: Executes an artifact or internal command.
Configuration
settings: Main configuration command to manage workspace settings, repositories, aliases, launchers, and security.
Information
info: Displays detailed workspace and installation information.
version: Shows the nuts API and runtime versions.
help: Provides documentation and usage instructions.
license: Displays the nuts open-source license.
welcome: Bootstraps the workspace and shows a welcome message.
Execution Modes
Nuts supports multiple ways to invoke external commands:
Spawn (--spawn): The default mode. Spawns a new operating system process for the command.
Embedded (--embedded): Executes Java-based commands within the current JVM process to avoid startup overhead.
System (--syscall): Delegates the execution directly to the underlying operating system.
Additionally, commands can be run in dry mode using the --dry flag. This simulates the execution without applying any side effects, allowing you to preview actions before committing.
Common Global Options
Many commands accept global options to modify their behavior:
-y or --yes: Automatically confirms all interactive prompts. Ideal for CI/CD environments.
-n or --no: Automatically rejects all interactive prompts.
--bot: Enables bot mode, formatting output for automated processing and suppressing interactive prompts.
--json: Formats the output as structured JSON.
--workspace=<path>: Specifies an alternative workspace directory.--trace: Enables detailed tracing for debugging.
--dry: Simulates the command without side effects.
5.2 Exec
Synopsis
nuts exec [options] <command> [<args>...]
Description
The exec command executes another artifact or command. When you type nuts <command>, it is implicitly translated to nuts exec <command>.
The exec command is particularly helpful because it permits passing extra parameters to application executors. In nuts, an application executor is an artifact that can be used to run other artifacts. For instance, nsh (a companion shell) is an executor for all .nsh artifacts.
Some executors are specially handled, such as the java executor, which is used to run all JARs and Java-based artifacts. The Java executor supports all standard JVM options.
nuts exec -Xmx1G netbeans-launcher
In this example, the -Xmx1G argument is passed to the Java executor because netbeans-launcher is resolved as a Java-based artifact.
External Commands
External commands are commands that invoke another downloaded artifact. For example:
nuts netbeans-command
This runs an external command, specifically the net.thevpc.app:netbeans-launcher#1.2.2 artifact.
External Files & URLs
You can run any JAR file using nuts as long as it contains a supported descriptor (e.g., standard Maven metadata) and is specified as a path (containing a / or \ separator).
wget -N https://github.com/thevpc/vpc-public-maven/raw/master/net/vpc/app/netbeans-launcher/1.2.2/netbeans-launcher-1.2.2.jar
nuts ./netbeans-launcher-1.2.2.jar
You can also run a remote file directly via its URL:
nuts https://github.com/thevpc/vpc-public-maven/raw/master/net/vpc/app/netbeans-launcher/1.2.2/netbeans-launcher-1.2.2.jar
Execution Types
Spawn (Default)
The default execution type where any external command spawns a new process. Internal commands are not affected and always run embedded.
nuts --spawn ls
Embedded
The command runs within the current JVM process, avoiding the overhead of spawning a new process (applicable only to Java commands).
nuts --embedded nsh -c ls
System
The command execution is delegated directly to the underlying operating system shell.
nuts --system ls
Rerun & Cron Scheduling
The exec command supports repeated execution loops and cron scheduling:
| Option | Description |
|---|---|
--rerun | Runs the command continuously in a loop |
| Schedules application execution using standard cron expression format |
| Minimum runtime threshold; if app crashes/stops before this time, the loop terminates |
| Sleep duration to wait between consecutive loop iterations |
| Maximum number of iterations before exiting the rerun loop |
# Rerun app with a 5 second safe delay between runs
nuts exec --rerun --rerun-safe-time=5s myapp
# Run on a cron schedule
nuts exec --cron="0 0 * * *" my-daily-job
Remote Execution
Execute commands on remote hosts via connection strings:
| Option | Description |
|---|---|
| Runs the command on a remote machine using the given connection string. Currently supports SSH connection strings in the format |
nuts exec --target=ssh://user:pass@remote-host:22 myapp
Privilege Modes
| Option | Description |
|---|---|
--current-user | Runs with current user privileges (default) |
--as-root | Runs with system root privileges (prompts for root password if required) |
--sudo | Runs with elevated privileges via sudo |
| Runs under specified system user identity |
Java Executor Options
When executing Java artifacts, nuts provides specialized executor flags:
| Option | Description |
|---|---|
| Specify required Java version (e.g. 11, 17, 21) |
| Explicit JDK/JRE installation home directory |
| Specify main class to execute (name or candidate index) |
| Custom classpath entries |
| Additional nuts artifact IDs to append to classpath |
| Working directory for process execution |
--win / --javaw | Use windowless javaw executable for GUI applications |
--show-command | Prints the full resolved Java command line prior to launch |
Execution Modes
Effective Execution (Default)
The command is executed normally with all side effects applied.
Dry Execution
The command is simulated with no side effects.
nuts --dry version
5.3 Which
Synopsis
nuts which [options] <command>
Description
The which command resolves the command execution path without actually executing it. It performs a dry run to determine how nuts would execute the specified command.
$ nuts which version ls
version : internal command
ls : nuts alias (owner maven-local://net.thevpc.app.nuts.toolbox:nsh# ) : maven-local://net.thevpc.app.nuts.toolbox:nsh# -c ls
In this example, which reveals that version is an internal command, while ls is a nuts alias mapping to an artifact-based command (nsh -c ls).
This is invaluable for debugging why a specific version of a tool is being run, or to inspect alias definitions and executors.
External Commands
For external commands, which resolves the exact artifact ID and version that will be invoked.
$ nuts which netbeans-command
net.thevpc.app:netbeans-launcher#1.2.2
External Files & URLs
Just like exec, which can resolve execution for local JAR files and remote URLs, verifying if they contain supported descriptors.
nuts which ./netbeans-launcher-1.2.2.jar
nuts which https://example.com/myapp.jar
Execution Types
You can use which alongside execution type flags to see how execution strategies affect resolution.
--spawn: Resolves for spawning a new process (default).
--embedded: Resolves for running within the current JVM process.
--syscall: Resolves for operating system delegation.
Execution Modes
Since which is fundamentally a diagnostic tool, it operates safely without side effects, similar to running commands with the --dry flag.
5.4 Fetch
Synopsis
nuts fetch [options] <artifact-id>
Description
The fetch command downloads and caches an artifact and its dependencies into the local machine's cache without installing or executing it. Once downloaded, the artifact transitions to the fetched status.
This command is particularly useful when you need to prepare an environment for offline use, verify that an artifact is available in remote repositories, or simply warm up the workspace cache before a deployment script runs.
Options
The fetch command supports standard global options, including:
--repository=<repo>: Fetch exclusively from the specified repository.-y, --yes: Automatically confirm any resolution prompts.
--dry: Perform a dry run to check what would be fetched without actually downloading anything.
Examples
Fetch a specific version of an artifact:
nuts fetch net.thevpc.app:netbeans-launcher#1.2.2
Fetch the latest available version:
nuts fetch net.thevpc.app:netbeans-launcher
Verify availability using a dry run:
nuts fetch --dry net.thevpc.app:netbeans-launcher
Related Commands
install: Installs an artifact after fetching it.
deploy: Deploys a local artifact to a repository.
search: Searches for artifacts without downloading them.
5.5 Install
Synopsis
nuts install [options] <artifact-id>
Description
To be executed securely and optimally, an artifact should generally be installed. While you can run URLs and local paths directly, installing an artifact ensures it is integrated properly into your workspace.
Installation can be triggered automatically upon first execution (where you are prompted), or manually using the install command.
nuts install net.thevpc.app:netbeans-launcher#1.2.2
You can use wildcard artifact queries to install matching components:
nuts install "net.thevpc.app:netbeans-*"
If an artifact is already installed and you need to reinstall or repair it, use the --force flag (or alternatively, the reinstall command):
nuts install --force net.thevpc.app:netbeans-launcher#1.2.2
Switching Versions
When multiple versions of an artifact are installed, they remain isolated and execute side-by-side. The most recently installed version automatically becomes the default when no version is specified during execution.
To change the default version, simply run install on the desired existing version without the --force flag.
$ nuts install net.thevpc.app:netbeans-launcher#1.2.2
$ nuts netbeans-launcher
1.2.2
$ nuts install net.thevpc.app:netbeans-launcher#1.2.1
$ nuts netbeans-launcher
1.2.1
You can find all installed artifacts using nuts search --installed.
Installation Strategies
The installation system handles dependencies seamlessly using multiple strategies. The status of a package can be installed (explicitly requested by the user) or required (installed implicitly as a dependency).
require: Installs the package and its dependencies as "required". Required packages are automatically uninstalled if no other installed package depends on them.
install: Installs the package as a primary, first-class installed package.
reinstall: Re-installs or re-requires the package and its dependencies.
repair: Repairs a given dependency state.
State Transition Matrix
| Status/Strategy | REQUIRE | INSTALL | REINSTALL | REPAIR |
|---|---|---|---|---|
| NOT_INSTALLED | REQUIRED | INSTALLED | INSTALLED? | ERROR |
| INSTALLED | INSTALLED REQUIRED | INSTALLED? | INSTALLED | INSTALLED |
| INSTALLED REQUIRED | INSTALLED REQUIRED | INSTALLED REQUIRED | INSTALLED REQUIRED | INSTALLED REQUIRED |
| REQUIRED | REQUIRED | INSTALLED REQUIRED | REQUIRED | REQUIRED |
| INSTALLED OBSOLETE | INSTALLED REQUIRED OBSOLETE | INSTALLED | INSTALLED | INSTALLED |
| INSTALLED REQUIRED OBSOLETE | INSTALLED REQUIRED | INSTALLED REQUIRED | INSTALLED REQUIRED | INSTALLED REQUIRED |
| REQUIRED OBSOLETE | REQUIRED OBSOLETE | INSTALLED REQUIRED | REQUIRED | REQUIRED |
5.6 Uninstall
Synopsis
nuts uninstall [options] <artifact-id>[#version]
Description
The uninstall command removes an installed artifact from the local workspace.
When an artifact is uninstalled, its binaries and execution scripts are removed. However, configuration files and data generated by the application may be preserved depending on the application's specific behavior and the workspace settings.
Options
--all-versions: Uninstalls all installed versions of the specified artifact.
--erase: Completely removes the artifact, including its cached files, data, and configuration (if supported by the artifact's uninstaller).
-y, --yes: Automatically confirm the uninstallation prompt.
Examples
Uninstall the default or latest installed version of an artifact:
nuts uninstall net.thevpc.app:netbeans-launcher
Uninstall a specific version:
nuts uninstall net.thevpc.app:netbeans-launcher#1.2.1
Uninstall all versions of an artifact:
nuts uninstall --all-versions net.thevpc.app:netbeans-launcher
Related Commands
install: Installs a new artifact.
reinstall: Reinstalls an existing artifact.
search: Searches for currently installed artifacts using
nuts search --installed.
5.7 Check Updates
Synopsis
nuts check-updates [options] [<artifact-id>]
Description
The check-updates command resolves and displays available updates for the specified artifact, or for all installed artifacts if no specific artifact is provided.
This command does not perform the updates. It is used strictly for information and verification purposes, allowing you to see what new versions are available before deciding to upgrade. To actually apply the updates, use the update command.
When to Use
- Auditing the current workspace for outdated packages.
- Checking if a critical security patch is available for a specific artifact.
- Scripting environments where you want to evaluate updates before triggering an upgrade cycle.
Options
-a, --all: Checks for updates across all packages.
-i, --installed: Checks for updates only for explicitly installed artifacts.
-e, --extensions: Checks for updates for installed nuts extensions.
-c, --companions: Checks for updates for nuts companions.
-r, --runtime: Checks for updates for the nuts runtime.
-A, --api: Checks for updates for the nuts API.
--json: Outputs the available updates in a structured JSON format, useful for CI/CD parsing.
--table: Displays the updates in a tabular format.
--dry: Simulates the check.
Examples
Check for updates across all installed artifacts:
nuts check-updates
Check for updates for a specific artifact:
nuts check-updates netbeans-launcher
Check for updates for the nuts API and runtime:
nuts check-updates -A -r
Related Commands
update: Checks for and applies available updates.
search: Searches for specific versions of artifacts.
5.8 Update
Synopsis
nuts update [options] [<artifact-id>]
Description
The update command resolves available updates for the specified artifacts and applies them to the workspace. If no artifact is specified, it checks for and updates all currently installed artifacts.
Unlike check-updates, which only reports available newer versions, the update command automatically fetches and installs the latest stable versions. It can also be used to update the nuts package manager itself.
Options
-a, --all: Update all applicable artifacts.
-w, --workspace: Update workspace dependencies.
-i, --installed: Update explicitly installed artifacts.
-e, --extensions: Update nuts extensions.
-c, --companions: Update nuts companions.
-r, --runtime: Update the nuts runtime implementation.
-A, --api: Update the nuts API bootstrap jar.
-v <version>,--to-version <version>: Force an update to a specific version (this allows downgrading as well).-y, --yes: Automatically confirms all update prompts.
--dry: Simulates the update process, showing what would be updated without applying changes.
--json: Formats the update results as structured JSON.
Examples
Update all installed artifacts in the workspace:
nuts update
Update a specific artifact:
nuts update netbeans-launcher
Force an artifact to a specific version (can be used to downgrade):
nuts update netbeans-launcher --to-version 1.2.0
Update the nuts package manager runtime and API:
nuts update -r -A
Simulate an update to see what would change:
nuts update --dry
Related Commands
check-updates: Only checks for updates without applying them.
install: Installs specific versions of an artifact.
reinstall: Reinstalls the current version of an artifact to repair it.
5.9 Reinstall
Synopsis
nuts reinstall [options] <artifact-id>
Description
The reinstall command is used to reinstall an existing, already installed artifact.
When you execute this command, nuts forces the re-resolution of the artifact's dependencies, repairs corrupted installation states, and re-executes the installer script. This is highly useful when an artifact's execution environment has been compromised, when files have been accidentally deleted from the workspace, or when dependencies need to be force-synced.
Options
-y, --yes: Automatically confirm prompts.
--dry: Perform a dry run simulation.
Examples
Reinstall a specific artifact to repair it:
nuts reinstall net.thevpc.app:netbeans-launcher
Related Commands
install: Installs a new artifact.
uninstall: Removes an artifact.
update: Upgrades an artifact to a newer version.
5.10 Search
Synopsis
nuts search [options] <query>
Description
The search command queries available repositories to find artifacts.
Artifacts can be in several states:
unavailable: No registered repository can serve the artifact.
available: At least one repository can serve the artifact.
fetched: The artifact is cached locally.
installed: The artifact is fetched and fully installed in the workspace.
installed default: The artifact is installed and marked as the default version.
Artifact Queries
An artifact query is a generalized artifact ID that supports wildcards and version intervals.
Examples of artifact queries:
# All artifacts that start with netbeans, regardless of groupId
nuts search "netbeans*"
nuts search "*:netbeans*"
# All artifacts in the net.thevpc.app groupId
nuts search "net.thevpc.app:*"
# All artifacts in any net.thevpc.* sub-group
nuts search "net.thevpc.*:*"
# Artifacts filtered by OS and architecture
nuts search "netbeans*?os=windows&arch=x86_64"
# Version greater than 1.2.0 (excluding 1.2.0)
nuts search "netbeans-launcher#]1.2.0,["
# Version greater than or equal to 1.2.0
nuts search "netbeans-launcher#[1.2.0,["
Options
You can filter search results by status:
-i, --installed: Search only for installed artifacts.
--local: Search only for locally fetched/cached artifacts.
--remote: Search only for non-fetched, remote artifacts.
--online: Search in installed, then local, then remote. Stops when the first match is found.
-a, --anywhere: Search everywhere and return all results.
Output Formatting
The search command supports structured output, making it highly useful for scripting. Use the -l or --long flag for verbose listings.
$ nuts search -i -l
I-X 2019-08-26 09:53:53.141 anonymous vpc-public-maven net.thevpc.app:netbeans-launcher#1.2.1
IcX 2019-08-24 11:05:49.591 admin maven-local net.thevpc.app.nuts.toolbox:nsh#
I-x 2019-08-26 09:50:03.423 anonymous vpc-public-maven net.thevpc.app:kifkif#1.3.3
You can change the output format using global flags: --plain, --json, --xml, --table, or --tree.
$ nuts search -i -l --json
[
{
"id": "vpc-public-maven://net.thevpc.app:netbeans-launcher#1.2.1",
"descriptor": {
"id": "net.thevpc.app:netbeans-launcher#1.2.1",
"packaging": "jar",
"executable": true
}
}
]
5.11 Deploy
Synopsis
nuts deploy [options] <file-or-artifact>
Description
The deploy command installs a local artifact (such as a locally built JAR file or a Maven POM descriptor) into a local nuts repository. Once deployed, the artifact becomes available for installation and execution within your workspace, just as if it had been fetched from a remote repository.
This is essential for local development, allowing you to test artifacts before pushing them to remote servers.
Options
--repository=<repo>: Specifies the target local repository to deploy to.-y, --yes: Skip confirmation prompts.
Examples
Deploy a locally built JAR file:
nuts deploy ./target/my-app-1.0.jar
Deploy using a specific descriptor:
nuts deploy ./pom.xml
Related Commands
push: Synchronizes a local repository to a remote repository.
undeploy: Removes a deployed artifact from a local repository.
5.12 Push
Synopsis
nuts push [options] <artifact-id>
Description
The push command uploads an artifact from a local repository to a remote repository. This essentially synchronizes the local artifact deployment with its remote peer, making the artifact available to other users or environments.
It acts as the counterpart to fetch, allowing developers to publish their completed applications or libraries.
Options
--repository=<repo>: The target remote repository to push the artifact to.-y, --yes: Suppress confirmation prompts.
Examples
Push an artifact to the default remote repository:
nuts push net.thevpc.app:my-awesome-tool#1.0.0
Related Commands
deploy: Deploys an artifact locally.
fetch: Downloads an artifact from a remote repository.
5.13 Undeploy
Synopsis
nuts undeploy [options] <artifact-id>
Description
The undeploy command removes a deployed artifact from a local repository.
This command is the reverse of deploy and is typically used to clean up local development repositories or remove testing artifacts that are no longer needed. Note that this removes the artifact from the repository index and storage, making it unavailable for new installations.
Options
--repository=<repo>: Specifies which local repository to undeploy from.-y, --yes: Skip confirmation prompts.
Examples
Undeploy a specific artifact version:
nuts undeploy net.thevpc.app:my-awesome-tool#1.0.0
Related Commands
deploy: Deploys a local artifact to a repository.
uninstall: Removes an installed artifact from the active workspace.
5.14 Settings
Synopsis
nuts settings <subcommand> [options]
Description
The settings command is the primary configuration tool for managing nuts workspaces. It acts as a meta-command with numerous subcommands to handle repositories, group imports, aliases, desktop integration (NDI), user security, JDK installations, logging, backups, and more.
By using the settings command, administrators can tailor the environment to their specific deployment needs, ensuring proper artifact resolution, tight security, and customized command aliases.
Subcommands Overview
Managing Repositories
Repositories define where nuts searches for and downloads artifacts.
settings add repo <url>: Adds a new repository to the workspace.settings remove repo <id>: Removes an existing repository.settings enable repo/settings disable repo: Enables or disables a repository.settings edit repo: Edits repository configuration.settings list repos: Lists all configured repositories.
Managing Imports
Group imports allow you to shorten artifact IDs by implicitly searching within designated group prefixes.
settings add import <groupId>: Adds a group ID to the import list.settings remove import <groupId>: Removes a group ID.settings list imports: Lists all active group imports.
Managing Aliases
Aliases allow you to create custom commands with preset arguments.
settings add alias <name> <command>: Creates a new alias.settings remove alias <name>: Deletes an alias.settings list aliases: Displays all registered aliases.
Desktop Integration (NDI)
Launchers and desktop integration integrate nuts artifacts with the host OS.
settings ndi [options] <package>: Manages desktop integration (menu entries, desktop shortcuts, icons).
Managing Java (JDKs)
nuts can provision and manage specific JDK versions required by artifacts.
settings add java --search: Scans the system for available JDKs.settings add java <folder>: Registers a new JDK installation from a specific path.settings remove java <name>: Removes a registered JDK.settings list java: Lists registered JDKs.
Managing Security & Users
The security model supports user authentication and restricted execution.
settings secure: Enables security mode for the workspace.settings unsecure: Disables security mode.settings add user <username>: Adds a new authorized user.settings remove user <username>: Removes a user.settings list users: Lists all users.settings password: Change the current user's password.
Maintenance & Operations
settings backup --file=<file>/settings restore --file=<file>: Backs up or restores the workspace configuration.settings connect --password=<password> user@host:port: Connects to remote environments.settings delete bin|conf|var|log|temp|cache|run: Clears specific workspace directories.settings update stats: Updates workspace statistics.settings get log level/settings set log level: Manages the workspace logging level.
Examples
Add a custom Maven repository:
nuts settings add repo https://my-company.com/maven/
Create a shortcut alias for a frequently used command:
nuts settings add alias nsh-ls "nsh -c ls"
Register a specific JDK version for older artifacts:
nuts settings add java /usr/lib/jvm/java-11-openjdk/
Create desktop shortcuts for an application:
nuts settings ndi --menu --desktop net.thevpc.app:netbeans-launcher
Backup the workspace configuration:
nuts settings backup --file=my-workspace-backup.zip
5.15 Welcome
Description
The welcome command simply bootstraps the nuts workspace and displays a welcome message. It does not perform any structural changes or execute other artifacts.
_ __ __
/ | / /_ __/ /______ Network Updatable Things Services
/ |/ / / / / __/ ___/ The Open Source Package Manager for Java (TM)
/ /| / /_/ / /_(__ ) and other Things ... by vpc
/_/ |_/\__,_/\__/____/ https://github.com/thevpc/nuts
version
SYNOPSIS:
nuts [<options>]... <command> <args> ...
For Help, type nuts help
5.16 Info
Synopsis
nuts info [options]
Description
The info command provides detailed diagnostic information about the booted nuts workspace. While version gives you basic API and runtime versions, info displays the complete operational context, including configuration variables, storage locations, security flags, and the Java environment running the workspace.
Example Output
$ nuts info
name = default-workspace
nuts-api-version = 1.0.0
nuts-api-id = net.thevpc.app.nuts:nuts#1.0.0
nuts-runtime-id = net.thevpc.app.nuts:nuts-core#
nuts-runtime-path = ~/.cache/nuts/default-workspace/boot/net/vpc/app/nuts/nuts-core//nuts-core-.jar;~/.cache/nuts/default-workspace/boot/net/vpc/app/nuts/nuts/1.0.0/nuts-1.0.0.jar;~/.cache/nuts/default-workspace/boot/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar;~/.cache/nuts/default-workspace/boot/org/fusesource/jansi/jansi/1.17.1/jansi-1.17.1.jar
nuts-workspace-id = 99b73002-804d-4e4c-9a13-f57ac1f40b3d
nuts-store-layout = linux
nuts-store-strategy = exploded
nuts-repo-store-strategy = exploded
nuts-global = false
nuts-workspace = ~/.config/nuts/default-workspace
nuts-workspace-apps = ~/.local/share/nuts/apps/default-workspace
nuts-workspace-config = ~/.config/nuts/default-workspace/config
nuts-workspace-var = ~/.local/share/nuts/var/default-workspace
nuts-workspace-log = ~/.local/log/nuts/default-workspace
nuts-workspace-temp = ~/nuts/default-workspace
nuts-workspace-cache = ~/.cache/nuts/default-workspace
nuts-workspace-lib = ~/.local/share/nuts/lib/default-workspace
nuts-workspace-run = /run/user/1000/nuts/default-workspace
nuts-open-mode = open-or-create
nuts-secure = false
nuts-gui = false
nuts-inherited = false
nuts-recover = false
nuts-reset = false
nuts-debug = false
nuts-trace = true
nuts-read-only = false
nuts-install-companions = false
nuts-skip-welcome = false
java-version = 1.8.0_222
platform = java#1.8.0_222
java-home = /usr/lib64/jvm/java-1.8.0-openjdk-1.8.0/jre
java-executable = /usr/lib64/jvm/java-1.8.0-openjdk-1.8.0/jre/bin/java
java-classpath = ~/.m2/repository/net/vpc/app/nuts/nuts/1.0.0/nuts-1.0.0.jar
java-library-path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
os-name = linux#4.12.14-lp151.28.13-default
os-family = linux
os-dist = opensuse-leap#15.1
os-arch = x86_64
user-name = me
user-home = /home/me
user-dir = /home/me
command-line-long = --color=system --trace --open-or-create --exec info
command-line-short = -t info
inherited = false
inherited-nuts-boot-args =
inherited-nuts-args =
creation-started = 2019-08-26 00:02:10.903
creation-finished = 2019-08-26 00:02:11.223
creation-within = 320ms
repositories-count = 5
This structured output is highly valuable when submitting bug reports, debugging XDG-compliant folder layouts, or verifying that your execution environment is correctly configured.
5.17 Version
Synopsis
nuts version
Description
The version command displays the current version of the nuts runtime.
nuts uses a decoupled architecture consisting of a bootstrap API and a runtime implementation.
The API (the
nuts-*.jarfile, ~500KB) contains only the minimum logic required to bootstrap the environment and fetch the runtime.- The Implementation (the full runtime, ~3MB) contains the actual logic for dependency resolution, package management, and execution.
Generally, the implementation version tracks the API version, but they can evolve independently.
$ nuts version
1.0.0/1.0.0.0
Here, the version command displays both the API version (1.0.0) and the implementation version.
5.18 Help Command
Synopsis
nuts help [<command>]
Description
The help command displays the manual and usage instructions for nuts itself or for specific commands.
To view the help manual for a specific command, pass the command name as an argument:
$ nuts help version
version :
nuts version
nuts --version
nuts -version
nuts -v
show version and exit
...
Alternatively, all nuts commands inherently support the --help flag, which produces the exact same output. The following command is entirely equivalent:
$ nuts version --help
You can use nuts help without arguments to view the general system manual and a list of available commands.
5.19 License
Synopsis
nuts license
Description
The license command displays the open-source license for nuts and exits.
nuts is proudly open-source and is distributed under the GNU General Public License v3 (GPL-3.0), which guarantees end users the freedom to run, study, share, and modify the software.
_ __ __
/ | / /_ __/ /______ Network Updatable Things Services
/ |/ / / / / __/ ___/ The Open Source Package Manager for Java (TM)
/ /| / /_/ / /_(__ ) and other Things ... by vpc
/_/ |_/\__,_/\__/____/ https://github.com/thevpc/nuts
version
Is a new Open Source Package Manager to help install packages
and libraries for runtime execution. Nuts is the ultimate companion for
maven (and other build managers) as it helps installing all package
dependencies at runtime. Nuts is not tied to java and is a good choice
to share shell scripts and other 'Things' . It's based on an extensible
architecture to help supporting a large range of sub managers / repositories.
Copyright (C) 2016-2019 thevpc
Licensed under the GNU LESSER GENERAL PUBLIC LICENSE Version 3 (the "License"); you may
not use this file except in compliance with the License. You may obtain a
copy of the License at
https://www.gnu.org/licenses/lgpl-3.0.en.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an
AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific language
governing permissions and limitations under the License.
6 ANSI Themes
ANSI Themes
Overview
Nuts provides a powerful theming system for ANSI and NTF (Nuts Text Format) formatted output. Themes map semantic text styles (such as PRIMARY, KEYWORD, ERROR, WARN, INFO, PATH, etc.) to specific terminal colors, supporting 16-color ANSI, 256-color palettes, and 24-bit RGB true-colors.
The --theme option supports specifying theme parameters by theme name (for built-in or cached themes) or by file path / URL (for custom .ntf-theme files).
Built-in Themes & Default Names
Nuts includes several built-in themes available out-of-the-box. You can reference them directly by name:
default – OS-dependent default theme (grass on Windows, standard theme on Unix/Linux).
ansi – Basic 16-color ANSI palette theme.
grass – Green/nature-toned palette, optimized for Windows terminals.
horizon – Dark blue horizon theme, default on Unix/Linux.
whiteboard – Light background theme using 24-bit true colors.
When no theme name or path is provided (or when set to default), Nuts automatically selects the appropriate default theme for the running operating system environment.
Setting Themes via Command Line (--theme)
The --theme CLI option accepts either a built-in theme name or a file path/URL to a custom theme file.
1. By Theme Name
Pass one of the default theme names (default, ansi, grass, horizon, whiteboard):
nuts --theme=horizon
2. By File Path or URL
Pass a file path (relative or absolute) or URL to a .ntf-theme file:
nuts --theme=/path/to/my-theme.ntf-theme
Defining Your Own Theme
Themes are defined in .ntf-theme property files. A theme file consists of key-value pairs defining: 1. Optional theme metadata (e.g. theme-name=my-theme). 2. Optional custom color/palette variables (e.g., MY_BLUE=4, DARK_RED=#670000). 3. Mapping rules for semantic token styles.
Syntax & Format
# example.ntf-theme
theme-name=my-theme
# Palette variables (ANSI numbers 0-255 or 24-bit hex colors)
DARK_BLUE=4
BRIGHT_BLUE=12
DARK_SKY=6
DARK_RED=#670000
# Primary and Secondary base palette styles with variant index
PRIMARY(0)=foregroundColor(DARK_BLUE)
PRIMARY(1)=foregroundColor(BRIGHT_BLUE)
PRIMARY(*)=PRIMARY(*%16)
SECONDARY(0)=backgroundColor(DARK_BLUE)
SECONDARY(*)=SECONDARY(*%16)
# Title style combining primary and underline
TITLE(*)=primary(*),underlined()
# Syntax & Token Styles
KEYWORD(0)=foregroundColor(BRIGHT_BLUE)
KEYWORD(1)=foregroundColor(DARK_SKY)
KEYWORD(*)=KEYWORD(*%4)
OPTION(0)=foregroundColor(DARK_SKY)
OPTION(*)=KEYWORD(*%4)
# Semantic UI & Status Styles
ERROR(*)=foregroundColor(DARK_RED)
SUCCESS(*)=foregroundColor(2)
WARN(*)=foregroundColor(3)
INFO(*)=foregroundColor(DARK_SKY)
CONFIG(*)=foregroundColor(5)
DATE(*)=foregroundColor(6)
NUMBER(*)=foregroundColor(6)
BOOLEAN(*)=foregroundColor(6)
STRING(*)=foregroundColor(8)
SEPARATOR(*)=foregroundColor(208)
OPERATOR(*)=foregroundColor(208)
INPUT(*)=foregroundColor(11)
FAIL(*)=foregroundColor(DARK_RED)
DANGER(*)=foregroundColor(DARK_RED)
VAR(*)=foregroundColor(190)
PALE(*)=foregroundColor(250)
COMMENTS(*)=foregroundColor(250)
VERSION(*)=foregroundColor(220)
PATH(*)=foregroundColor(114)
Supported Token Styles
Supported semantic style tokens include:
Base: PRIMARY, SECONDARY, TITLE
Syntax: KEYWORD, ENTITY, ACTION, ANNOTATION, VAR, OPERATOR, SEPARATOR, COMMENTS
Literals: STRING, INPUT, PATH, VERSION, NUMBER, DATE, BOOLEAN, OPTION, PLACEHOLDER
UI Status: INFO, CONFIG, SUCCESS, WARN, ERROR, DANGER, FAIL, PALE
Supported Styling Functions
Modifiers: plain, underlined, bold, blink, striked, reversed, italic
Colors:
foregroundColor(val)/foreground(val),backgroundColor(val)/background(val),foregroundTrueColor(val),backgroundTrueColor(val)or direct#RRGGBBhex values.
Custom Theme Locations
Place custom theme files in: 1. The Nuts user configuration directory under ~/.config/nuts/.../themes/<name>. 2. The application classpath under META-INF/ntf-themes/<name>.ntf-theme. 3. Any accessible filesystem location loaded by path or URL using --theme=/path/to/theme.ntf-theme.
Further Reading
For more details, refer to the Styling Messages section.
7 Appendix
Supplementary reference material and deep dives.
7.1 Bootstrap Deep Dive
Bootstrap Deep Dive
This technical specification details the complete sequence of operations performed by NBootWorkspaceImpl during the nuts bootstrap lifecycle.
The Bootstrap Lifecycle Step-by-Step
When you execute nuts (or java -jar nuts.jar), NBootWorkspaceImpl executes the following sequence:
Step 1: Environment and Option Parsing
1. Inherited System Properties: Reads options from system env (NUTS_BOOT_ARGS) and propertu (nuts.args) (unless --skip-inherited is specified). 2. Command Line Arguments: Tokenizes CLI options using NBootWorkspaceCmdLineParser. 3. Custom Boot Options:
---m2: Enables or disables local Maven repository (
~/.m2/repository) integration.---connection-timeout: Sets network timeout thresholds for remote repository checks. 4. Bot / Automation Mode: If launched for shell completion or with --bot, interactive prompts are disabled (
confirm=ERRORorconfirm=NO).
Step 2: Workspace Location & Layout Resolution
The bootstrapper determines the active workspace directory and storage layout:
Workspace Identification:
Pinned workspace via
--workspace <path-or-name>or-w <name>.Protocol-based remote workspace (e.g.
http://orssh://).Default workspace:
~/.config/nuts/default-workspace(or OS equivalent).
Isolation Modes:
SYSTEM: Global shared workspace (
/etc/opt/nutson Linux/Unix,C:\Program Files\nutson Windows).USER: Per-user isolated workspace (
~/.nutsor standard XDG directories).SANDBOX: Completely isolated temporary directory (
nuts-sandbox-...), using STANDALONE storage and deleted upon JVM termination.MEMORY: In-memory temporary workspace.
Store Location Mapping:
Computes physical paths for each functional store based on the active strategy (EXPLODED or STANDALONE):
BIN: Executable binaries and scripts.
CONF: Workspace configuration (
nuts-workspace.json, API/runtime descriptors).LIB: Cached JARs, POMs, and library binaries.
VAR: Application databases and runtime state.
LOG: Log and trace files.
TEMP: Temporary scratch folders.
CACHE: Ephemeral index caches.
RUN: Process IDs, named pipes, and socket files.
Step 3: Repository Discovery
The bootstrapper resolves the list of repositories used to download nuts-runtime and dependencies: 1. Previous Workspace Configuration: If the workspace was previously initialized, loads repository definitions from nuts-workspace.json. 2. Default Repositories: If creating a fresh workspace, uses built-in defaults:
maven: Local Maven cache (
~/.m2/repository).central: Maven Central (
https://repo.maven.apache.org/maven2).nuts-preview: Nuts Preview Repository (enabled by default or via --preview-repo). 3. Repository Descriptors: Reads local
.nuts-repositorymetadata files when referencing directory-based repositories.
Step 4: API Version Resolution
The bootstrapper identifies the target nuts-api version:
Explicit Version: Specified via
--api-version <version>.LATEST or RELEASE
: Queries configured repositories for the highest available version inmaven-metadata.xml.Embedded Default: Falls back to the bootstrapper's own built-in NUTS_BOOT_VERSION.
Inherited Session: When executing embedded within an existing nuts process, strictly enforces NUTS_BOOT_VERSION to prevent classloader collisions.
Step 5: Runtime Version & Dependency Resolution
Once the API version is determined (e.g., 1.0.0): 1. Version Prefix Matching: The bootstrapper looks for net.thevpc.nuts:nuts-runtime where the runtime version starts with <apiVersion>. (e.g., 1.0.0.0, 1.0.0.1). 2. Local-First Resolution:
Checks the workspace's local
LIB/id/cache.If not found or if cache is expired (--expire), queries remote repositories for the latest matching version.
If offline and remote queries fail, inspects the local fallback cache map (getFallbackCache). 3. Dependency Descriptor: Loads the runtime descriptor (
.nutsJSON descriptor orpom.xml) containing the runtime's transitive dependencies.
Step 6: ClassLoader & ClassWorld Construction
1. Artifact Verification & Download:
Missing JARs are downloaded into the workspace LIB store (<lib-store>/id/<group-path>/<artifact>/<version>/<artifact>-<version>.jar). 2.
NBootClassLoader Creation
:Constructs an isolated classloader tree (NBootClassLoader) containing:
nuts-runtime.jar- Runtime dependencies (e.g., internal parsers, terminal formatters, SSH/crypto helpers).
- Parent ClassLoader: Context ClassLoader / System ClassLoader.
Step 7: Factory SPI Discovery & Handoff
1. ServiceLoader Discovery:
Executes ServiceLoader.load(NBootWorkspaceFactory.class, workspaceClassLoader) to find workspace factory implementations inside the loaded nuts-runtime.jar. 2. Priority Ordering:
Sorts discovered factories using NBootWorkspaceFactoryComparator (which evaluates supported API versions, runtime architectures, and priority scores). 3. Workspace Instantiation:
Calls factory.createWorkspace(bootOptions) to instantiate NWorkspaceBase.
Step 8: Execution
With the runtime loaded:
If --version or --help was requested, outputs formatted information and exits.
If
--nuts-exec-mode=completewas requested, generates auto-completion suggestions.Otherwise, executes
workspace.runBootCommand(), handing full control over to nuts-runtime.
Multi-Process Execution & Delegation
When the requested execution requirements cannot be satisfied in the current JVM process, NBootWorkspaceImpl automatically delegates to a child JVM process via runNewProcess():
Current JVM (e.g. Java 17, nuts-boot 1.0.0)
│
├─ Requires Java 8? ────────► Spawns `java-8 -jar nuts.jar ...`
├─ Custom JVM options? ─────► Spawns `java [custom-opts] -jar nuts.jar ...`
└─ Target API mismatch? ────► Spawns `java -jar <resolved-api-nuts.jar> ...`
Requirement Triggers
Java Executable: Different JVM executable requested via
--java-command <path>.JVM Options: Specific memory/GC/system options requested via
--java-options <options>.API Version: Target API version differs from NUTS_BOOT_VERSION.
Recovery and Maintenance Flags
| Flag | Description | Action Taken by NBootWorkspaceImpl |
|---|---|---|
--expire | Forces expiration of cached metadata | Bypasses local timestamp cache checks and re-validates repository metadata. |
--recover | Recovers a corrupted workspace | Clears CACHE, TEMP, and deletes cached |
--reset | Reinitializes workspace | Deletes workspace configuration and cache while preserving user data and previous repository configurations. |
--reset-hard | System-wide reset | Deletes all workspace store locations and restores the system to a clean state. |
-N / --dry | Dry run | Simulates bootstrap actions without modifying the filesystem. |
Error Diagnostics & Troubleshooting
When bootstrap fails (e.g. network failure or missing runtime), NBootWorkspaceImpl logs a comprehensive diagnostics block containing:
Exact nuts-boot version and API version.
- Resolved workspace locations and storage layout.
- Active repositories and connection timeout settings.
- JVM version, executable path, classpath, and OS properties.
- Full exception stack traces with component context.