https://github.com/tweag/nickel Skip to content Sign up Sign up * Why GitHub? Features - + Mobile - + Actions - + Codespaces - + Packages - + Security - + Code review - + Project management - + Integrations - + GitHub Sponsors - + Customer stories- * Team * Enterprise * Explore + Explore GitHub - Learn and contribute + Topics - + Collections - + Trending - + Learning Lab - + Open source guides - Connect with others + The ReadME Project - + Events - + Community forum - + GitHub Education - + GitHub Stars program - * Marketplace * Pricing Plans - + Compare plans - + Contact Sales - + Nonprofit - + Education - [ ] [search-key] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this organization All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up Sign up {{ message }} tweag / nickel * Notifications * Star 307 * Fork 11 Cheap configuration language MIT License 307 stars 11 forks Star Notifications * Code * Issues 38 * Pull requests 11 * Actions * Projects 0 * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Security * Insights master Switch branches/tags [ ] Branches Tags Nothing to show {{ refName }} default View all branches Nothing to show {{ refName }} default View all tags 17 branches 0 tags Go to file Code Clone HTTPS GitHub CLI [https://github.com/t] Use Git or checkout with SVN using the web URL. [gh repo clone tweag/] Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Go back Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Go back Launching Xcode If nothing happens, download Xcode and try again. Go back Launching Visual Studio If nothing happens, download the GitHub extension for Visual Studio and try again. Go back Latest commit @edolstra edolstra Merge pull request #313 from tweag/task/test-suite-2 ... 9a594f4 Mar 8, 2021 Merge pull request #313 from tweag/task/test-suite-2 Migrate failure tests 9a594f4 Git stats * 861 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github/workflows Fix target system in GH actions Mar 3, 2021 makam-spec nixify circleci jobs and run them with github actions Jan 24, 2021 notes Save the review of the error reporting libs Jul 16, 2020 scripts fixing update_channel.sh script Jan 24, 2021 src Merge pull request #313 from tweag/task/test-suite-2 Mar 8, 2021 stdlib Merge remote-tracking branch 'origin/feature/ record-definition-by-pie... Mar 2, 2021 tests Migrate remaining failure tests from Program Mar 8, 2021 .gitignore added update channels script and hook it with github actions Jan 15, 2021 Cargo.lock Merge remote-tracking branch 'origin/feature/ record-definition-by-pie... Mar 2, 2021 Cargo.toml Merge remote-tracking branch 'origin/feature/ record-definition-by-pie... Mar 2, 2021 LICENSE Set the license to Tweag's MIT Aug 10, 2020 RATIONALE.md Update RATIONALE.md Nov 13, 2020 README.md Merge pull request #118 from tweag/doc/design-rationale Aug 27, 2020 build.rs Implement clippy recommandations Feb 5, 2021 default.nix use nixpkgs-mozilla and provide a way to build on different channels Jan 15, 2021 flake.lock nixify circleci jobs and run them with github actions Jan 24, 2021 flake.nix Fix typo in flake.nix Mar 3, 2021 shell.nix Add flake.nix Jul 3, 2020 View code README.md Nickel - Cheap configuration language Nickel is a lightweight 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: at its heart, it is JSON with functions. It adds other features on top of it to improve expressivity and modularity, but you can do just fine without using it. Nickel's important traits are: * Lightweight: Nickel aims at being embeddable into other projects. As such, a simple and lightweight minimal interpreter should be reasonably simple to implement. The reference interpreter should also be easily callable from various programming languages. * Functional: the basic building blocks are functions. They are first-class citizens, which can be passed around, called and composed. * Gradual typing: static types improve code quality, serve as a documentation and eliminate bugs early. On the one hand, code specific to a particular configuration does not depend on external inputs and will always be evaluated to the same value, thus any type error will show up at run time anyway. Also, some JSON can be hard to type. There, types are only a burden. On the other hand, reusable code - that is, functions - is evaluated on potentially infinitely many different inputs, and is impossible to test exhaustively: there, types are precious. Nickel has types, but you get to chose when you want it or not, and it handles safely the interaction between the typed and the untyped world. * Contracts: complementary to the type system, contracts are a principled approach to dynamic type checking. They are used internally by the interpreter to insert guards at the boundary between typed and untyped chunks. Nickel makes them available to the programmer as well, to give them the ability to enforce type assertions at runtime in a simple way. * Merge system: while the basic computational blocks are functions, the basic data blocks are records (called objects in JSON). Nickel features a merge operation which lets you combine together such records modularly, but also to specify meta-data about the content of these records (documentation, default values, type contracts, etc.), called enriched values. The motto guiding Nickel's design is: Great defaults, design for extensibility There should be a standard, clear path for doing usual things. There should not be arbitrary restrictions which limit you this one day you need to go beyond usual to solve a hard specific problem. Use cases Nickel should fit any situation where you need to generate a complex configuration, be it for a software, a machine, a whole infrastructure, or a build system. The motivating use cases are in particular: * The Nix package manager: Nix is a declarative package manager using its own language for specifying packages. Nickel is inspired in part by the Nix language, while trying to overcome some of its limitations. It could be used instead of the Nix language. * (Cloud) infrastructure as code: infrastructure is becoming increasingly complex, requiring a rigorous approach to deployment, modification and configuration. This is where a declarative approach also shines, as adopted by Terraform, NixOps or Kubernetes, all requiring potentially complex generation of configuration. * Build systems: build systems are yet another piece of software which needs to dynamically generate configuration, the dependency graph for example. Bazel rules may require a powerful language. Several aforementioned projects have their own dedicated configuration language. See the Related project section for a partial comparison. In general, such specific languages may suffer from feature creep, lack of abstractions or just feel ad-hoc. Some are also totally fine but have just made different design decisions and trade-offs. Getting started Build 1. Clone the repository in a local folder: $ git clone git@github.com:tweag/nickel.git $ cd nickel nickel$ 2. Install build dependencies: + With Nix: If you have Nix installed, you can just type nickel$ nix-shell shell.nix [nix-shell:/tmp/nickel]$ to be dropped in a shell, ready to build. + Without Nix: Otherwise, follow this guide to install Rust and Cargo first. 3. Build Nickel: nickel$ cargo build And voila ! Generated files are placed in target/debug. Run 1. (optional) Make a symbolic link to the executable: nickel$ ln -S nickel target/debug/nickel 2. Run your first program: nickel$ ./nickel <<< 'let x = 2 in x + x' Typechecked: Ok(Types(Dyn)) Done: Num(4.0) Or load it from a file: nickel$ echo 'let s = "world" in "Hello, " ++ s' > program.ncl nickel$ ./nickel < program.ncl Typechecked: Ok(Types(Dyn)) Done: Str("Hello, world") By default, Nickel reads from the standard input. It may change in the future. Tests nickel$ cargo test Documentation 1. Build the doc: nickel$ cargo doc --no-deps 2. Open the file target/doc/nickel/index.html in your browser. Examples You can find examples in src/examples. Note that as the syntax is not yet fixed, and some basic helpers are missing, they may seem a bit alien currently. Roadmap The design is settled and implemented for the most part, but the final syntax and others important practical aspects are still being debated. We aim to transition from an experimental stage to a minimum viable product stage. The next points to deal with are: * Imports * List comprehensions * Destructuring * String interpolation * Recursive records * Syntax Related projects and inspirations * Cue is a configuration language with a focus on data validation. It has an original constraint system backed by a solid theory which ensures strong guarantees about your code. It allows for very elegant schema specifications. In return, the cost to pay is to abandon functions and Turing-completeness. Nickel's merge system is inspired by the one of CUE, even if since Nickel does have general functions and is Turing-complete, they are necessarily different. * Nix: The Nix language, or Nix expressions, is one of the main inspiration for Nickel. It is a very simple yet powerful lazy functional language. We strive to retain this simplicity, while adding typing capabilities, modularity, and detaching the language from the Nix package manager. * Dhall is a statically typed configuration language. It is also inspired by Nix, to which it adds a powerful static type system. However, this forces the programmer to annotate all of their code with types. * Jsonnet is another language which could be dubbed as "JSON with functions" (and others things as well). It is a lazy functional language with object oriented features, among which inheritance is similar to Nickel's merge system. One big difference with Nickel is the absence of typing. * Pulumi is not a language in itself, but a cloud tool (like Terraform) where you can use your preferred language for describing your infrastructure. This is a different approach to the problem, with different trade-offs. * Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden, making it not Turing-complete. See RATIONALE.md for the design rationale and a more detailed comparison with a selection of these languages. License MIT License. Copyright (c) Tweag Holding and its affiliates. About Cheap configuration language Topics nix configuration configuration-language Resources Readme License MIT License Releases No releases published Packages 0 No packages published Contributors 10 * @yannham * @teofr * @edolstra * @garbas * @aspiwack * @curiousleo * @mboes * @regnat * @zimbatm * @wbadart Languages * Rust 94.7% * NCL 4.3% * Other 1.0% * (c) 2021 GitHub, Inc. * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.