CLI tool
TomWright/dasel avatar
TomWright/dasel

Dasel: one selector syntax across JSON, YAML, TOML, XML, CSV and KDL

Unified querying, transformation, and modification of JSON, TOML, YAML, XML, INI, HCL, KDL and CSV.

8,044 stars174 forksGoMIT

At a glance

What is it?
Dasel is a Go CLI and library from TomWright that queries, edits and converts structured config files with a single selector language. It is a good fit for shell pipelines and Go services, and a poor fit for anything that needs schema validation.
Who is it for?
Adopt Dasel if you edit structured config from shell scripts or need one selector language across JSON, YAML, TOML, XML, CSV, HCL, INI and KDL, and if you are willing to pin a v3 release because the go install path tracks master. Do not adopt it as a schema validator or as a general-purpose stream processor; it parses whole documents and has no validation layer.
Can I use it commercially?
Yes. MIT 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?
Yes. The repository last received commits 45 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

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

Editorial analysis

What Dasel solves for people who edit config files

Structured config files do not share a query language. jq reads JSON. yq reads YAML. tomlq reads TOML. A shell script that touches three formats ends up shelling out to three tools with three selector dialects and three sets of quoting rules. Dasel's pitch is that all of them take the same selector, so `foo.bar` means the same thing whether the document underneath is JSON, YAML, TOML, XML, CSV, HCL, INI or KDL.

The README describes it as "a command-line tool and library for querying, modifying, and transforming data structures" and lists developers, DevOps and data wrangling as the audience. That is an accurate description of the intended user: someone in a pipeline who needs to read one value out of a file, or change one value in a file, without writing a script in a language runtime. The library side matters too. The repository exposes a top-level `api.go`, so Go programs can call the same execution engine instead of the CLI.

How the selector engine and format handling fit together

The repository layout separates concerns cleanly. `parsing/` holds the format readers and writers, `selector/` holds the selector language, `execution/` runs it, and `model/` defines the in-memory data structure that everything is converted into. `cmd/` holds the CLI entry point. The flow is: a parser turns the input document into the internal model, the selector is evaluated against that model, and an output parser writes the result back out in whatever format `-o` names.

That design explains two behaviours visible in the README. First, format conversion needs no selector at all: `cat data.json | dasel -i json -o yaml` pipes a JSON document in and gets YAML out. Second, selectors are format-independent because they run against the model, not against the source text. The dependencies in `go.mod` confirm the format list is real rather than aspirational: `hashicorp/hcl/v2` for HCL, `pelletier/go-toml/v2` for TOML, `go.yaml.in/yaml/v4` for YAML, `gopkg.in/ini.v1` for INI, and `goccy/go-json` for JSON. The CLI is built on `alecthomas/kong`, and the Charm libraries (`bubbletea`, `bubbles`, `lipgloss`) are present, which points at an interactive terminal component in the CLI.

The selector language goes beyond dotted paths. The README shows recursive descent with `..`, which searches all nested objects and arrays for a matching key, and a `search(...)` function that finds values matching a condition anywhere in the structure. Both return arrays even when the input had a single match, as the README examples show for `..bar` and `search(bar == "baz")`. That is worth knowing before you pipe the output into something that expects a scalar.

Installing Dasel and running a first edit

The README gives three install paths. Homebrew is the shortest on macOS and Linux:

bash
brew install dasel

Go users can install from source. Note that this command targets `@master`, so it tracks the default branch rather than a tagged release:

bash
go install github.com/tomwright/dasel/v3/cmd/dasel@master

The third path is prebuilt binaries on the Releases page for Linux, macOS and Windows. The README points at the installation docs for other options. There is also a `Dockerfile` in the repository that builds the binary with `go build -o /dasel` and copies it to `/usr/local/bin/dasel` in a `debian:bookworm-slim` image, with `--help` as the default command.

For a first real use, take the README's own example. Selecting a value prints just that value:

bash
echo '{"foo": {"bar": "baz"}}' | dasel -i json 'foo.bar'

The output is `"baz"`. Note the quoting: the selector is a single shell argument, and the JSON string is quoted so the shell does not eat the braces. Adding an assignment changes the document instead of reading it:

bash
echo '{"foo": {"bar": "baz"}}' | dasel -i json --root 'foo.bar = "bong"'

Without `--root` the command prints the new value alone. With `--root` it prints the whole document with the edit applied, which is what you want when writing back to a file. The `-i` flag names the input format and `-o` names the output format; the README does not show a default for either, so pass them explicitly in scripts.

Where Dasel is the wrong tool

