jsonc.min
Why
🔐 Safety
Many JSON minification packages rely on vulnerable regex, making them unsuitable for production.
jsonc.min prioritizes security by avoiding these pitfalls and offering a robust solution.
🤝 Compatibility
jsonc.min ensures full compatibility with both Node.js, Bun, Deno and, browser environments.
All features work for both JSON and JSONC.
🪶 Lightweight
Zero dependencies and optimized for production environments.
Install
# Node.js
npm i jsonc.min
# Bun
bun add jsonc.min
# Deno
deno add npm:jsonc.min
Usage
Import
ES Modules
import { JSONC } from 'jsonc.min';
CommonJS
const { JSONC } = require('jsonc.min');
Browser
<script src="https://cdn.jsdelivr.net/npm/jsonc.min/browser/jsonc.min.js"></script>
toJSON
Convert from JSONC to JSON.
JSONC.toJSON('/* JSONC content */ { "test": true }');
// "{ test: true }"
If the content is already JSON, it will just be preserved:
JSONC.toJSON('{ "test": true }');
// "{ test: true }"
minify
Minify both JSON and JSONC.
const content = `
/**
* JSONC content
*/
{
"test": true // 🔬
}
`;
JSONC.minify(content);
// "{test:true}"
const content = `
{
"test": true
}
`;
JSONC.minify(content);
// "{test:true}"
parse
Parse both JSON and JSONC.
const content = `
/**
* JSONC content
*/
{
"test": true // 🔬
}
`;
JSONC.parse(content);
// { test: true }
const content = `
{
"test": true
}
`;
JSONC.parse(content);
// { test: true }
- If your content is guaranteed to be a JSON, there is no advantage to using
JSONC.parse(content) instead of JSON.parse(content).
stringify
Prettify both JSON and JSONC.
Use JSON.stringify behind the scenes.
const content = '/** JSONC content */ { "test": true }';
JSONC.stringify(content, null, 2);
// "{
// "test": true
// }"
const content = '{ "test": true }';
JSONC.stringify(content, null, 2);
// "{
// "test": true
// }"
Examples
Reading a JSON or JSONC file
import { readFile } from 'node:fs/promises';
import { JSONC } from 'jsonc.min';
const content = await readFile('./file.jsonc', 'utf-8');
JSONC.parse(content);
Parsing a dynamic config file
For this example, let's assume a .configrc that can be both a JSON or a JSONC, as well as looking for both config.json and config.jsonc files:
import { JSONC } from 'jsonc.min';
import { cwd } from 'node:process';
import { join } from 'node:path';
import { readFile } from 'node:fs/promises';
export const getConfigs = async (customPath?: string) => {
const targetRoot = cwd();
const expectedFiles = customPath
? [customPath]
: ['.configrc', 'config.json', 'config.jsonc'];
for (const file of expectedFiles) {
const filePath = join(targetRoot, file);
try {
const configsFile = await readFile(filePath, 'utf-8');
// jsonc.min will parse both JSON and JSONC extensions, even if there is no extension.
return JSONC.parse(configsFile);
} catch {}
return {};
}
};
Each benchmark parses 10,000 iterations of mixed inputs (BOM-prefixed, block and line comments, trailing commas, and nested structures) comparing JSONC.parse from jsonc.min against parse from jsonc-parser (Microsoft) through hyperfine:
| Benchmark |
jsonc-parser |
jsonc.min |
Difference |
| Parse JSONC inputs |
672.8 ms |
298.0 ms |
~2.26x faster |
| Parse JSON inputs |
629.1 ms |
271.3 ms |
~2.32x faster |
- Only the
parse method is compared.
- See detailed results and how the benchmarks are run in the benchmark directory.
[!NOTE]
Benchmarks ran on GitHub Actions (ubuntu-latest) using Node.js LTS.
Results may vary depending on runner hardware and runtime version.
Acknowledgements
