Connect

Blog / News

Sometimes You Just Need jq

Stephen Yeargin

A dev environment for platform work might include jq, Kubernetes tools, cloud CLIs, and dozens of other packages. But sometimes you just need to run jq... without bringing an entire dev environment along with it. The same goes for working with secrets: You should be able to declare your provider, define your config, and have secrets-retrieval just work. You shouldn’t have to build integration logic from scratch.

Flox now gives you both. With the new flox run subcommand, you can invoke jq at any time just by doing flox run jq. Flox now ships pre-built secrets integrations built on the experimental environment-plugin capability we introduced in Flox v1.14.

Run Flox, Run

We built flox run to make it easier to experiment with a new software package without first creating a Flox environment from scratch. The flox run subcommand is also helpful when you need to run a particular package just once, but don’t want to add it to an environment… only to have to take it out later.

The flox run subcommand finds the package that provides the requested program and runs it without requiring you to create or modify a Flox environment.

Let’s say I wanted to try out the hello demo package. The classic pattern involves creating a Flox environment, installing hello, and activating the environment.

This workflow looks like:

$ flox init
⚡︎ Created environment 'demo' (aarch64-darwin)
 
Next:
  $ flox search <package>    <- Search for a package
  $ flox install <package>   <- Install a package into an environment
  $ flox activate            <- Enter the environment
  $ flox edit                <- Add environment variables and shell hooks
  $ flox push                <- Use the environment from other machines or
                                share it with someone on FloxHub
 
> Auto-activate the environment in '/tmp/demo'? No
ℹ Disabled auto-activation for the environment.
Run 'flox activate allow --dir <PATH>' to re-enable.

This initializes the environment; the next step is to imperatively install hello

$ flox install hello
✔ 'hello' installed to environment 'demo'

… or use flox edit to declaratively add it to the environment’s manifest:

schema-version = "1.16.0"
 
[install]
hello.pkg-path = "hello"

Only then can you actually run the hello command:

$ flox activate
✔ You are now using the environment 'demo'
To stop using this environment, run 'flox deactivate'
 
flox [demo default] % hello
Hello, world!

Why Not Just flox run It?

That’s a lot of steps to get “Hello world!” in your terminal. Flox is great for sharing the same setup across a team; now we've made it easier to try out the commands packages expose without creating any environment setup.

Because some packages provide programs with the same names, we also added the ability to select the one you want:

$ flox run hello
! Multiple packages provide 'hello'. Select one to run:
> haskellPackages.hello
  hello
  tests.haskell.ghcWithPackages.hello
  fyne
  mbedtls
  mbedtls_2
v polarssl
[Showing 10 of 16 results. Use 'flox search --command hello --all' to see the full list.]
 
$ flox run hello
> Multiple packages provide 'hello'. Select one to run: hello
✔ Saved 'hello' as the package to run for 'hello'
Run 'flox run --reselect hello' to choose another package.
 
Hello, world!
 
$ flox run hello
Hello, world!

So what exactly did we build? Basically, we now index the commands provided by all free packages in nixpkgs: i.e., those with unencumbered open source licenses. You can discover these for yourself in FloxHub by searching for a package, selecting a specific version, and clicking the “Outputs” tab. The screenshot below shows that hello has a single command: hello.

We also added a special --command flag to flox search so that you can find what you’re looking for without leaving the CLI:

$ flox search --command hello
16 packages provide 'hello' — 3 exact matches (*):
  * hello        (haskellPackages.hello)
  * hello        (hello)
  * hello        (tests.haskell.ghcWithPackages.hello)
    fyne         (fyne)
    mbedtls      (mbedtls)
    mbedtls_2    (mbedtls_2)
    polarssl     (polarssl)
    allowPkgsInPermittedInsecurePackages (tests.config.allowPkgsInPermittedInsecurePackages)
    helloFromCabalSdist (tests.haskell.cabalSdist.helloFromCabalSdist)
    install-bin  (tests.install-shell-files.install-bin)
 
ℹ There are 16 packages that supply 'hello'.
Use 'flox search --command hello --all' or
'flox run --package <PACKAGE> hello' to choose a specific package.

When more than one package provides a command with the same name, we save your selection so you don’t have to choose again. We store this as a simple command-to-package attribute in ~/.config/flox/flox.toml, Flox’s standard user-scoped configuration file.

# The rest of your configuration
 
[run_preferences]
hello = "hello"

If you want Flox to use a different package for a given command later, use the --reselect flag.

$ flox run --reselect python
! Multiple packages provide 'python'. Select one to run:
> buildbotPackages.python
  gnuradio3_8Packages.python
  gnuradio3_9Packages.python
  gnuradioPackages.python
  mopidyPackages.python
  python310Packages.python
v python311Packages.python
[Showing 10 of 44 results. Use 'flox search --command python --all' to see the full list.]

You can also use the --package / -p flag to specify which package should provide the command you want to run. This is especially useful in non-interactive environments such as CI, where Flox can’t prompt you to choose between multiple matches.

$ flox run -p python312 -- python hello.py
Hello world, but from python!

You can use flox run with the more than 225,000 packages available in the Flox base catalog. This includes packages that aren’t returned with flox search --command <package_name>, such as unfree packages, or custom packages you publish to your private Flox catalog. For example, to run 1Password’s unfree op command, specify the _1password package explicitly, along with op:

$ flox run -p _1password -- op whoami
URL:        https://my.1password.com/
Email:      hello@flox.dev
User ID:    ABCDEF123456789

Integrating Secrets Providers Without the Glue

Flox now ships pre-built secrets plugins for common secret providers, including 1Password and HashiCorp Vault. To be clear, Flox is not providing a secret store or persisting secret values itself. Instead, these secrets plugins give Flox environments a standard way to declare references to secrets held by upstream providers. At activation, the plugin retrieves secrets from the provider and exports them into the active environment.

Just-in-time secrets retrieval has always been possible with Flox. Over time we added the ability to build, package, and publish custom secrets-handling integrations to your private Flox Catalog. You could define these integrations as packages in your Flox environments and call them from an activation hook. So even though Flox could package the secrets-handling logic, you still had to wire it into each environment yourself.

Plugins correct this. They define a standard interface in the Flox manifest (a [plugins.<provider_name>] section) along with an activation path for that packaged logic.

This standardizes both how an environment plugin’s packaged logic gets invoked and where environments declare the plugin’s config. For example, users of HashiCorp Vault can declare the Flox-provided Vault plugin in their manifests…

[install]
plugin-vault.pkg-path = "flox/plugin-vault"

…along with the secret references the plugin expects to resolve under the [plugins.<name>] section:

[plugins.vault]
GH_TOKEN = "secret/github-work#token"

The secrets plugin packages shipped by Flox bundle both the retrieval logic and the secrets provider’s CLI.

Flox currently provides secrets plugins for:

  • flox/plugin-1password. Run with op.
  • flox/plugin-vault. Run with vault.
  • flox/plugin-openbao. Run with bao.
  • flox/plugin-infisical. Run with infisical.

Just the Right Touch of Flox

A reproducible environment is essential when the environment itself is what matters. It’s a bit heavy when you only need to run jq or ripgrep. Integrating secrets is a related problem: the environment absolutely matters, but integration machinery can be standardized and reused across environments.

A one-off command should feel like a one-off command. That’s flox run. A secrets integration should feel like configuration, not an exercise in wiring up a harness. That’s Flox’s pre-built secrets plugins.

Download Flox and use flox run to test drive one of 225,000+ packages.