---
title: "A Nix flake for opting out of telemetry"
description: "Every tool and application manages telemetry differently. I set up a Nix flake to let me opt out across all my devices."
date: 2026-02-21
tags: ["Nix","Home Manager","Telemetry","Flake"]
url: https://adampie.dev/a-nix-flake-for-opting-out-of-telemetry/
---

# A Nix flake for opting out of telemetry

---

Over the past couple of years, I've migrated my configs, preferences, and dotfiles over to Nix and home-manager. This has been great as it lets me wipe my devices on a semi-regular basis without having to go through the manual process of reconfiguring everything. Being able to manage multiple personal and work devices, having them all set up the same greatly helps in reducing cognitive load when switching machines.

Before Nix, one thing that I would always try to do, but occasionally forgot, was to turn off telemetry for the tools and applications I was installing. Each one of these bits of software had its own way to disable telemetry, or even did not give you a way to opt out. At work, from time to time, I need to work on confidential or restricted systems and data; ensuring nothing is transmitted by accident is a must. The only way I could be confident I had configured things correctly was if it was managed with code, which is why I've set up [`adampie/opt-out`](https://github.com/adampie/opt-out).

## How opt-out works 

Tools and applications normally give you a way to opt out of telemetry with either environment variables, CLI commands, or settings in-app or defined in config files. The most popular method in the current list I've reviewed is environment variables, which makes it much more convenient for us to configure across all devices.

Using the dendritic pattern (every file is a module) and [`import-tree`](https://github.com/vic/import-tree) we can dynamically include the tools that support opting out of telemetry. This lets us track things over time, and from what I've seen so far, telemetry always gets added but never gets removed. Currently, tools without telemetry or an opt-out option have file names prefixed with an underscore ('_'), as 'import-tree' ignores these files.

### What Nix files look like

Here is the configuration for `tools/github-cli.nix`. 

```nix
{
  name = "github-cli";
  meta = {
    description = "GitHub's official command line tool";
    homepage = "https://github.com/cli/cli";
    documentation = "https://cli.github.com/telemetry";
    lastChecked = "2026-08-01";
    hasTelemetry = true;
  };
  variables = {
    GH_TELEMETRY = "false";
  };
  commands = {
    disable = "gh config set telemetry disabled";
  };
  config = { };
}
```

In the future, I might look into using the commands and wrapping them in an `activationScript`, but to keep things simple, the flake exports the environment variables. As each file is a module, we can target a single tool, e.g. `inputs.opt-out.darwinModules.hashicorp` or we can pull in all the environment variables.

- Home Manager -> `home.sessionVariables`
- nix-darwin -> `environment.variables`
- NixOS -> `environment.sessionVariables`

## How opt-out keeps things up to date

Before working on this flake, I was manually reading documentation to find how to opt-out of telemetry. Now with LLMs and a simple harness, it's possible to have a [Skill](https://github.com/adampie/opt-out/blob/main/.claude/skills/add-tool/SKILL.md) to drive the onboarding of new tools and validation of existing ones.

As documentation occasionally drifts from reality, the skill ends up checking the source code if available. When dealing with closed-source tools, I've observed the LLM use 'strings' to determine if the binary references the environment variable.
