Skip to content

packageOverrides

Overview

packageOverrides is the older nixpkgs global configuration hook for reshaping the package set. You set a function pkgs: { … } that returns attribute overrides and new packages—similar in spirit to an overlay, but as a single layer wired through config rather than a composable list.

The mechanism predates overlays and still appears in the Nixpkgs manual under Global configuration. For new work, prefer overlays: they stack in order, expose both final and prev, and are easier to share across flakes, NixOS, and user config. packageOverrides is not documented as removed—treat it as a legacy alternative you may still encounter in older configs and wiki examples.

Details

Where it lives. The usual entry point is ~/.config/nixpkgs/config.nix:

{
  packageOverrides = pkgs: {
    # overrides and new attrs
  };
}

The same attribute can be passed when importing nixpkgs: import <nixpkgs> { config.packageOverrides = pkgs: { … }; }. Nixpkgs merges user config from ~/.config/nixpkgs/config.nix (and legacy ~/.nixpkgs/config.nix) unless you override config at import time—see the manual’s Global configuration chapter.

Shape. The function takes one argument—the current pkgs set—and returns a set of attribute overrides, much like pkgs/top-level/all-packages.nix. Inside, you typically call .override or .overrideAttrs on existing packages (see Overlay vs Override for package-level overrides). You can also add new top-level attributes (for example a custom buildEnv bundle).

Relation to overlays. The manual states that packageOverrides acts as an overlay with only the prev argument—you see the package set before your changes, not the fully composed final set. That limits patterns where a new package must depend on another override in the same layer. Overlays apply in list order and are the standard way to compose multiple customization layers; see Installing overlays and Writing Overlays.

When it still shows up.

Situation Notes
Personal config.nix from pre-overlay workflows Often a single packageOverrides block
Declarative “my packages” envs in config Manual Build an environment examples use packageOverrides with buildEnv
Reading older blogs or configs May use packageOverrides where overlays are used today

Not the same name everywhere. Some language scopes (Python, Lua, PHP, and others) expose their own packageOverrides argument on the interpreter or package set. Those are scoped customization hooks, not the global nixpkgs config.packageOverrides described here.

Prefer overlays when you can. If you might add a second layer, share customization via a flake input, or need final for cross-references within the same overlay, use Writing Overlays instead of growing one monolithic packageOverrides function. Pinning nixpkgs and layering overlays is the usual modern project layout; global packageOverrides in config.nix affects user-level commands like nix-env and nix-shell that read that config.

Examples

Override one package in config.nix.

{
  packageOverrides = pkgs: {
    hello = pkgs.hello.overrideAttrs (old: {
      pname = old.pname + "-patched";
    });
  };
}

Same change as an overlay (preferred for composability).

final: prev: {
  hello = prev.hello.overrideAttrs (old: {
    pname = old.pname + "-patched";
  });
}

Pass that function in overlays = [ … ] when importing nixpkgs, via nixpkgs.overlays on NixOS, or under ~/.config/nixpkgs/overlays/—details in Writing Overlays.

Explicit import with config.

import <nixpkgs> {
  config.packageOverrides = pkgs: {
    jq = pkgs.jq.overrideAttrs (old: {
      patches = (old.patches or [ ]) ++ [ ./jq-local.patch ];
    });
  };
}

References

See also