Native Mode
JFrog CLI provides two execution modes for package managers: Wrapped Mode (default) and Native Mode (opt-in). This page explains the difference, which tools support Native Mode, and how to configure each one.
Prerequisites
Before using any build-tool command, ensure the following are in place:
| Requirement | Details |
|---|---|
| JFrog CLI configured | Run jf config add at least once. Verify with jf config show. |
| Tool installed | Install the package manager you intend to use (Maven, Gradle, npm, Poetry, Docker). |
| Tool-specific runtime | Maven and Gradle require Java in PATH. Verify with java -version. |
| Docker daemon running | Docker Native Mode requires the Docker daemon to be active. Verify with docker info. |
| Artifactory access | For Native Mode: a repository must exist and credentials must be configured via Artifactory Set Me Up. For Wrapped Mode: run jf <tool>-config first. |
Tip
If you have multiple JFrog servers configured, identify your default server with
jf config show. Alljf rt build-publishandjf rt bpcommands use the default server unless you pass--server-id=<your-server-id>explicitly.
Build-Info Flags in Native Mode
The following flags are available on every build-tool command that supports build-info collection. They work in both Wrapped Mode and Native Mode.
| Flag | Default | Description |
|---|---|---|
--build-name | — | A name for this build (for example, my-web-app). Required with --build-number. |
--build-number | — | A number or identifier for this build run (for example, 42, $BUILD_NUMBER). Required with --build-name. |
--project | — | JFrog Artifactory project key. Associates the build-info with a specific project. |
--module | — | Optional module name within the build-info. Use when a single build produces artifacts from multiple modules. Requires --build-name and --build-number. |
Note
--build-nameand--build-numbermust always be provided together. If you supply one without the other, the CLI returns an error.
--module Flag
--module FlagThe --module flag is used when a single build produces multiple logical components:
jf mvn clean install --build-name=my-app --build-number=1 --module=backend
jf mvn clean install --build-name=my-app --build-number=1 --module=frontend
jf rt build-publish my-app 1 --server-id=<your-server-id>The resulting build-info for build my-app #1 contains two modules (backend and frontend), each with their own dependency trees.
Note
jf rt build-publishuses your default configured server. If the build tool was configured with a different server, pass--server-id=<your-server-id>to target the correct server.
Note
The
--moduleflag is functional for all build-tool commands. For some commands (Maven, Gradle), it does not appear injf <tool> --helpoutput but still works when passed on the command line.
Known CLI limitation
jf npm install --helpdoes not display build-info flags (--build-name,--build-number,--module,--project). These flags are supported and work correctly — checkjf npm publish --helpto see them listed, or refer to this page.
--project Flag
--project FlagThe --project flag associates the build-info with a JFrog Project — an organizational unit in the JFrog Platform that groups repositories, builds, and security policies.
jf npm install --build-name=my-app --build-number=1 --project=my-team
jf rt build-publish my-app 1 --project=my-team --server-id=<your-server-id>Note
The JFrog Project (
--project) must already exist in Artifactory before publishing. Create projects in the JFrog Platform UI under Projects.
Wrapped Mode vs Native Mode
| Aspect | Wrapped Mode (Default) | Native Mode |
|---|---|---|
| Repository configuration | Injected by JFrog CLI from .jfrog/projects/*.yaml | You must configure manually |
| Project file modifications | CLI may modify settings.xml, pyproject.toml, .npmrc, etc. | No project files are modified |
| Build-info collection | Automatic when --build-name / --build-number are provided | Supported for Maven, Gradle, npm, Poetry, Docker, Helm, and Conan when --build-name / --build-number are provided via jf <tool> |
| Lock file changes | Possible (for example, poetry.lock may be updated) | Never modified |
Requires *-config command | Yes — run jf <tool>-config first | No — config is ignored |
| Requires Artifactory Set Me Up | Optional | Required |
Which Tools Support Native Mode?
| Package Manager | How to Enable | Build-Info in Native? | Notes |
|---|---|---|---|
| Maven | export JFROG_RUN_NATIVE=true | Yes | Bypasses mvn-config and .jfrog/ YAML; no settings.xml injection; user must configure Maven manually |
| Gradle | export JFROG_RUN_NATIVE=true | Yes | Bypasses gradle-config and .jfrog/ YAML; no Artifactory plugin injection; pass --server-id for server resolution |
| npm | export JFROG_RUN_NATIVE=true (or deprecated --run-native flag) | Yes | Bypasses npm-config; uses user's .npmrc; build-info still works |
| Poetry | export JFROG_RUN_NATIVE=true | Yes | Bypasses poetry-config and .jfrog/ YAML; no pyproject.toml source injection; no poetry.lock changes; build-info works via jf poetry |
| Docker | export JFROG_RUN_NATIVE=true | Yes | For jf docker build: runs native Docker build directly; build-info still collected when --build-name/--build-number provided |
Native-only tools (no wrapped mode; no *-config command):
Wrapped-only tools (no Native Mode support):
Yarn, pip, Pipenv, Twine, Go, NuGet, .NET, Terraform, Ruby — these tools operate exclusively in Wrapped Mode.
Maven Native Mode
When JFROG_RUN_NATIVE=true is set, jf mvn runs Maven without injecting a generated settings.xml or applying .jfrog/projects/maven.yaml. You must configure Maven to resolve from Artifactory yourself using the Artifactory Set Me Up instructions for your Maven repository. The Set Me Up page generates a <server> entry with your Artifactory URL and credentials that you add to your ~/.m2/settings.xml.
Important — existing
mvn-configusersIf you have previously run
jf mvn-config, a.jfrog/projects/maven.yamlfile exists in your project. When this file is present,JFROG_RUN_NATIVE=trueis currently ignored and the CLI falls back to Wrapped Mode silently.
To switch Maven to Native Mode when .jfrog/projects/maven.yaml exists:
-
Remove the wrapped-mode project file:
rm .jfrog/projects/maven.yaml -
Enable Native Mode for the shell session:
export JFROG_RUN_NATIVE=true
Usage
To run a Maven build in Native Mode:
-
Run:
export JFROG_RUN_NATIVE=true jf mvn clean install --build-name=my-app --build-number=1 --server-id=<your-server-id>Where:
- <your-server-id>: The JFrog CLI server ID from
jf config add
For example:
export JFROG_RUN_NATIVE=true jf mvn clean install --build-name=my-app --build-number=1 --server-id=my-server - <your-server-id>: The JFrog CLI server ID from
Expected output
When Native Mode is active (no .jfrog/projects/maven.yaml present), Maven runs directly and build-info is collected after the build completes:
[INFO] BUILD SUCCESS
[Info] Collecting build info for executed command...
[Info] Build info saved locally. Use 'jf rt bp my-app 1' to publish it to Artifactory.
Note
After Maven finishes, the CLI collects build-info from the build output. This post-build step can take several seconds. The
[Info] Build info saved locallymessage confirms it is complete — the command is not hung.
What changes
- No
settings.xmlinjection - No
.jfrog/projects/maven.yamlis read (requires the file to be absent — see note above) - Build-info is collected after the build completes (post-execution, not via extractor injection)
- All Maven configuration comes from your own
settings.xml
Gradle Native Mode
When JFROG_RUN_NATIVE=true is set, jf gradle runs Gradle without injecting the Artifactory Gradle plugin or applying .jfrog/projects/gradle.yaml. You must configure Gradle to resolve from Artifactory yourself using the Artifactory Set Me Up instructions, which generate the repository URL and credential configuration you add to your build.gradle or gradle.properties.
Important — existing
gradle-configusersIf you have previously run
jf gradle-config, a.jfrog/projects/gradle.yamlfile exists in your project. When this file is present, you must remove it for Native Mode to take effect.
To switch Gradle to Native Mode when .jfrog/projects/gradle.yaml exists:
-
Remove the wrapped-mode project file:
rm .jfrog/projects/gradle.yaml -
Enable Native Mode for the shell session:
export JFROG_RUN_NATIVE=true
Usage
To run a Gradle build in Native Mode:
-
Run:
export JFROG_RUN_NATIVE=true jf gradle clean build --server-id=<your-server-id>Where:
- <your-server-id>: The JFrog CLI server ID to use for build-info (required in Native Mode)
For example:
export JFROG_RUN_NATIVE=true jf gradle clean build --server-id=my-server
Note
In Gradle Native Mode, pass
--server-idto specify which configured JFrog server to use for build-info publishing. Without it, the CLI uses the default server.
What changes
- No Artifactory Gradle plugin injection
- No
.jfrog/projects/gradle.yamlis read (requires the file to be absent — see note above) - Build-info is still collected when
--build-nameand--build-numberare provided - All Gradle configuration comes from your own build scripts
npm Native Mode
When JFROG_RUN_NATIVE=true is set (or the deprecated --run-native flag is used), jf npm delegates entirely to the native npm client and uses your .npmrc for all configuration. You must configure your .npmrc with the Artifactory registry URL and authentication token using the Artifactory Set Me Up instructions for your npm repository.
Usage
To run npm commands in Native Mode:
-
Enable Native Mode for the shell session:
export JFROG_RUN_NATIVE=true -
Run install or publish (examples):
jf npm install --build-name=my-app --build-number=1 jf npm publish --build-name=my-app --build-number=1 --server-id=<your-server-id>Where:
- <your-server-id>: The JFrog CLI server ID for publish operations when you have multiple servers configured
For example:
export JFROG_RUN_NATIVE=true jf npm install --build-name=my-app --build-number=1 jf npm publish --build-name=my-app --build-number=1 --server-id=my-server
When Native Mode is active, the CLI confirms it at the start of execution:
[Info] Running npm in native mode (JFROG_RUN_NATIVE=true)
What changes
- No temporary
.npmrcis created by the CLI - Your own
.npmrcis used for all configuration - Build-info collection still works (as with other tools in Native Mode)
- Publishing uses the native npm publish lifecycle (
prepublish,publish,postpublishscripts run normally — no renaming needed)
Deprecation notice
The
--run-nativeflag is deprecated. Useexport JFROG_RUN_NATIVE=trueinstead. On npm 11.x, passing--run-nativemay also producenpm warn Unknown cli config "--run-native"from the npm client itself — this is harmless and does not affect behaviour.
npm 11.x compatibility
In Wrapped Mode, the JFrog CLI injects
always-authand.npmrc. npm 11.x treats these as deprecated configuration keys and emitsnpm warn Unknown project config "always-auth"on every install. These warnings are harmless. To eliminate them, use Native Mode (JFROG_RUN_NATIVE=true) with a manually configured.npmrc.
Known CLI limitation
jf npm install --helpdoes not display build-info flags. These flags are functional — usejf npm publish --helpto see them listed, or refer to the Build-Info Flags section above.
Poetry Native Mode
When JFROG_RUN_NATIVE=true is set, jf poetry delegates to the native Poetry client without injecting Artifactory configuration or modifying project files. You can run Poetry commands through jf poetry (to benefit from build-info collection) or directly via poetry (without build-info). You must configure Poetry to use the Artifactory repository using the Artifactory Set Me Up instructions for your PyPI repository. The Set Me Up page generates the poetry source add command and credential configuration you add to your project.
Usage
To run Poetry with build-info in Native Mode:
-
Enable Native Mode:
export JFROG_RUN_NATIVE=true -
Run installs and publishes through
jf poetrywhen you need build-info, or use nativepoetrywhen you do not:-
With build-info:
jf poetry install --build-name=my-app --build-number=1 jf poetry publish --build-name=my-app --build-number=1 -
Without build-info:
poetry install poetry build poetry publish -r artifactory
-
Note
In Native Mode, you can use either
jf poetry install(which delegates to native Poetry and collects build-info when--build-name/--build-numberare provided) orpoetry installdirectly (no build-info). Poetry must be configured via Artifactory's Set Me Up instructions for both approaches.
What changes
- No
tool.poetry.sourceentries are injected intopyproject.toml - No
poetry updateis called implicitly - No
poetry.lockmodifications - No
.jfrog/projects/poetry.yamlis read - Build-info is still collected when using
jf poetrywith--build-nameand--build-number - All configuration comes from Poetry's own
configand Artifactory Set Me Up
Docker Native Mode
When JFROG_RUN_NATIVE=true is set, jf docker build runs the native Docker build directly instead of the legacy JFrog build flow. Build-info is still collected when --build-name and --build-number are provided. Prerequisites: the Docker daemon must be running (docker info), a JFrog server must be configured with jf config add, and you must be logged in to the Docker registry with docker login <registry> before running these commands. For details, see jf docker.
Usage
To build and push a Docker image in Native Mode:
-
Enable Native Mode, confirm the Docker daemon is running (
docker info), and log in to the registry (docker login <registry>). -
Run build, push, and publish build-info:
export JFROG_RUN_NATIVE=true jf docker build -t <registry>/<image>:<tag> . --build-name=my-app --build-number=1 jf docker push <registry>/<image>:<tag> --build-name=my-app --build-number=1 jf rt bp my-app 1 --server-id=<your-server-id>Where:
- <registry>: Your Artifactory Docker registry host (for example,
acme.jfrog.io) - <image>: Image name (for example,
docker-local/my-app) - <tag>: Image tag (for example,
1.0.0) - <your-server-id>: The JFrog CLI server ID for
jf rt bp
For example:
export JFROG_RUN_NATIVE=true jf docker build -t acme.jfrog.io/docker-local/my-app:1.0.0 . --build-name=my-app --build-number=1 jf docker push acme.jfrog.io/docker-local/my-app:1.0.0 --build-name=my-app --build-number=1 jf rt bp my-app 1 --server-id=my-server - <registry>: Your Artifactory Docker registry host (for example,
What changes
- Docker build runs via the native Docker client (no legacy JFrog build wrapper)
- Build-info is still collected when
--build-nameand--build-numberare provided - Push, pull, and scan behave the same in both modes
Supported Client Versions
JFrog CLI (v2.92.0) is forward-compatible with modern package manager clients. The "Max Client" column represents the highest version certified for build-info collection and Native execution without schema errors.
| Package Manager | Min Client | Max Client (Certified) | Build-Info | Mode |
|---|---|---|---|---|
| Maven | 3.1.0 | 3.9.12+ (Rec: 3.9.x) | Full | Wrapped and Native |
| Gradle | 5.0 | 9.0 | Full | Wrapped and Native |
| npm | 6.x | 11.x | Full | Wrapped and Native |
| Docker | 17.07.0 | 27.x (28 with BuildX) | Full | Wrapped and Native |
| Poetry | 1.2.0 | 2.0 | Full | Wrapped and Native |
| Conan V2 | 2.0 | 2.11+ | Full | Native only |
| Helm (OCI) | 3.8.0 | 3.17 | Full | Native only |
| NuGet / .NET | Core 2.0 | .NET 9.0 | Full | Wrapped only |
| Go | 1.14 | 1.24 | Full | Wrapped only |
| pip | 20.x | 25.x | Full | Wrapped only |
| Terraform | 1.0 | 1.11 | Full | Wrapped only |
| Yarn | 1.x | 3.x | Full | Wrapped only |
Notes
- Yarn 4.x is not supported.
- Docker BuildX supports Docker engine up to v28 for multi-platform builds.
- Go
--no-fallbackdefault istrue(VCS fallback disabled by default).
When to Use Which Mode
Use Wrapped Mode when you want:
- Integrated Artifactory resolution with zero manual configuration
- Automatic build-info capture
- Managed repository configuration via JFrog CLI
- Consistent, unified behaviour across machines and CI
Use Native Mode when you need:
- Strict lockfile fidelity (no modifications to
poetry.lock,package-lock.json, etc.) - Zero modification to project metadata (
pom.xml,pyproject.toml,settings.xml, etc.) - Full compatibility with the upstream package manager's behaviour
- Builds that must be fully deterministic across environments
- Custom or advanced workflows configured directly in the package manager
Frequently Asked Questions
How do I enable Native Mode?
Set the environment variable JFROG_RUN_NATIVE=true before running any jf <tool> command. This applies to all supported tools in the current shell session. Unset it or open a new terminal to return to Wrapped Mode.
Does Native Mode still collect build-info?
Yes. When you run commands through jf <tool> with --build-name and --build-number, build-info is collected in both Wrapped and Native Mode. If you run the native tool directly (for example, npm install without the jf prefix), no build-info is collected.
Which tools support Native Mode?
Maven, Gradle, npm, Poetry, and Docker support both Wrapped and Native Mode. Helm and Conan are native-only (no wrapped mode). All other tools (Yarn, pip, Pipenv, Twine, Go, NuGet, .NET, Terraform, Ruby) operate exclusively in Wrapped Mode.
Will Native Mode modify my lockfiles or project files?
No. Native Mode never modifies poetry.lock, package-lock.json, pyproject.toml, settings.xml, or any other project file. This is the primary reason to choose Native Mode over Wrapped Mode.
Can I use Native Mode for some tools and Wrapped Mode for others?
JFROG_RUN_NATIVE=true applies to all supported tools in the session. To mix modes, set the variable only before the commands that should run natively, then unset it before wrapped commands.
How do I migrate an existing project from Wrapped Mode to Native Mode?
If you have previously run jf <tool>-config, a .jfrog/projects/<tool>.yaml file exists in your project directory. When this file is present, JFROG_RUN_NATIVE=true is currently ignored for Maven and Gradle and the CLI silently continues in Wrapped Mode.
To migrate from Wrapped Mode to Native Mode:
-
Delete the existing config file:
rm .jfrog/projects/maven.yaml # or gradle.yaml, npm.yaml, poetry.yaml -
Configure your package manager to resolve from Artifactory manually (via Artifactory Set Me Up).
-
Set the environment variable and verify the mode switch in the CLI output:
export JFROG_RUN_NATIVE=true jf mvn validate --build-name=test --build-number=1For Maven, look for
[Info] Build info saved locally. Use 'jf rt bp...' to publish.For npm, look for[Info] Running npm in native mode (JFROG_RUN_NATIVE=true).
How can I tell that Native Mode is active?
For npm, the CLI prints [Info] Running npm in native mode (JFROG_RUN_NATIVE=true) at the start of each command.
For Maven, there is currently no startup confirmation message. You can confirm Native Mode is active by checking that the build output does not contain Initializing Artifactory Build-Info Recording and does contain [Info] Collecting build info for executed command... after the build finishes.
For Gradle and Poetry, refer to the absence of injected configuration in the build output.
Note
JFROG_RUN_NATIVEis not shown injf mvn --helporjf gradle --help. This page and the FAQ are the primary discovery path for this environment variable.
Related Topics
- Build Tools Overview — Capabilities matrix and tool reference
- Native Mode — Supported packages with Native Mode
Environment Variable Reference
| Variable | Purpose | Default |
|---|---|---|
JFROG_RUN_NATIVE | Enables Native Mode for all supported tools | false (not set) |
When this variable is set to true, it applies to all commands in the current shell session. Unset it or start a new session to return to Wrapped Mode.
Updated about 1 month ago