Dasel has no schema validation. It will parse a YAML file, let you select and assign values, and write it back, but nothing in the README claims it checks that the result matches a schema, that required keys exist, or that a type is correct. If your pipeline needs that guarantee, Dasel is the wrong layer and you want a validator alongside it.

Whole-document parsing is the second constraint. Every example in the README pipes a complete document in and gets a complete document out. There is no documented streaming mode, so a multi-gigabyte JSON log is not a Dasel workload. It is also not a replacement for a query engine with joins, aggregation or indexing; the selector language traverses a single document tree.

The third issue is source installation. `go install ...@master` follows the default branch, and the repository's last push was on 2026-08-16, so that command can pull in commits newer than any tagged release. The most recent release listed is v3.11.2 from 2026-06-27. If you need reproducible builds, take a tagged binary from Releases or pin a commit rather than using `@master`.

One more gap worth naming: the README documents `--root` for outputting the full document after a modification, but it does not document a rollback or backup mechanism for in-place edits. If you run an assignment against a file, the safety net is your own copy.

Dasel against jq

jq is the obvious comparison, and the difference is scope rather than quality. jq reads JSON only. It is a full functional language with `map`, `reduce`, `group_by`, string interpolation and user-defined functions, and it is far more expressive once you are inside a JSON document. Dasel trades that expressive depth for format breadth: the same `foo.bar` selector works on YAML, TOML, XML, CSV, HCL, INI and KDL, and `-o` converts between them.

That makes the choice depend on what your documents are. If everything you touch is JSON and your transformations are non-trivial, jq is the stronger tool and Dasel adds nothing. If your repository has a `values.yaml`, a `config.toml`, a `.ini` and an HCL file, and you want one mental model for all of them, Dasel is the tool that avoids four separate dialects. The recursive descent operator `..` and the `search(...)` function cover the common "find this key anywhere" case that otherwise pushes people into jq for a YAML file, which means round-tripping through a converter.

Maintenance, licence and what an upgrade costs

The repository is not archived. Its last push was on 2026-08-16, and the release history shows v3.11.0 on 2026-05-19, v3.11.1 on 2026-06-20 and v3.11.2 on 2026-06-27, so releases are frequent enough that pinning a version is practical. The `CHANGELOG.md` at the repository root is where the project records what changed between them, and it is the file to read before moving a pinned version forward.

The module path is `github.com/tomwright/dasel/v3` and the `go.mod` declares `go 1.25`, so the library surface requires a recent Go toolchain. That is a real constraint for teams on older Go versions, and it is the kind of thing that turns a dependency bump into a toolchain bump.

The licence is MIT, stated in the README and in the `LICENSE` file, which is permissive and imposes no copyleft obligation on your own code. The README does not describe any separate terms for the documentation site or the prebuilt binaries. This is a description of what the repository states, not legal advice; if licence terms matter to your organisation, read `LICENSE` directly.

Upgrade cost is mostly selector compatibility. Because the CLI and the Go library share the `execution/` and `selector/` packages, a change in selector semantics lands in both at once. Scripts that depend on the shape of results, particularly the array-wrapping behaviour of `..` and `search(...)`, are the ones most likely to need attention.

Editorial conclusion

Adopt Dasel if you edit structured config from shell scripts or need one selector language across JSON, YAML, TOML, XML, CSV, HCL, INI and KDL, and if you are willing to pin a v3 release because the go install path tracks master. Do not adopt it as a schema validator or as a general-purpose stream processor; it parses whole documents and has no validation layer. Before committing, verify the output format you need is listed in the README's format list, confirm the v3 module path in go.mod, and check that your selector works against a copy of the real file rather than a reduced example.

Frequently asked questions

What is Dasel used for?

Dasel queries, modifies and transforms structured data such as JSON, YAML, TOML, XML, CSV, HCL, INI and KDL. It is used from shell scripts and pipelines, and as a Go library through the module github.com/tomwright/dasel/v3.

How do I install Dasel?

The README gives three routes: brew install dasel on macOS and Linux, go install github.com/tomwright/dasel/v3/cmd/dasel@master, or a prebuilt binary from the Releases page for Linux, macOS and Windows. The installation docs cover further options.

Can Dasel convert between file formats?

Yes. The README shows format conversion with no selector at all, for example cat data.json | dasel -i json -o yaml, where -i names the input format and -o names the output format.

Does Dasel validate my config against a schema?

The README does not describe any schema validation. Dasel parses a document, evaluates a selector against it and writes the result back out; checking required keys or types is a separate concern.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. TomWright/dasel on GitHub
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/tomwright-dasel.svg)](https://hysenlabs.com/projects/tomwright-dasel)