Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

flk unfree

Nix refuses to evaluate packages with an unfree license by default, so adding something like vscode, slack, or terraform to a profile fails with “has an unfree license, refusing to evaluate”.

flk unfree records the exception as an explicit allow-list of package names. flk turns that list into a nixpkgs.config.allowUnfreePredicate, so only the packages you name are exempt — everything else still gets the default refusal and an unfree dependency can never slip in unnoticed.

Scope

An unfree exception belongs to the profile that needs it, so the list normally lives in the profile file, next to the package it covers:

# .flk/profiles/rust.nix
{pkgs, ...}: {
  allowUnfree = ["terraform"];

  packages = [
    pkgs.terraform
  ];
}

Like flk add, a bare invocation targets the current or default profile, and -p picks another:

flk unfree add terraform            # -> default profile
flk unfree add terraform -p rust    # -> .flk/profiles/rust.nix

Use --all for an exception that should apply to every profile. That list lives in .flk/config.nix:

flk unfree add vscode --all
# .flk/config.nix
{
  defaultProfile = "rust";
  maxCombinations = 3;
  allowUnfree = ["vscode"];
}

The two are merged at evaluation time: a profile shell allows the environment-wide list plus its own. A combination shell (rust-node) allows the union of its members, because each profile is evaluated against its own package set.

Subcommands

flk unfree add

Allow an unfree package.

flk unfree add vscode
flk unfree add terraform --profile rust
flk unfree add slack --all

Options

  • -p, --profile <NAME>: Target profile. Defaults to the current or default profile
  • --all: Write the environment-wide list instead. Conflicts with --profile

Behavior

  • Appends the name to allowUnfree and keeps the list sorted
  • Only records the exception — run flk add vscode to actually install it
  • Re-adding an already-allowed package is a no-op
  • Fails if the target profile does not exist, rather than creating it

flk unfree remove

Stop allowing an unfree package.

flk unfree remove vscode
flk unfree remove slack --all

Behavior

  • Fails if the package is not in the target’s list, rather than silently doing nothing
  • Removes only from the target — a package allowed both environment-wide and in a profile must be removed from each
  • Does not remove the package from your profiles — use flk remove

flk unfree list

Show what is allowed.

flk unfree list             # environment-wide + default profile
flk unfree list -p rust     # environment-wide + the rust profile
flk unfree list --all       # environment-wide only

Both lists are shown by default because evaluation merges them — seeing one alone would misreport what the shell actually allows.

Package names

Entries are package names as reported by lib.getName, not attribute paths and not versioned store names:

Write thisNot this
vscodepkgs.vscode
google-chromegoogle-chrome-131.0.6778.85

When Nix refuses a package it prints the name it used — the quoted name in “Refusing to evaluate package ‘slack-4.49.89’” is slack.

Global environment

The same subcommands work on the machine-wide environment, including profile targeting:

flk global unfree add slack
flk global unfree add slack -p cli-tools
flk global unfree list

Applying the change

The allow-list is part of the environment definition, so an already-open shell keeps the old one. Reload it:

refresh

or

refresh -g #for global environment

Why a list instead of allowUnfree = true

A blanket allowUnfree = true silently exempts every current and future dependency of your environment. The list form keeps each exception visible in the profile or config file, and in code review.

If you hand-write allowUnfree = true;, flk honors it at evaluation time but refuses to manage it — flk unfree add will tell you to switch back to the list form first. A true in either the environment-wide list or a profile wins for that profile.

Known limitation: pinned packages on the legacy layout

On the slim layout (the flk init default), the allow-list also covers version-pinned packages from .flk/pins.nix.

The legacy in-repo driver resolves pins through .flk/overlays.nix, which predates unfree support and does not receive the config. Unfree pinned packages therefore still fail there. Run flk migrate to move to the slim layout. Profile-scoped and environment-wide lists both work on the legacy layout for unpinned packages.