This is the biggest fx release yet. You can now write queries inside the viewer and watch the result update as you type, with Tab completion for keys. fx also reads six new input formats, runs on Bubble Tea v2, and has vim-style commands.
⚡ Interactive queries
Press . in the viewer and start typing. As you type:
- Live preview. The result updates on every keystroke, so you see what your query does before you press Enter.
- Tab completion. Tab completes keys from your data, even inside lambdas. On arrays it walks every element and document.
.items.on an array becomes.items[].key. - The fx syntax you know, with multiple arguments:
.users ?.active @.namefilters and then maps, like on the command line. - JS syntax highlighting in the query input.
- History. ↑/↓ go through earlier queries, and your unfinished draft is kept.
- Esc to cancel. The query is dropped and the original document comes back.
- Streams and slow queries work. A query that never ends can be cancelled, and streamed documents keep flowing in.
The same completion engine now powers shell completion too, so fx data.json .us<Tab> behaves the same in the TUI and in your shell.
📄 New input formats: XML, HTML, EDN, MAML
fx feed.xml .rss.channel.item[].title
fx page.html .html.body
fx deps.edn .paths
fx config.maml .server.port- XML (
--xml,.xml,.svg): attributes become@attr, text becomes#text, repeated children become arrays. This is the familiar xmltodict mapping. Namespace prefixes stay as written, and non-UTF-8 charsets are handled. A file with several root elements becomes a stream of JSON documents. - HTML (
--html,.html,.htm): parsed as a full HTML5 tree, so even messy real-world pages load.<meta charset>is respected. - EDN (
--edn,.edn): keywords lose the colon, so:pathsis queried as.paths. Key order and big integers are kept. - MAML (
--maml,.maml): key order and exact number text are kept.MAML.parseandMAML.stringifyare also available in queries, and in the npm version of fx.
⌨️ Vim-style commands
Press : to open the command line:
| Command | What it does |
|---|---|
:w [file]
| Write the current view, or the query result, to a file |
:wq
| Write and quit |
:w !cmd
| Pipe the JSON to a shell command: :w !less, :w !vim -, :w !code -, :w !pbcopy
|
:q
| Quit |
:<n>
| Go to line n |
🫧 Bubble Tea v2
fx now runs on Bubble Tea v2:
- Yank works over SSH. Copying uses OSC 52 and falls back to the local clipboard tool. This fixes #283 and #413.
- The terminal window title shows the file name.
- Pasting into the query and search inputs works.
- Colors are downsampled correctly when output goes to a pipe.
🧭 Viewer improvements
- % jumps to the matching bracket.
- r reloads the file.
- Ctrl-E/Ctrl-Y scroll the view one line at a time.
- Search in the preview pane, with highlighting and navigation keys.
- Sizes of objects and arrays are shown next to their keys.
- The help screen is grouped by category.
--no-tuiprints the output and never opens the viewer.
🧰 New functions
sortKeyssorts object keys recursively.del(key)removes a key from an object or an index from an array:.users map(del('password')).exit(code)exits fx with the given status code.
🛡️ Stability
A lot of work went into making fx hard to break:
- The JS engine can no longer crash fx. Panics inside queries are reported as errors, and only previews time out.
- Several ways to crash or freeze the viewer were fixed, including ones involving deleted nodes and searches that were still running.
- Windows TTY raw mode is restored after reading stdin.
- UTF-8 BOMs are handled.
- fx works when
$HOMEis not set. - File arguments are detected correctly in non-TTY contexts.
- String escapes are decoded in preview and print.
🎲 One more thing
fx --dungeonThere's a roguelike dungeon hidden inside your JSON viewer. Good luck. 🗡️
⚠️ Breaking changes
- Esc no longer quits. Use q or Ctrl-C.
- The v key (open in editor) is removed. Use
:w !vim -, or any other editor that reads from stdin. - The
digfeature is removed. Interactive queries with Tab completion replace it. - Game of Life is removed. It has been replaced by the dungeon.
- fx exits with a non-zero status on empty input.
- Save operations are rejected for non-JSON input files, so a YAML or XML file is never overwritten with JSON.
Full documentation: fx.wtf
Full Changelog: 39.2.0...40.0.0
