Skip to content

Nix-flakes and Bun

Posted on:June 30, 2024 at 02:09 PM

Since taking up some extra cyber security and hacking courses I have been focusing on more Linux development. As a result I have picked up NixOS and as a JavaScript developer I have to say I have fallen in love with the declarative nature of my environment on NixOS. It has been a blast working on building VMs and my own cluster out of NixOS configurations from scratch. I have also moved my spare laptop over to NixOS and have been daily driving it in lieu of my M2 Macbook Air.

Developing with NixOS

Many developers will notice that this blog is built with Astro.js and Bun.js so let’s talk about my development experience adding flakes to this project and getting it up and running on my NixOS machine.

Setting up my Development Environment

Using flakes it can be overwhelming to know where to start. Luckily they provide a simple way to get started. By running the command:

nix flake init

You will get a new file called flake.nix which just like package.json is declarative and tells the OS what tools and their versions are needed for development. I went ahead and replace the default flake.nix with the following.

{
  description = "Basic flake for Astro.js and Bun.js project";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

    outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
      in
      {
        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [
            bun
            nodejs
          ];

          shellHook = ''
            echo "Astro.js with Bun.js development environment"
            echo "Run 'bun create astro' to create a new Astro project"
          '';
        };
      });
}

Cool right? It’s not super crazy and is decently readable. Notice the file extension .nix as you can see NixOS comes with its own DSP for declarative configuration. To learn more about the syntax visit this page about the Nix DSP.

Description

description = "Basic flake for Astro.js and Bun.js project";

Purpose: Provides a brief description of what the flake is for. This description is shown when you run commands like nix flake metadata.

Inputs

This part of the configuration declares the needed dependancies for the flake.

inputs = {
  nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  flake-utils.url = "github:numtide/flake-utils";
};

I grabbed these two main dependancies:

These are two of the most common deps you will see in most flakes.

Outputs

outputs = { self, nixpkgs, flake-utils }:
  flake-utils.lib.eachDefaultSystem (system:
    let
      pkgs = nixpkgs.legacyPackages.${system};
    in
    {
      devShells.default = pkgs.mkShell {
        buildInputs = with pkgs; [
          bun
          nodejs
        ];

        shellHook = ''
          echo "Astro.js with Bun.js development environment"
          echo "Run 'bun create astro' to create a new Astro project"
        '';
      };
    });

Outputs define what the flake produces. The outputs function takes the inputs (self, nixpkgs, and flake-utils) and returns an attribute set. Here, we use flake-utils.lib.eachDefaultSystem to create outputs for each supported system (e.g., x86_64-linux, aarch64-linux).

    let
      pkgs = nixpkgs.legacyPackages.${system};
    in

Purpose: Defines a local variable pkgs that refers to the Nix packages for the current system.

devShells.default = pkgs.mkShell {
  buildInputs = with pkgs; [
    bun
    nodejs
  ];

  shellHook = ''
    echo "Astro.js with Bun.js development environment"
    echo "Run 'bun create astro' to create a new Astro project"
  '';
};

Purpose: Creates a development shell environment. This is useful for setting up a consistent development environment.

This setup ensures that anyone using this flake will have a consistent development environment with the necessary tools for working on an Astro.js project using Bun.js. Now it doesn’t matter where in the world or what hardware you are using as long as it is able to run flakes and access the internet to grab the deps needed for the dev environment it will work and run.