Skip to content
Open
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
103 changes: 103 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,104 @@
# Nix flake development environment example

> **Warning**: [Nix flakes][flakes] are an experimental feature in [Nix]. Flakes
> will eventually become the de facto standard way to use Nix and thus you may
> find it worthwhile to learn how to use them. But beware that there may be
> breaking changes in the user interface around flakes.
This repo provides an example [Nix flake][flakes] that outputs a reproducible Nix
[development environment][env] that works across [several systems][systems].

## Prerequisites

In order to use this starter template, you need to have [Nix installed][install]
and [flakes enabled][enable].

## Explore this flake

To see what this flake provides:

```shell
nix flake show
```

### System support

As you can see, this flake outputs `default` development environments
(`devShells`) for a variety of architectures:

- `aarch64-darwin` (macOS on Apple Silicon)
- `aarch64-linux` (Linux on ARM64)
- `x86_64-darwin` (macOS on AMD/Intel)
- `x86_64-linux` (Linux on AMD/Intel)

## Using the environment

There are two ways to use the [Nix development environment][env] provided in
this flake:

1. You can clone this repo and run `nix develop` inside of it:

```shell
git clone https://github.com/nix-dot-dev/nix-flake-example
cd nix-flake-example
nix develop
```

> **Note**: If you have [direnv] installed, you can also enter this
> flake-provided development environment by running `direnv allow`. Once
> you've done that, you will automatically enter the environment every time
> you navigate to this directory.
2. You can run `nix develop` and provide the flake reference to this repo:

```shell
nix develop github:nix-dot-dev/nix-flake-example
```

This will likely take some time, as Nix needs to download [Nixpkgs] and then
install the tools provided in the environment. Once that's finished, you should
be greeted by a welcome message and then enter a [Bash] shell with a `bash-5.1$`
prompt.

This dev environment provides several tools:

- [Node.js]
- [Python]
- [Go]
- [Terraform]

You can see that these tools are installed in your local [Nix store][store] by
running commands like these:

```shell
which node
which npm
which python
which go
```

In all cases, you should see paths of this form:

```shell
/nix/store/${LONG_HASH}-${PACKAGE_NAME}/bin/${EXECUTABLE_NAME}
```

That means that if you run `node`, `npm`, `python`, and so on you'll use
versions of those tools in the Nix store and _not_ versions installed in
directories like `/usr/bin`.

[bash]: https://gnu.org/software/bash
[direnv]: https://direnv.net
[enable]: https://nixos.wiki/wiki/Flakes#Enable_flakes
[env]: https://nixos.org/explore
[flakes]: https://nixos.wiki/wiki/Flakes
[go]: https://go.dev
[install]: https://nixos.org/download
[nix]: https://nixos.org
[nix.dev]: https://nix.dev
[nixpkgs]: https://github.com/NixOS/nixpkgs
[node.js]: https://nodejs.org
[python]: https://python.org
[store]: https://nixos.org/manual/nix/stable/command-ref/nix-store
[systems]: #system-support
[terraform]: https://terraform.io
42 changes: 42 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 79 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
# If you wish, you can provide flakes with a description string. This string is
# shown if you run `nix flake show` to get information about the flake. To see
# this description string, run this command:
# `nix flake show github:nix-dot-dev/nix-flake-example`
description = "nix.dev starter template for Nix flakes";

# Flake inputs are Nix code dependencies. What you don't see here in
# `flake.nix` is that each of these inputs has an entry in `flake.lock` that
# "pins" the input to a specific revision. This makes `flake.nix` and
# `flake.lock` inseparable. With flakes, the pinning mechanism previously
# provided by tools like Niv is built in.
inputs = {
# Nixpkgs is by far the largest Nix codebase in the world, providing tens of
# thousands of packages and utilities for the Nix language. Here, we
# essentially import Nixpkgs using a flake reference. `github` is the prefix
# for GitHub repos, but other prefixes include `gitlab` for GitLab repos,
# `path` for directories in the local filesystem, and more.
nixpkgs.url = "github:NixOS/nixpkgs";

flake-utils.url = "github:numtide/flake-utils";

# Although Nixpkgs and flake-utils are extremely common, you can use any
# valid flake as an input.
};

# Outputs are what the flake provides (packages, NixOS configurations, dev
# environments, and more). Flakes *must* have outputs or else they are... kind
# of pointless! In fact, you can think of flakes as a way of sharing Nix code
# with others.
outputs = { self, nixpkgs, flake-utils }:
let
# A set of systems to provide outputs for. In Nix flakes, many output
# types, like packages and development environments, need to be for
# specific systems. This flake supports these systems:
supportedSystems = [
"x86_64-linux" # Linux on AMD/Intel
"aarch64-linux" # Linux on ARM64
"x86_64-darwin" # macOS on AMD/Intel
"aarch64-darwin" # macOS on Apple Silicon
];
in
flake-utils.lib.eachSystem supportedSystems (system:
let
# This creates a system-specific version of Nixpkgs and stores it in a
# variable
pkgs = import nixpkgs { inherit system; };
in
{
# When you specify a `default` environment, you can enter it by running
# `nix develop` with no arguments. In other words `nix develop` is the
# equivalent of `nix develop .#default`.
devShells.default = pkgs.mkShell {
# The packages provided in the environment. Because the packages are
# included in the `pkgs` attribute set, each is pinned to a specific
# revision of Nixpkgs via `flake.lock`, which makes the environment
# reproducible (as anyone else using this environment uses the same
# Git revision).
buildInputs = with pkgs; [
python310 # Python 3.10
go_1_19 # Go 1.19
nodejs-18_x # Node.js 18
terraform
];

# Nix development environments support environment variables. You
# can set variables like `DEBUG = true` or `ENV = "production"`. But
# beware: we do *not* recommend using environment variables to provide
# secrets!
MESSAGE = "This is only available inside the environment";

# Shell hooks are optional scripts that are run every time you enter
# the development environment.
shellHook = ''
echo "Welcome to an example Nix development environment for nix.dev!"
'';
};
});
}