Convert JSON, CSV, YAML, XML and SQL from the terminal. Nothing leaves your machine.
Transmute is a small command-line tool for developers, analysts and anyone else who gets handed a data file in the wrong format. Point it at a file, say what you want out, and optionally filter, sort, join or flatten on the way.
- json
- csv
- yaml
- xml
- sql
- table
npm i -g @mahope/transmute
Other ways to install
$ npx @mahope/transmute people.csv -o json
[
{
"name": "Alice",
"age": 32,
"city": "Aarhus"
},
{
"name": "Bob",
"age": 25,
"city": "Odense"
}
]
Try it here
The same engine as the CLI, running in your browser. Edit the input or the pipeline and the output updates as you type. Nothing is uploaded.
The same thing in the terminal: transmute data.json --pipe '[{"op": "filter", "expr": "item.status === \"shipped\""},{"op": "pick", "fields": ["id", "customer", "total"]},{"op": "sort", "by": "total", "dir": "desc"}]' -o csv
With JavaScript off this shows the example as run against the current release; the CLI gives the same output.
Need the whole CLI? The cheat sheet has every operation, flag and format rule, and the full reference has the exact output, exit codes and script examples for each one.
Three things you would actually do with it
Every example on this page was run against the current release before it was pasted in. The output is what you get.
Turn an API export into a spreadsheet-ready CSV
Keep the shipped orders, keep three columns, sort by value. Field names are yours; item is the current row.
$ transmute orders.json --pipe '[
{"op":"filter","expr":"item.status === \"shipped\""},
{"op":"pick","fields":["id","customer","total"]},
{"op":"sort","by":"total","dir":"desc"}
]' --output csv
id,customer,total
1039,Cara Vind,2199.99
1042,Alice Hansen,1299
Seed a database from a CSV
Numbers stay numbers, strings are quoted and escaped, empty cells become NULL. Works for Postgres, MySQL and SQLite.
$ transmute users.csv --output sql --table users
-- Generated by Transmute
INSERT INTO "users" ("id", "name", "email") VALUES
(1, 'Alice', '[email protected]'),
(2, 'O''Brien', '[email protected]');
Read an XML file as JSON
XML values come through as strings, so wrap them in Number() when you filter on them.
$ transmute users.xml --pipe '[{"op":"filter","expr":"Number(item.age) > 26"},{"op":"pick","fields":["name"]}]' -o json
[
{
"name": "Alice"
}
]
Formats
- Reads
- JSON, CSV, YAML and XML. The format is detected from the file extension or the content; override it with
--format. - Writes
- JSON, CSV, YAML, XML, SQL
INSERTstatements, or an aligned table in the terminal (the default). - Worth knowing
- CSV values are coerced the way a spreadsheet would:
32becomes a number,truea boolean. The YAML parser handles lists of flat records and simple key–value documents, not anchors or multi-line strings. Everything is read into memory, so it is built for files up to a few hundred megabytes rather than multi-gigabyte logs.
Pipeline operations
| Operation | Example |
|---|---|
| filter | {"op":"filter","expr":"item.age > 18"} |
| map | {"op":"map","expr":"({...item, active: true})"} |
| pick / omit | {"op":"pick","fields":["name","email"]} |
| sort | {"op":"sort","by":"name","dir":"asc"} |
| unique | {"op":"unique","by":"email"} |
| group | {"op":"group","by":"city"} |
| add | {"op":"add","fields":{"total":"item.price * item.qty"}} |
| join | {"op":"join","on":"id","keep":"left","with":[…]} |
| rename | {"op":"rename","mapping":{"qty":"quantity"}} |
| flatten | {"op":"flatten","field":"items"} |
| head / tail / count | {"op":"head","n":5} |
Chaining steps
A pipeline is a JSON array of steps, run in order. Expressions are plain JavaScript with the current row as item. Here a cart is joined with stock levels from a second data set, then filtered and counted:
$ transmute cart.json --pipe '[
{"op":"join","on":"sku","keep":"left","with":[{"sku":"A1","stock":42},{"sku":"B2","stock":0}]},
{"op":"filter","expr":"item.stock > 0"},
{"op":"count"}
]' --output json
[
{
"count": 1
}
]
To join against a whole file instead of inline rows, splice it in from the shell: --pipe "[{\"op\":\"join\",\"on\":\"sku\",\"with\":$(cat stock.json)}]". The join guide walks through it.
Install the CLI
Needs Node.js 22 or newer. No other dependencies.
$ npm i -g @mahope/transmute
$ transmute --help
Or run it once without installing:
$ npx @mahope/transmute data.yaml -o json
Pass a file with no options to get a quick table preview of it. Pipe from stdin with cat file | transmute …. Source and issues on GitHub.
Desktop app
The same engine with a window around it: paste or open a file, build the pipeline step by step, see the result update as you go. Built with Tauri, so it is a small native binary on each platform. It is a separate product, and its source is not in this repository — the CLI and the engine you install from npm stay MIT and unlimited.
How to get the app, and what Pro adds
The desktop app is free to download and runs three transformations per launch. Pro removes the limit: a one-time purchase of 19 USD, no subscription, for up to three machines. The licence key arrives by email right after payment. The CLI has no limits and stays free under the MIT licence.
Guides
Longer walkthroughs of specific jobs, each with commands you can paste and the output they produce.
- JSON to CSV with filtersClean spreadsheets from API data: pick columns, filter rows, sort, dedupe.
- CSV to SQL INSERT statementsSeed Postgres, MySQL or SQLite from a spreadsheet export.
- JSON to SQL INSERT statementsShape rows first, then generate statements with correct escaping and NULLs.
- Flatten nested JSON arraysOne row per array element, ready for CSV.
- Join two files by a shared keyA left join from the terminal, without Python or SQLite.
- Add computed fieldsTotals, tax and derived flags from existing columns.
- Filtering JSON without learning jqNamed steps instead of jq syntax, with format conversion built in.
- XML to JSONFrom the command line or in Python, with the caveats spelled out.
- JSON to XMLWell-formed XML from a JSON array, plus the Python equivalent.
- CSV to XMLSpreadsheet exports as XML, with filtering on the way.
Questions
Does it work offline?
Yes. Transformations never make a network request. The only exception is the desktop app contacting the licence server once, when you activate or deactivate a Pro licence.
Where does my data go?
Nowhere. Files are read from disk or stdin, transformed in memory and written to stdout. There is no telemetry, no account and no server side.
What is the licence?
The CLI and engine are MIT licensed; the source is on GitHub. The desktop app is free to download with the limit described above; a Pro licence is a one-time purchase of 19 USD and works on up to three machines.
What is the difference between the CLI and the desktop app?
They share the same engine and produce the same output. The CLI is for scripts, cron jobs, CI and anyone comfortable in a terminal. The desktop app is for building a pipeline interactively and seeing the result while you do it. If you only ever need one, the CLI is the one to start with.
How do I quote the pipeline on Windows?
With difficulty, honestly. In Git Bash or WSL the single-quote form on this page works as written, and that is the recommended route. In PowerShell you can use the stop-parsing token and write inner quotes as \": transmute --% orders.json --pipe "[{\"op\":\"filter\",\"expr\":\"item.status === 'shipped'\"}]" -o csv. That breaks as soon as the pipeline contains < or >, because cmd.exe reads them as redirects, so comparisons are best run from Git Bash or WSL.
Can I use the engine from my own code?
Yes. require('@mahope/transmute') exposes run(text, inputFormat, pipeline, outputFormat) together with the parsers, serializers and operations. It is one file with no dependencies.
Who makes this
Transmute is made by Mads Holst Jensen, a developer and technical partner based in Odense, Denmark. He builds and runs software for small companies and their teams, and this tool grew out of that work.
Bug reports and feature requests go to GitHub issues. For anything else, including working together, see mahoje.dk.