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.

Output
id,customer,total
1039,Cara Vind,2199.99
1042,Alice Hansen,1299

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 INSERT statements, or an aligned table in the terminal (the default).
Worth knowing
CSV values are coerced the way a spreadsheet would: 32 becomes a number, true a 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

OperationExample
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.

Buy Pro for 19 USD

Guides

Longer walkthroughs of specific jobs, each with commands you can paste and the output they produce.

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.