Skip to content

Instantly share code, notes, and snippets.

@alanning
Last active October 23, 2025 09:30
Show Gist options
  • Save alanning/1ff5c6dabe90e7cb6c37362da92793a5 to your computer and use it in GitHub Desktop.
Save alanning/1ff5c6dabe90e7cb6c37362da92793a5 to your computer and use it in GitHub Desktop.
Script for reading relaxed json from stdin and returning formatted json
#!/usr/bin/env node
const vm = require('node:vm')
const readline = require('node:readline')
// Safely parse relaxed json from stdin and return formatted result.
// Intended for use from within VIM.
//
// Requirements:
// 1. Linux shell
// 2. NodeJS must be installed
// 3. Executable flag set on script file: chmod u+x formatRelaxedJson.js
//
// Command line:
//
// echo "{ foo: 'bar' }" | ./formatRelaxedJson.js
//
//
// VIM:
// Press your leader key and then 'fj' to convert the whole file.
// Also works in visual mode so you can select just the json to format
//
// .vimrc:
// " assumes formatRelaxedJson.js is located in your home directory...
// nnoremap <Leader>fj :%! ~/formatRelaxedJson.js<CR>
// vnoremap <Leader>fj :! ~/formatRelaxedJson.js<CR>
//
// Credit for use of node:vm goes to ojosilva:
// https://stackoverflow.com/a/76044884/219238
async function main () {
const parts = []
for await (const line of readline.createInterface({ input: process.stdin })) {
parts.push(line)
}
const badJson = parts.join('\n')
const parsedJson = parseRelaxedJson(badJson)
console.log(JSON.stringify(parsedJson, null, 2))
}
function parseRelaxedJson (badJson) {
try {
const parsedJson = new vm.Script(`x=${badJson}`).runInNewContext(
{ console: undefined }, // nuke console inside the vm
{ timeout: 1000, displayErrors: true }
)
if (typeof parsedJson !== 'object') {
// in case you're expecting an object/array
throw new Error(`Invalid JSON=${badJson}, parsed as: ${parsedJson}`)
}
return parsedJson
} catch (err) {
throw new Error(`Could not parse JSON: ${err}`)
}
}
main()
@alanning
Copy link
Author

alanning commented Oct 23, 2025

Motivation for this script was a tool that works on "relaxed" json rather than requiring the input json to be well-formatted like these do:

:%!jq .
:%!python -m json.tool

This script may also be helpful to those interested in:

  • Creating a nodejs script that can be executed on the command line
  • Reading in from stdin
  • Using a VM to safely do parsing
  • Configuring .vimrc to map both in normal and visual mode
  • Sending buffer contents to a general shell script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment