Skip to content

Latest commit

 

History

History
293 lines (213 loc) · 9.23 KB

README.md

File metadata and controls

293 lines (213 loc) · 9.23 KB

Nix Flake Templates

This is a collection of Nix flake templates I use in my personal projects. Most of them provide development shells (i.e. devShells.*), but I may add further instructions for production builds in the future.

I use these templates on NixOS, so they don't assume any non-Nix dependencies. They should work on any platform. Basically, each template contains:

  • A programming language implementation (compiler and build system)
  • A language server

Most of the modern programming languages provide a scaffolding command (typically as new/init sub-command), so most of my templates are minimalist. They also don't contain DevOps things (e.g. CI, non-default formatting and linting, and other conformance-related settings), as such settings can be opinionated.

For maintaining a complex flake configuration, I would suggest use of flake-parts. Actually, I am using flake-parts in some of these templates where it makes the configuration more concise.

List of templates in this repository

This is a minimal project boilerplate which depends only on nix-systems and nixpkgs.

nix flake init -t github:akirak/flake-templates#minimal

This is another minimal project boilerplate with flake-utils. It adds a flake-utils dependency but can be more convenient if you plan to provide multiple types of outputs from your flake:

nix flake init -t github:akirak/flake-templates#flake-utils

This is a boilerplate based on flake-parts.

nix flake init -t github:akirak/flake-templates#flake-parts

It contains a stub for partitions which is commented out by default.

This is a basic project boilerplate with pre-commit-hooks.nix to run linters.

nix flake init -t github:akirak/flake-templates#pre-commit

Alternatively, you can set up a pre-commit hook without adding a boilerplate by running nix develop as in akirak/git-hooks.

Based on minimal, this boilerplate contains a configuration for treefmt-nix, so you can set up formatters easily.

nix flake init -t github:akirak/flake-templates#treefmt

Usage:

  • You can run nix fmt to run formatters configured in treefmt.nix in the repository.
  • You can run nix flake check --print-build-logs to check if all files are correctly formatted (useful on CI).

This is based on minimal but contains basic dependencies for web development with Node.js and TypeScript. You can add it to your existing code base to start coding without globally installing node. To scaffold a new project, you can use, for example, bolt.new and then develop the project on NixOS after adding flake.nix:

nix flake init -t github:akirak/flake-templates#node-typescript

It includes Node, TypeScript, and typescript-language-server as buildInputs of the development shell. You can tweak these settings to suit your needs, e.g. to use yarn or pnpm.

This flake.nix lets you use Dune for your development workflow but also allows to build your package using Nix. It depends on the overlay from nix-ocaml.

nix flake init -t github:akirak/flake-templates#ocaml

You will define your OCaml dependencies in propagatedBuildInputs of the dune package in flake.nix. With the direnv integration, you don't have to manually install packages using opam for development.

See also the Nixpkgs manual for concrete information.

This is a template for a simple Rust project with a single executable package.

nix flake init -t github:akirak/flake-templates#rust

It depends on:

It provides:

  • rust-analyzer for a selected Rust toolchain.
  • Auto-formatting of Rust and Nix code via nix fmt.

This is a simplified flake.nix for Elixir.

nix flake init -t github:akirak/flake-templates#elixir

Once you enter the devShell, you can initialize a project by running mix:

mix new . --app hello

This is a more complex Nix boilerplate for Elixir. To use this flake, first scaffold an application using mix, and then run the following command to add flake.nix:

nix flake init -t github:akirak/flake-templates#elixir-app

Features:

  • It includes native dependencies for developing a Phoenix application such as node.js and a file watcher.
  • It includes Lexical LSP server, but you can tweak the flake to use one of the alternatives.
  • It uses flake-parts to organize the flake outputs. It contains a boilerplate for process-compose-flake to define background processes declaratively.

Note that I don't run Elixir applications in production, so I didn't take into account real-world deployment scenarios of Erlang applications.

This flake provides minimal dependencies for Gleam.

nix flake init -t github:akirak/flake-templates#gleam

This flake provides a development environment for Go.

nix flake init -t github:akirak/flake-templates#go

Note that creating a Go project may require some manual work. This template helps you start working on an existing Go project on NixOS or adding a Nix-based CI, but not much more.

This flake provides a minimal development environment for Zig.

nix flake init -t github:akirak/flake-templates#zig

This is a set of common metadata files for GitHub projects, such as .gitignore, dependabot.yml, etc.

nix flake init -t github:akirak/flake-templates#meta

Editor integration

Emacs

To turn on a LSP client and linters inside Emacs, a recommended way is to set .dir-locals. I have the following configuration in my init.el:

(let ((prettier '((eval . (prettier-on-save-mode t))))
      (lsp '((eval . (eglot-ensure))))
      (flymake-eslint '((eval . (flymake-eslint-enable)))))
  (dir-locals-set-class-variables
   'default
   `((web-mode . (,@prettier ,@lsp))
     (css-mode . (,@prettier ,@lsp))
     (svelte-mode . (,@prettier ,@lsp ,@flymake-eslint))
     (elixir-ts-mode . (,@lsp))
     (tsx-ts-mode . (,@prettier ,@lsp))
     (typescript-ts-mode . (,@prettier ,@lsp))
     (tuareg-mode . (,@lsp))
     (haskell-mode . (,@lsp)))))

;; Apply the settings to only relevant organizations
(dir-locals-set-directory-class "~/work/my-org/" 'default)

For details, see [elisp#Directory Local Variables](info:elisp#Directory Local Variables) info manual.

Th above settings depend on the following packages:

  • eglot, a LSP client for Emacs, which is built-in from Emacs 29
  • reformatter for defining a formatter. See this comparison table for alternatives
  • flymake-eslint for running eslint alongside the syntax checker provided by the running language server

prettier-on-save-mode become available when you define prettier formatter using reformatter as follows:

(reformatter-define prettier
  :program "prettier"
  :args (list (concat "--plugin-search-dir="
                      (expand-file-name
                       (locate-dominating-file default-directory "package.json")))
              "--stdin-filepath" (buffer-file-name)))

Also see nix3.el, which provides nix3-flake-new and nix3-flake-init commands for running a flake template quickly from inside Emacs.

Other template repositories and alternatives

The following is a list of template repositories I found on GitHub:

devenv is a convenient tool that lets you set up a Nix-based development environment quickly.

nix-init is a program that interactively generates a Nix expression to build a project at a URL.