- docs
- Packages
- Run a command with its dependencies
Run a command with its dependencies
Use this page to run a tool together with the tools it depends on, and to inspect the dependency tree.
Pull and run
Section titled “Pull and run”A publisher can declare that a package needs other packages to work. A web app needs a JavaScript runtime. A build tool needs a compiler. The publisher pins each dependency to an exact OCI digest. OCX handles dependencies for you.
Pull the package, and OCX resolves the closure transitively:
ocx package pull "acme/webapp:2.0.0"Say acme/webapp:2.0 declares dependencies on nodejs/node:24 and oven-sh/bun:1.3. All three packages land in the package store. Only acme/webapp:2.0 is the explicit install. The dependencies are stored but do not show up as top-level installs.
To run the package with its dependency environments configured, use ocx package exec:
ocx package exec "acme/webapp:2.0.0" -- serve --versionocx package exec first composes the environments of all dependencies in topological order. Then it launches the command. ocx package env exports the same composed environment for use in your own shell.
Run several packages together
Section titled “Run several packages together”Name more than one package before -- to run a command with all their environments composed. A dependency that two roots share is emitted once, as composition order describes:
ocx package exec "nodejs/node:24.0.0" "oven-sh/bun:1.3.0" -- bun --versionThis puts Node.js and Bun on PATH for the one bun --version command. ocx package env takes the same list when you need the variables in your own shell.
Inspecting the dependency tree
Section titled “Inspecting the dependency tree”ocx package deps shows the declared relationships. The default tree view annotates non-public dependencies, so you can see which deps cross the interface surface:
--flat shows the resolved evaluation order, which is the exact sequence OCX uses when it composes environments. This is the primary debugging tool when environment variables are not what you expect:
--why traces the path from a root package to a transitive dependency:
Conflict warnings
Section titled “Conflict warnings”Two dependencies may set the same scalar variable, for example both set JAVA_HOME to different paths. OCX applies last-writer-wins semantics: the package later in topological order wins, silently. Inspect the order with ocx package deps --flat and decide whether the conflict is real.
Project toolchains behave the same way. Suppose you add a package with dependencies and also declare one of those dependencies as a top-level binding in ocx.toml. Both contribute environment variables. Either remove the redundant binding, because the transitive dependency provides it, or accept that the top-level entry’s value wins the conflict.