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.
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 1The resulting build-info for build my-app #1 contains two modules (backend and frontend), each with their own dependency trees.
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.
--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-teamWrapped 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 (e.g., 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, pnpm, 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.
Usage
export JFROG_RUN_NATIVE=true
jf mvn clean install --build-name=my-app --build-number=1What changes
- No
settings.xmlinjection - No
.jfrog/projects/maven.yamlis read - Build-info is still collected when
--build-nameand--build-numberare provided - 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 include applying the Artifactory Gradle plugin and configuring repository URLs and credentials in your build script or gradle.properties.
Usage
export JFROG_RUN_NATIVE=true
jf gradle clean build --server-id=my-serverNote: In Gradle Native Mode, pass
--server-idto specify which configured server to use. Without it, the CLI uses the default server.
What changes
- No Artifactory Gradle plugin injection
- No
.jfrog/projects/gradle.yamlis read - 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.
Usage
export JFROG_RUN_NATIVE=true
# Install
jf npm install --build-name=my-app --build-number=1
# Publish
jf npm publish --build-name=my-app --build-number=1What 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.
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.
Usage
export JFROG_RUN_NATIVE=true
# Install with build-info collection
jf poetry install --build-name=my-app --build-number=1
# Or install directly (no build-info)
poetry install
# Publish with build-info collection
jf poetry publish --build-name=my-app --build-number=1
# Or publish directly (no build-info)
poetry build
poetry publish -r artifactoryNote: 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. A server must be configured with jf config add and you must be logged in to the Docker registry before using Docker Native Mode. For details, see jf docker.
Usage
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 1What 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 |
| pnpm | 6.x | — | — | Config only |
Notes:
- Yarn 4.x is not supported.
- pnpm has config-only support; no
jf pnpmrun command; no build-info collection.- 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 (e.g., 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, pnpm, 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.
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 8 days ago
