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
allowUnfreeand keeps the list sorted - Only records the exception — run
flk add vscodeto 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 this | Not this |
|---|---|
vscode | pkgs.vscode |
google-chrome | google-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.