Logo

dev-resources.site

for different kinds of informations.

Nix first steps

Published at
9/4/2024
Categories
nix
nixos
devex
Author
alexander_shagov
Categories
3 categories in total
nix
open
nixos
open
devex
open
Author
16 person written this
alexander_shagov
open
Nix first steps

It might be overwhelming to dive into the Nix world, but this little glossary should help refine your understanding of the tools you might encounter when starting your journey.

UPD: I wrote one more short article to articulate why I prefer nix over non-nix setups in general: https://dev.to/alexander_shagov/why-use-nix-even-on-macos-786


Nix Package Manager ā€“ The core tool that allows declarative and reproducible package management.

NixOS ā€“ A Linux distribution built entirely on the Nix package manager. It's better to start with nix package manager alone before switching to NixOS completely.

Home Manager ā€“ Manages user packages, dotfiles, environment variables, shell configurations, and more. Allows for portable user environments across different machines.

Flakes ā€“ Provides a standardized structure for Nix projects, improving reproducibility and composability. It's worth noting that while Flakes are still technically experimental, they have been widely adopted by the Nix community due to their benefits. Many newer Nix configurations and projects are built using Flakes.


Old flow vs New flow

When you start searching for actual commands, you might encounter that some of them have different syntax (e.g., 'nix build' vs 'nix-build').

https://nixos-and-flakes.thiscute.world/nixos-with-flakes/introduction-to-flakes

Based on the article, there are two "flows" or approaches to using Nix: the old (or classic) flow and the new flow using flakes.

New Flow (Flakes and New CLI):

  • Introduces flake.nix and flake.lock files.

  • Uses new CLI commands that start with "nix" (e.g., nix develop, nix shell, nix build).

  • Replaces channels with explicit inputs in flake.nix.

  • Aims for improved reproducibility and composability.

Old Flow (Classic Nix):

  • Used commands like nix-channel, nix-env, nix-shell, and nix-build.

  • Relied on channels for package management.

  • Less standardized structure for Nix projects.

  • Could lead to less reproducible builds in some cases.

The new flow is essentially an evolution of Nix, addressing some limitations of the classic approach and borrowing ideas from other modern package managers (like npm, Cargo, etc.).

Assuming you're not using NixOS itself but, let's say, macOS, your flow of working with your development environment might look like this:

1) Use home-manager (preferably with flakes) to manage user-specific packages, tools, and configurations. This includes system-wide tools like Emacs, as well as dotfiles and environment settings.

2) For each project you're working on, create a flake.nix file to define the project-specific development environment and dependencies.


The aim of the article was to provide a good starting point and set up the mental model for further readings. Even though I didn't set a goal to share specific code snippets, here's the example of a home-manager (home.nix) file defining the global configuration on my MacOS. This configuration defines the global state of my system. Any project-related pieces live a in separate flake.nix files in their own namespaces. NOTE: I'm not using brew anyhow!


{ config, pkgs, ... }:

{
  home.username = "<username>";
  home.homeDirectory = "<homeDirectory>";

  home.stateVersion = "24.05";

  home.packages = with pkgs; [
    direnv
    ripgrep
    htop
    inetutils
    jq
    emacs29
    emacsPackages.vterm
  ];

  home.shellAliases = {
    # ============ git aliases =====================
    gs = "git status";
    gcm = "git checkout main && git pull";
    gc = "git checkout";
  };

  home.sessionVariables = {
    EDITOR = "emacs";
  };

  # ======== Zsh configuration ============

  programs.zsh = {
    enable = true; # Enable managing the Zsh configuration

    initExtra = ''

      # Private ENV vars configuration
      if [ -f ~/.bashrc_private ]; then
        . ~/.bashrc_private
      fi    

      # ========= Prompt with a branch ========
      function git_branch_name() {
           git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '='
      }
      autoload -Uz colors && colors
      setopt prompt_subst
      prompt='%F{yellow}%~/%f [%F{green}$(git_branch_name)%f] > '

    '';
  };

  programs.direnv = {
    enable = true;
    # enableBashIntegration = true; # see note on other shells below
    nix-direnv.enable = true;
  };

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
}
Enter fullscreen mode Exit fullscreen mode

Any time I need to add/remove system-wide package, or adjust, let's say, zsh configuration, it just boils down to editing the home.nix file and running the home-manager switch to apply the change (or home-manager build to see if a build compiles correctly).


Where to look for packages

Given you want to install htop. Just use the search.nixos.org and put the package name into your home.nix file. Run home-manager switch and you'll have your htop configured automatically (e.g. /Users/<username>/.nix-profile/bin/htop)

How to install a specific version of a package?

If you want to install a specific version of a package (not the latest one by default), you can search at nixhub.io. There, you'll see a specific Nixpkgs Reference you should use in your home.nix file to point to a specific version you're interested in.


Useful links for further reading


ā­ Comments and more useful articles for nix beginners appreciated!

devex Article's
30 articles in total
Favicon
Designing for developers means designing for LLMs too
Favicon
Why Duplicating Environments for Microservices Backfires
Favicon
Rely.io Update Roundup - December 2024
Favicon
Orchestrating Distributed Apps (Spin/Rust and .NET/C#) with .NET Aspire/Dapr
Favicon
Developer Self-Service with Resourcely
Favicon
Why does improving Engineering Performance feel broken?
Favicon
Top Backstage alternatives
Favicon
Shifting End-to-End Testing Left on Microservices
Favicon
Observability 2.0: Rethinking Debugging
Favicon
Fix Your Foundation: Developer Experience
Favicon
Shifting Testing Left: The Request Isolation Solution
Favicon
A developer's perspective on time-based estimates
Favicon
What is Engineering Enablement (And Why it Matters)
Favicon
Shift Left on a Budget: Cost-Savvy Testing for Microservices
Favicon
Our Gitlab journey. Migrating from Docker+Machine to Kubernetes
Favicon
How to Understand and Improve Your Developer Experience
Favicon
Improving Tinybird DevEx šŸš€ Data Re-Population CLI Tool
Favicon
Improving Tinybird DevEx šŸš€ Creating an Informative CLI Prompt with Oh My Posh
Favicon
Are You Delivering on Developer Experience?
Favicon
Illuminate Collections vs. PHP Arrays
Favicon
Spring Boot DevTools: Speeding Up Development with Hot Reloads
Favicon
How to Diagnose Flaky Tests
Favicon
Limitations in Measuring Platform Engineering with DORA Metrics
Favicon
7 Reasons Why Developer Experience Is a Strategic Priority
Favicon
Transforming DevEx Through Bulk Refactoring (and How AI Can Assist)
Favicon
Why Use Nix package manager, Even on macOS?
Favicon
How to Be an Effective Platform Engineering Team
Favicon
How to Do DORA Metrics Right
Favicon
Nix first steps
Favicon
The DevRel Digest August 2024: Choose Your Own Adventure Documentation

Featured ones: