tweag / nickel

Better configuration for less
https://nickel-lang.org/
MIT License
2.23k stars 85 forks source link
configuration configuration-language infrastructure nickel nix rust

Nickel

Continuous integration Website Discord

Nickel is the cheap configuration language.

Its purpose is to automate the generation of static configuration files - think JSON, YAML, XML, or your favorite data representation language - that are then fed to another system. It is designed to have a simple, well-understood core: it is in essence JSON with functions.

Nickel's salient traits are:

The motto guiding Nickel's design is:

Great defaults, design for extensibility

There should be a standard, clear path for common things. There should be no arbitrary restrictions that limit what you can do you the one day you need to go beyond.

Use cases

Nickel is a good fit in any situation where you need to generate a complex configuration, be it for a single app, a machine, whole infrastructure, or a build system.

The motivating use cases are in particular:

Most aforementioned projects have their own bespoke configuration language. See Comparison. In general, application-specific languages might suffer from feature creep, lack of abstractions or just feel ad hoc. Nickel buys you more for less.

The Nickel ecosystem

Related projects that are part of the Nickel ecosystem:

Getting started

Please follow the getting started guide for Nickel users on the nickel-lang website. The instructions below are either reproduced for this document to be self-contained or because they are aimed toward hacking on the Nickel interpreter itself (e.g. building the nickel-lang-core crate documentation).

Run

  1. Get a Nickel binary:

    • With flake-enabled Nix, run Nickel directly with nix run github:tweag/nickel. You can use our binary cache to prevent rebuilding a lot of packages. Pass arguments to Nickel with an extra -- as in nix run github:tweag/nickel -- repl,
    • Again with flake-enabled Nix, you can install Nickel in your profile with nix profile install github:tweag/nickel. The nickel command is then in your $PATH and is available anywhere.
    • If you're running macOS you can use Homebrew to install the Nickel binary with brew install nickel.
    • Without Nix, you can use cargo run --bin nickel after building, passing arguments with an extra -- as in cargo run --bin nickel -- eval program.ncl.
  2. Run your first program:

    $ nickel eval <<< '["hello", "world"] |> std.string.join ", "'
    "hello, world"

    Or load it from a file:

    $ echo 'let s = "world" in "hello, %{s}"' > program.ncl
    $ nickel eval program.ncl
    "hello, world"
  3. Start a REPL:

    $ nickel repl
    nickel> {"hello" = true, "world" = true, "universe" = false}
      |> std.record.to_array
      |> std.array.filter (fun {field, value} => value)
      |> std.array.map (fun {field, value} => field)
      |> std.string.join ", "
    
    "hello, world"

    Use :help for a list of available commands.

  4. Export your configuration to JSON, YAML or TOML:

    $ nickel export --format json <<< '{content = "hello, world"}'
    {
    "content": "hello, world"
    }

Use nickel help for a list of subcommands, and nickel help <subcommand> for help about a specific subcommand.

To get in touch, you can join our Discord server.

Editor Setup

Nickel has syntax highlighting plugins for Vim/Neovim, and VSCode. In-editor diagnostics, type hints, and auto-completion are provided by the Nickel Language Server. Please follow the LSP guide to set up syntax highlighting and NLS.

Formatting

To format one or several Nickel source files, use nickel format:

nickel format network.ncl container.ncl api.ncl

Nickel uses Topiary to format Nickel code under the hood.

Please follow the Formatting Capabilities section of the LSP documentation to know how to hook up the Nickel LSP and Topiary in order to enable formatting inside your code editor.

Build

  1. Download build dependencies:

    • With Nix: If you have Nix installed:

      nix-shell # if you don't use Nix flakes
      nix develop # if you use Nix flakes

      You will be dropped in a shell, ready to build. You can use our binary cache to prevent rebuilding a lot of packages.

    • Without Nix: otherwise, follow this guide to install Rust and Cargo first.
  2. Build Nickel:

    cargo build -p nickel-lang-cli --release

    And voilà! Generated files are placed in target/release.

    You can directly build and run the Nickel binary and pass argument after -- by using cargo run:

    cargo run --bin nickel -- eval foo.ncl

Test

Run tests with

cargo test

Documentation

The user manual is available on the nickel-lang.org website, and in this repository as a collection of Markdown files in doc/manual.

To get the documentation of the nickel-lang codebase itself:

  1. Build the doc:

    cargo doc --no-deps
  2. Open the file target/doc/nickel/index.html in your browser.

Examples

You can find examples in the ./examples directory.

Current state and roadmap

Since version 1.0 released in May 2023, the core design of the language is stable and Nickel is useful for real-world applications. The next steps we plan to work on are:

The next steps we plan to work on are:

Comparison

See RATIONALE.md for the design rationale and a more detailed comparison with these languages.

Comparison with other configuration languages

Language Typing Recursion Evaluation Side-effects
Nickel Gradual (dynamic + static) Yes Lazy Yes (constrained, planned)
Starlark Dynamic No Strict No
Nix Dynamic Yes Lazy Predefined and specialized to package management
Dhall Static (requires annotations) Restricted Lazy No
CUE Static (everything is a type) No Lazy No, but allowed in the separated scripting layer
Jsonnet Dynamic Yes Lazy No
KCL Gradual (dynamic + static) Yes Strict No
JSON None No Strict No
YAML None No N/A No
TOML None No N/A No