CLI tool
google/jsonnet avatar
google/jsonnet

Jsonnet: Google's data templating language for generating JSON config

Jsonnet - The data templating language

7,572 stars477 forksJsonnetApache-2.0

At a glance

What is it?
Jsonnet is a functional templating language that compiles to JSON. This review covers how it works, how to install it from Homebrew or pypi, and why the README points most users at go-jsonnet instead of the C++ implementation.
Who is it for?
Adopt Jsonnet when you are generating large volumes of JSON or YAML that share structure and you trust the source of the templates. Do not adopt the C++ implementation if you need to evaluate untrusted Jsonnet input; the README states it is not hardened for that case and that import, importstr and importbin can read any path available to the interpreter process.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Jsonnet, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Jsonnet solves, and who it is aimed at

JSON has no variables, no functions and no imports. Every environment you deploy to therefore ends up with a near-copy of the same configuration file, and the copies drift. Jsonnet is a language that evaluates to JSON, so you can define a base object once, parameterise it, and emit a different concrete document for staging and production from the same source. The repository describes it as "The data templating language" and the topics list confirms the intent: config, configuration, functional, json.

The audience is platform and infrastructure engineers who already generate machine-readable configuration at scale. The repository ships a Kubernetes example and its related searches include Jsonnet Kubernetes and jsonnet grafana, so the intended use is clearly the config-generation layer of a deployment pipeline rather than application code. If you only ever write one small JSON file by hand, Jsonnet adds a build step and a language to learn for no benefit. The payoff starts when the same structure repeats across many files or many environments.

How evaluation works: a functional language that emits JSON

Jsonnet source is not interpreted line by line into output. The pipeline visible in the repository is a compiler front end followed by a virtual machine: setup.py lists core/lexer.cpp, core/parser.cpp, core/desugarer.cpp, core/static_analysis.cpp and core/vm.cpp among the sources it compiles. So a .jsonnet file is lexed, parsed into an AST, desugared, checked, then evaluated by the VM, and the result is serialised as JSON. That is why errors can surface before evaluation, and why the output is a value rather than a stream of text.

Objects are the central data structure, and they compose. The examples directory contains computed-fields.jsonnet, inner-reference.jsonnet, comprehensions.jsonnet and imports.jsonnet, which maps to the object model: a field can be computed from other fields, an object can reference itself, and a file can pull in another file. Imports are the mechanism for sharing a base template across many output files. The README warns that import, importstr and importbin "can import from any path accessible to the interpreter process" by default, so the sharing mechanism is also the part you have to constrain if the templates come from anywhere you do not control.

Jsonnet is a full expression language, not a substitution format. The search question is jsonnet turing complete is a fair one to ask, and the practical consequence is that a template can compute its own output rather than merely filling in blanks. That is the source of its power and of the review burden: a reader of a generated JSON file cannot tell what the source did without reading the Jsonnet.

Installing Jsonnet and rendering your first file

The README lists several distribution channels. Homebrew is the shortest path on macOS and Linux:

bash
brew install jsonnet

On Windows, the README points to MSYS2 and gives one package name per toolchain, for example:

bash
pacman -S mingw-w64-ucrt-x86_64-jsonnet

The Python binding is published on pypi, so a Python project can pull it in without a system package manager:

bash
pip install jsonnet

If you prefer to build from source, the Makefile is the documented route and it needs a C++17 compiler. The README gives both the GCC and Clang invocations:

bash
make
make CC=clang CXX=clang++

That produces a jsonnet binary and a jsonnetfmt reformatter in the repository root. The README shows how to run them:

bash
./jsonnet
./jsonnetfmt

Bazel is also supported, and the README states that `bazel build -c opt //cmd:all` builds the jsonnet and jsonnetfmt targets defined in cmd/BUILD. A Dockerfile is present as well: it builds in an alpine stage with `make`, then copies jsonnet and jsonnetfmt into /usr/local/bin in a second alpine stage and sets the entrypoint to /usr/local/bin/jsonnet. If you are containerising a pipeline, that file is the reference for what the image expects.

For a first real use, the examples directory is the intended starting point. The repository contains examples/arith.jsonnet with a matching examples/arith.jsonnet.golden, and examples/check.sh, which suggests the golden files are the expected output. Run the interpreter over a file like that and compare the result against the .golden file to confirm your build behaves as the project expects before you point it at your own configuration.

The C++ implementation is not hardened for untrusted input

This is the limitation the README states most plainly, and it decides the architecture of anything you build on top. The security notes say that if you need to process untrusted inputs, "it is best not to use the C++ implementation, as it is not hardened for that use-case", and that the expected use case is evaluating Jsonnet code you or your organisation wrote and trusts not to be malicious. Even setting aside implementation bugs, the README notes that import, importstr and importbin can exfiltrate sensitive data unless you restrict them or sandbox the interpreter, because by default they can read any path the process can reach.

