vix add
vix add adds or changes a Vix Registry dependency requirement for the current project or for one application module.
Use it when the application itself needs a package, or when an application module needs a registry package that should stay declared with that module.
vix add gk/jwtOverview
vix add is the command for declaring or changing a Vix Registry dependency requirement.
For a root project dependency, it resolves the package from the local registry index, updates vix.json, resolves the active project dependency graph, and updates the root vix.lock. In a modular vix.app project, --module stores the requirement in that module's vix.module instead. The application still has one root lockfile and one shared dependency graph.
This distinction keeps dependency ownership visible. A JWT package used only by auth can remain declared with auth, while Vix still resolves all active application and module requirements together from the project root.
vix add
|
+-- root dependency -> vix.json
|
+-- module dependency -> modules/<name>/vix.module
|
v
resolve active dependency requirements
|
v
root vix.lockUsage
vix add [@]namespace/name[@version]
vix add [@]namespace/name[@version] --module <name>
vix add [@]namespace/name[@version] -m <name>
vix add [@]namespace/name[@version] --module <name> --link <target>Basic examples
# Add the latest available version
vix add gk/jwt
# Add a compatible version range
vix add gk/jwt@^1.0.0
# Add an exact version
vix add gk/jwt@1.0.0
# Scoped-style syntax is supported
vix add @gk/jwt
# Scoped-style syntax with a range
vix add @gk/jwt@~1.2.0
# Add the package to a module instead of the root dependency list
vix add gk/jwt@^1.0.0 --module auth
# Override the CMake target linked by that module
vix add gk/jwt@^1.0.0 --module auth --link gk::jwtWhat it does
When you run:
vix add gk/jwt@^1.0.0Vix does this:
- Checks that the local registry index exists.
- Parses the package spec.
- Finds the package in the local registry index.
- Resolves the requested version or range.
- Builds the prospective root or module requirement state in memory.
- Resolves the active project dependency constraints.
- Fetches required package repositories at pinned commits.
- Computes package content hashes.
- Publishes the affected manifest and root
vix.lockas one project mutation. - Prints the resolved package and dependency count.
If resolution or publication fails, Vix does not leave the manifest and lockfile describing different dependency states.
Registry requirement
vix add requires the local registry index.
If the registry has not been synced, Vix reports:
registry not synced
Run: vix registry syncFix:
vix registry sync
vix add gk/jwtPackage format
A package name uses this format:
namespace/nameExamples:
gk/jwt
gk/json
gaspardkirira/treeScoped-style syntax is also accepted:
@namespace/nameExample:
@gk/jwtBoth forms point to the same package id:
gk/jwtVersion format
A package spec can include a version or version range.
vix add gk/jwt
vix add gk/jwt@1.0.0
vix add gk/jwt@^1.0.0
vix add gk/jwt@~1.2.0
vix add @gk/jwt@^1.0.0If no version is provided, Vix resolves the latest available version from the local registry index.
vix add gk/jwtIf a range is provided, Vix resolves the highest version that satisfies that range.
vix add gk/jwt@^1.0.0Supported version behavior
vix add uses semver resolution.
Supported forms include:
1.0.0
^1.0.0
~1.2.0The selected version is stored exactly in vix.lock.
For root-level dependencies, the requested version or range is stored in vix.json. For module dependencies, it is stored in the module's vix.module file.
What files are updated
Without --module, vix add updates:
vix.json
vix.lockWith --module, it updates:
modules/<name>/vix.module
vix.lockIt does not directly edit vix.app. The module must already be declared there for the generated vix.app build to treat it as part of the application graph.
There is no per-module vix.lock. Module ownership changes where the dependency requirement is declared and which module target consumes it, while exact resolution remains in the root lockfile.
Module dependencies
Use --module when a Registry package belongs to one application module.
vix add gk/jwt@^1.0.0 --module authThe requirement is stored in the module manifest.
[deps]
registry = [
"gk/jwt@^1.0.0",
]
links = [
"gk::jwt",
]If --link is omitted, Vix derives the conventional CMake target from the Registry package id. For gk/jwt, that target is:
gk::jwtUse an explicit target when the package exports a different target:
vix add gk/jwt@^1.0.0 \
--module auth \
--link gk::jwtWhen the module is active, its Registry requirement participates in the same dependency constraint analysis as root application requirements and requirements from other active modules.
The module target receives the module-owned link targets. They are not automatically attached to sibling modules or to the application target.
auth
+-- gk::jwt
billing
+-- no gk::jwt ownershipThe Registry requirement list and CMake link list represent different information. A Registry requirement identifies what must be resolved. A link entry identifies a target consumed by the module. Do not assume that the two arrays form a positional one-to-one mapping.
After adding a module dependency:
vix modules check
vix buildModule dependency constraints
Active root and module Registry requirements are analyzed together.
For example:
application -> gk/json@^1.0.0
auth -> gk/json@^1.2.0Vix selects an available version that satisfies all active compatible requirements.
If no available version can satisfy the active requirements, the operation fails instead of allowing one owner to overwrite another owner's requirement.
A disabled module can keep its Registry dependency metadata on disk. Its requirements do not constrain the active application dependency graph until the module becomes active.
Registry versus direct Git dependencies
vix add is the Registry workflow.
vix add gk/jwt@^1.0.0 --module authFor a direct Git repository, use vix install:
vix install https://github.com/gabime/spdlog \
--tag v1.15.3 \
--target spdlog::spdlog \
--module authThe Git form is stored as a structured [dependencies.<name>] entry in vix.module.
Do not use vix add as a synonym for direct Git installation.
vix.json
vix.json stores declared dependency requirements.
The current dependency format is:
{
"deps": [
{
"id": "gk/jwt",
"version": "^1.0.0"
}
]
}If the dependency already exists, vix add updates its requested version.
Example:
vix add gk/jwt@^1.0.0
vix add gk/jwt@~1.2.0After the second command, the gk/jwt entry is updated instead of duplicated.
vix.lock
vix.lock stores the exact resolved dependency state for the application.
Root and module-owned Registry requirements resolve into this same root lockfile. Vix updates it after successful dependency resolution.
Example shape:
{
"lockVersion": 1,
"dependencies": [
{
"id": "gk/jwt",
"requested": "^1.0.0",
"version": "1.2.0",
"repo": "https://github.com/...",
"tag": "v1.2.0",
"commit": "...",
"hash": "..."
}
]
}The lockfile is sorted by dependency id.
This keeps installs reproducible.
Transitive dependencies
vix add resolves the full project dependency graph.
If the package you add depends on other Vix packages, those dependencies are also resolved and written to vix.lock.
Example:
app depends on gk/http
gk/http depends on gk/jsonAfter:
vix add gk/httpvix.lock can include:
gk/http
gk/jsonThis is important because vix.lock represents the resolved project dependency state, not only the direct dependency you typed.
Package fetching
During resolution, Vix fetches package repositories into the global Git store.
Typical location:
~/.vix/store/git/A package is checked out at the pinned commit recorded by the registry.
This gives the lockfile stable fields such as:
repo
tag
commit
hashContent hash
After checkout, Vix computes a package content hash.
That hash is written into vix.lock.
The goal is to make package state verifiable and reproducible.
Output
Example output shape:
resolved: gk/jwt@1.2.0
Add
id: gk/jwt
version: 1.2.0
tag: v1.2.0
commit: 8f3a...
resolving project dependencies...
✔ added: gk/jwt@1.2.0
✔ lock: /home/user/api/vix.lock
✔ deps: 3The deps count is the number of resolved locked dependencies after the full graph resolution.
Package not found
If a package is not found, Vix searches the local registry index using the package name.
Example:
vix add gk/unknownOutput shape:
package not found: gk/unknown
Search
query: "unknown"
No matches found in the local registry index.
If you just updated the registry, run: vix registry syncIf matching packages exist, Vix prints local search results.
Invalid package spec
Valid:
vix add gk/jwt
vix add @gk/jwt
vix add gk/jwt@1.0.0
vix add @gk/jwt@^1.0.0Invalid:
vix add jwt
vix add gk
vix add @/jwt
vix add gk/jwt@If the spec is invalid, Vix reports:
invalid package spec
Expected: <namespace>/<name>[@<version>]
Example: vix add gaspardkirira/tree
Example: vix add gaspardkirira/tree@0.1.0
Try search: vix search <input>Version not found
If the requested version or range cannot be resolved, Vix reports an error.
Example:
vix add gk/jwt@99.0.0Output shape:
no version matches range: gk/jwt@99.0.0If a resolved version is missing from the registry entry, Vix can show available versions and suggest the latest version.
Add latest version
vix add gk/jwtThis resolves the latest version from the local registry index.
For a root-level dependency, the resolved exact version is stored in both vix.json and vix.lock. For a module dependency, the module manifest receives the dependency spec and the root lockfile receives the resolved exact version.
For no-version input, the requested version becomes the resolved exact version.
Example result:
{
"deps": [
{
"id": "gk/jwt",
"version": "1.2.0"
}
]
}Add a version range
vix add gk/jwt@^1.0.0For a root-level dependency, this stores the declared range in vix.json:
{
"deps": [
{
"id": "gk/jwt",
"version": "^1.0.0"
}
]
}And stores the exact resolved version in vix.lock:
{
"id": "gk/jwt",
"requested": "^1.0.0",
"version": "1.2.0"
}Add an exact version
vix add gk/jwt@1.0.0For a root-level dependency, this stores:
{
"deps": [
{
"id": "gk/jwt",
"version": "1.0.0"
}
]
}And locks:
{
"id": "gk/jwt",
"requested": "1.0.0",
"version": "1.0.0"
}Add a scoped package
vix add @gk/jwtThis is normalized to:
gk/jwtThe @ form is supported for users who prefer scoped package syntax.
After adding a dependency
After vix add, build the project.
vix buildFor development:
vix devFor validation:
vix check --testsIf the dependency exposes headers or targets, you must still use it from your project.
Using the dependency in vix.app
For root-level dependencies, vix add updates vix.json and vix.lock.
For vix.app projects, also add the package target alias to links when the application target uses the package directly. If the package belongs to a module, use vix add --module instead and keep the link target in modules/<name>/vix.module.
Example dependency:
vix add gk/json@^1.0.0Then in vix.app:
deps = [
gk/json@^1.0.0,
]
links = [
vix::vix,
gk::json,
]The registry package spec goes in:
depsThe CMake target alias goes in:
linksdeps in vix.json vs deps in vix.app
There are two places you may see dependency declarations.
vix.json is the package management manifest used by vix add, vix update, and vix install.
Example:
{
"deps": [
{
"id": "gk/json",
"version": "^1.0.0"
}
]
}vix.app is the app build manifest.
Example:
deps = [
gk/json@^1.0.0,
]The project dependency manager uses vix.json.
The app build manifest uses vix.app.
Keep them aligned when using vix.app.
Using the dependency in CMake
For a manual CMake project, include the generated dependency integration after install.
include(.vix/vix_deps.cmake)
target_link_libraries(api PRIVATE
gk::json
)A normal flow is:
vix add gk/json@^1.0.0
vix install
vix buildDifference between vix add and vix install
The commands overlap in dependency workflows, but they do different jobs.
| Command | Purpose |
|---|---|
vix add <pkg> | Add or change a Vix Registry requirement. |
vix add <pkg> --module <name> | Add or change a Registry requirement owned by one module. |
vix install | Materialize the dependency state already described by project manifests and vix.lock. |
vix install <git-url> | Add a direct Git dependency to the application. |
vix install <git-url> --module <name> | Add a direct Git dependency owned by one module. |
Use vix add when the dependency comes from the Vix Registry.
Use vix install <git-url> when the dependency is a direct Git repository.
After cloning an existing project, a normal reproducible workflow is:
vix install
vix buildDifference between vix add and vix update
| Command | Purpose |
|---|---|
vix add <pkg> | Add or change one dependency requirement. |
vix update | Re-resolve project dependencies and rewrite vix.lock. |
Use vix update when you want to refresh existing locked versions.
Difference between vix add and vix search
| Command | Purpose |
|---|---|
vix search <query> | Search the local registry index. |
vix add <pkg> | Add a package by exact registry id. |
If you do not know the exact package name, search first:
vix search jwt
vix add gk/jwtAtomic dependency updates
vix add updates project dependency metadata through one project mutation boundary.
For a root dependency, the relevant authoritative files are:
vix.json
vix.lockFor a module dependency:
modules/<name>/vix.module
vix.lockVix resolves the prospective dependency state before publishing the new metadata. If resolution, repository materialization, or metadata publication fails, the previous project state is preserved.
Project mutations are serialized so concurrent Vix commands cannot silently overwrite the same dependency metadata.
Full workflow
vix registry sync
vix search jwt
vix add gk/jwt@^1.0.0
vix install
vix build
vix testsFor development:
vix devCI workflow
After dependencies are committed:
vix registry sync
vix install
vix build --build-target all
vix testsvix add is usually not used in CI.
CI should use:
vix installbecause CI should install the exact versions from vix.lock.
Options
vix add takes one package spec. By default it writes a root dependency; with --module, it writes the dependency to a module manifest instead.
vix add [@]namespace/name[@version]
vix add [@]namespace/name[@version] --module <name>
vix add [@]namespace/name[@version] -m <name>
vix add [@]namespace/name[@version] --module <name> --link <target>| Option | Description |
|---|---|
-m, --module <name> | Add the dependency to modules/<name>/vix.module instead of the root dependency list. |
--link <target> | Set the CMake target linked by the module dependency. |
-h, --help | Show help. |
Commands reference
| Command | Description |
|---|---|
vix add gk/jwt | Add latest available version to the root dependency list. |
vix add gk/jwt@1.0.0 | Add exact version. |
vix add gk/jwt@^1.0.0 | Add compatible range. |
vix add @gk/jwt | Add using scoped-style syntax. |
vix add gk/jwt@^1.0.0 --module auth | Add the dependency to the auth module. |
vix add gk/jwt@^1.0.0 --module auth --link gk::jwt | Add the dependency to auth with an explicit CMake link target. |
Common workflows
Add latest package
vix registry sync
vix add gk/jwt
vix install
vix buildAdd compatible range
vix add gk/jwt@^1.0.0
vix install
vix check --testsAdd exact version
vix add gk/jwt@1.0.0
vix install
vix buildSearch before adding
vix search jwt
vix add gk/jwtAdd and validate
vix add gk/jwt
vix install
vix check --testsAdd a Registry package to one module
vix add gk/jwt@^1.0.0 --module auth
vix modules check
vix buildFor a direct Git dependency owned by the module, use vix install <git-url> --module auth instead.
Common mistakes
Forgetting to sync the registry
Wrong:
vix add gk/jwtwhen the registry has not been synced.
Correct:
vix registry sync
vix add gk/jwtUsing a package name without namespace
Wrong:
vix add jwtCorrect:
vix add gk/jwtExpecting vix add to update every dependency
vix add adds or changes one dependency requirement.
To refresh existing locked versions, use:
vix updateExpecting vix add to only update vix.json
vix add also rewrites vix.lock. With --module, it updates modules/<name>/vix.module instead of adding the dependency directly to vix.json.
It resolves the whole project dependency graph after updating the root manifest or the module manifest.
Expecting vix add to automatically edit vix.app
vix add updates package metadata. It does not add root vix.app link entries automatically.
For root-level vix.app dependencies, add the target alias to links when you need to link it. For module-level dependencies, use vix add --module so the link target is written to the module manifest.
Example:
links = [
vix::vix,
gk::json,
]Using vix add for a direct Git repository
vix add resolves Vix Registry package ids.
For a Registry package:
vix add gk/jwt@^1.0.0 --module authFor a direct Git repository:
vix install https://github.com/gabime/spdlog \
--tag v1.15.3 \
--target spdlog::spdlog \
--module authCreating a per-module lockfile
Do not create modules/<name>/vix.lock.
The root vix.lock is the exact dependency state for the whole application, including active module-owned dependencies.
Confusing package specs and CMake aliases
Package spec:
gk/json@^1.0.0CMake alias:
gk::jsonUse package specs in dependency declarations.
Use aliases in links or target_link_libraries.
Editing vix.lock manually
Do not manually edit vix.lock.
Use:
vix add
vix update
vix removeto change dependency state.
Troubleshooting
Registry not synced
Run:
vix registry syncThen:
vix add gk/jwtPackage not found
Search locally:
vix search jwtThen add the exact package id:
vix add gk/jwtIf the package should exist, refresh the registry:
vix registry syncInvalid package spec
Use:
namespace/name
namespace/name@version
@namespace/name
@namespace/name@versionExamples:
vix add gk/jwt
vix add @gk/jwt@^1.0.0No version matches range
If Vix reports:
no version matches range: gk/jwt@^2.0.0choose a range that exists in the registry.
Check available versions through the registry or package listing tools.
Version not found
If Vix reports that the resolved version is not found in the registry entry, sync the registry again:
vix registry syncThen retry.
Git clone failed
Vix fetches package source from the repository URL stored in the registry entry.
Check:
- network connection
- repository URL
- Git authentication if private
- registry metadata
Then retry:
vix add gk/jwtGit checkout failed
The registry entry points to a commit that could not be checked out.
This usually means registry metadata is stale or invalid.
Run:
vix registry syncIf the issue remains, the registry entry needs correction.
Add failed while resolving transitive dependencies
A transitive dependency may be missing, invalid, or impossible to resolve.
Run:
vix registry sync
vix add <package>If it still fails, inspect the dependency package’s vix.json.
Best practices
Run vix registry sync before adding Registry packages when the local index may be stale.
Use vix search when you do not know the exact Registry package id.
Use version ranges when compatible updates are acceptable. Use exact versions when the project requires an exact declared requirement.
Keep dependencies owned by the narrowest appropriate scope. If only auth needs a Registry package, prefer:
vix add gk/jwt@^1.0.0 --module authDo not create per-module lockfiles or caches.
Commit the dependency manifests and root vix.lock.
Do not edit vix.lock manually.
Run module checks after changing module-owned dependencies:
vix modules check
vix buildUse vix install <git-url> for direct Git dependencies rather than treating Git repositories as Registry package ids.
Related commands
| Command | Purpose |
|---|---|
vix search | Search the local Registry index. |
vix install | Materialize locked dependencies or add a direct Git dependency. |
vix modules | Manage and validate application modules. |
vix update | Re-resolve Registry dependency versions. |
vix outdated | Check outdated Registry dependencies. |
vix remove | Remove dependencies. |
vix list | List dependency state. |
vix registry sync | Refresh the local Registry index. |
vix build | Build after dependency changes. |
vix tests | Run tests after dependency changes. |
Next step
Install locked dependencies.