The practical consequence: a service that accepts Jsonnet from tenants or end users and evaluates it with this binary is outside the documented safe use case. Restricting imports or running the interpreter in a sandbox is your responsibility, and the README does not document a flag that does this for you. The README also points to go-jsonnet as "a newer implementation which in some cases is orders of magnitude faster, and is recommended in preference to the C++ version". That sentence is easy to miss, and it means the repository you are reading is not the implementation the project itself recommends for new work.

Jsonnet compared with CUE, Helm and Kustomize

The related searches put Jsonnet next to CUE, Helm and Kustomize, which is the right comparison set, because all four sit between you and a generated manifest.

Helm templates YAML with Go's text/template engine. The output is text, so a malformed template can produce YAML that parses in one place and breaks in another, and the values you inject are untyped. Jsonnet evaluates to a JSON value, so the structure is checked before serialisation. Helm's advantage is packaging and release management, which Jsonnet does not attempt: Jsonnet is a language and a renderer, not a chart repository or a release tool.

Kustomize takes valid YAML and applies overlays and patches. That is a different starting point: your base must already be valid YAML, and the transformations are declarative patches rather than computation. Jsonnet lets you compute a field from other fields, which Kustomize cannot express. Kustomize's advantage is that the base stays readable YAML, whereas a Jsonnet base is code.

CUE is the closest in spirit: a constraint language over data with types. CUE unifies values and validates them against constraints, while Jsonnet evaluates expressions to a value. The related search jsonnet vs cue reflects a real choice, and the deciding question is whether you mainly need to validate and merge existing data (CUE) or compute new data from parameters (Jsonnet).

The README names go-jsonnet as the alternative implementation and recommends it over the C++ version. That is the most consequential comparison here, because it is the project's own preference rather than an outside opinion.

Maintenance, releases and what the Apache-2.0 licence means for you

The repository is not archived and the last push was on 2026-03-30, so it is receiving changes. Release cadence is visible in the tags: v0.21.0 on 2025-05-07, v0.22.0-rc1 on 2026-03-08, and v0.22.0 on 2026-03-24. A roughly ten-month gap between v0.21.0 and v0.22.0, with a release candidate three weeks before the final tag, suggests a project that ships deliberately rather than continuously. Plan upgrades around the release tags rather than assuming a rolling stream of fixes.

Upgrade cost is dominated by how much of the standard library and how much of the object model your templates touch. The repository documents the standard library in a structured file, doc/_stdlib_gen/stdlib-content.jsonnet, and the website content is regenerated with tools/scripts/update_web_content.sh. A minor version bump can change standard library behaviour, and because your templates are code, the diff you have to review is your templates rather than a lockfile. There is a release_checklist.md in the repository root, which tells you the maintainers treat a release as a sequence of steps rather than a tag push.

The licence is Apache-2.0, stated in the repository metadata and in the LICENSE file. The file headers in setup.py carry the standard Apache 2.0 grant and the "AS IS" disclaimer. That permissive licence is compatible with closed-source internal use, but this is not legal advice and the patent grant and notice obligations are worth reading in full before you redistribute a modified interpreter.

Editorial conclusion

Adopt Jsonnet when you are generating large volumes of JSON or YAML that share structure and you trust the source of the templates. Do not adopt the C++ implementation if you need to evaluate untrusted Jsonnet input; the README states it is not hardened for that case and that import, importstr and importbin can read any path available to the interpreter process. Before committing, verify which implementation you are installing, since the README recommends go-jsonnet over the C++ version, and confirm that the Python binding on pypi is the one your build pipeline will pull.

Frequently asked questions

What is Jsonnet used for?

It is a data templating language that evaluates to JSON, intended for generating configuration. The repository topics list config, configuration, functional and json, and the examples include a Kubernetes example and a build example.

How do I install Jsonnet?

The README lists Homebrew with `brew install jsonnet`, MSYS2 packages for Windows, the Python binding on pypi with `pip install jsonnet`, and vcpkg. Building from source uses `make`, or Bazel with `bazel build -c opt //cmd:all`.

How do I install Jsonnet on Windows?

The README points to MSYS2 and gives one package name per toolchain, for example `pacman -S mingw-w64-ucrt-x86_64-jsonnet`. Other listed variants cover clang and gcc builds for 32-bit and 64-bit targets.

Is Jsonnet Turing complete?

The repository does not state this directly, but the language is functional and includes functions, conditionals, comprehensions and imports, as shown by examples/functions.jsonnet, examples/conditionals.jsonnet and examples/comprehensions.jsonnet. It evaluates expressions to a JSON value rather than performing substitution.

Official sources

  1. google/jsonnet on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-jsonnet.svg)](https://hysenlabs.com/projects/google-jsonnet)