json-parse-better-errors vs json-parse-even-better-errors
Robust JSON Parsing and Error Diagnostics in Node.js Tooling
json-parse-better-errorsjson-parse-even-better-errors

Robust JSON Parsing and Error Diagnostics in Node.js Tooling

json-parse-better-errors and json-parse-even-better-errors are specialized utilities designed to replace the native JSON.parse() method when working with configuration files, lockfiles, and data interchange formats in Node.js environments. While the native parser throws generic SyntaxError objects that often lack context, these libraries intercept parsing failures and augment them with precise metadata, such as the exact character position, line number, and column index of the error. json-parse-better-errors was the original solution for this problem, widely adopted in early package managers and build tools. json-parse-even-better-errors is its modern successor, engineered to handle edge cases more gracefully, support additional input types like Buffers, and provide more stable error messages across different Node.js versions. Both tools are critical for building resilient CLI applications and build systems that need to guide users toward fixing malformed JSON files rather than crashing with opaque stack traces.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
json-parse-better-errors15,106,32570-58 years agoMIT
json-parse-even-better-errors02710.2 kB14 months agoMIT

Deep Dive: json-parse-better-errors vs json-parse-even-better-errors

When building developer tools, build systems, or server-side applications in Node.js, handling configuration files is a daily reality. You will inevitably encounter malformed JSON. The native JSON.parse() method is strict and fast, but its error handling is notoriously unhelpful. It throws a generic SyntaxError that often points to the wrong line or gives a vague message like "Unexpected token in JSON at position 154." For a human trying to fix a config file, this is frustrating. For an automated tool, it makes debugging nearly impossible.

This is where json-parse-better-errors and its successor json-parse-even-better-errors come in. They wrap the native parser to catch these errors and enrich them with precise location data. Let's explore how they differ and why the evolution from one to the other matters for your architecture.

🚨 The Core Problem: Native Error Ambiguity

Before looking at the solutions, consider the baseline. If you parse a broken file with native Node.js, you get minimal context.

// Native Node.js behavior
const brokenJson = '{ "name": "test", }'; // Trailing comma

try {
  JSON.parse(brokenJson);
} catch (err) {
  console.log(err.message); 
  // Output: "Unexpected token } in JSON at position 16"
  // You have to manually count characters to find the issue.
}

Both libraries solve this by intercepting the error and calculating the exact line and column.

πŸ“¦ Input Flexibility: Strings vs Buffers

One of the most significant architectural improvements in json-parse-even-better-errors is how it handles input data. In real-world tooling, you often read files as Buffers or Uint8Arrays to handle encoding correctly or to avoid unnecessary string conversions.

json-parse-better-errors primarily expects a string. If you pass a Buffer, you typically need to convert it yourself before parsing, or the library might struggle depending on the version and environment.

// json-parse-better-errors usage
const parse = require('json-parse-better-errors');
const fs = require('fs');

// You must convert buffer to string manually for safety
const buffer = fs.readFileSync('config.json');
const data = parse(buffer.toString('utf8')); 
// Passing the buffer directly could lead to inconsistent behavior

json-parse-even-better-errors explicitly supports Buffers and Uint8Arrays out of the box. It handles the decoding internally, ensuring that the error position calculations remain accurate regardless of the input type. This reduces boilerplate in your file-reading logic.

// json-parse-even-better-errors usage
const parse = require('json-parse-even-better-errors');
const fs = require('fs');

// Directly pass the buffer - the library handles it
const buffer = fs.readFileSync('config.json');
const data = parse(buffer); 
// No manual .toString() needed, reducing potential encoding bugs

πŸ” Error Enrichment: Precision and Context

Both libraries augment the standard SyntaxError object, but the successor provides more robust metadata. When a parse failure occurs, you need to tell the user exactly where to look.

json-parse-better-errors adds line and column properties to the error object. It was a massive step forward when released.

// json-parse-better-errors error output
const parse = require('json-parse-better-errors');

try {
  parse('{ "key": undefined }');
} catch (err) {
  console.log(`Error at line ${err.line}, column ${err.column}`);
  console.log(err.message);
  // Provides basic location, but message formatting can vary by Node version
}

json-parse-even-better-errors refines this further. It ensures the error message itself is rewritten to include the location, making it consistent across different Node.js versions. It also handles complex Unicode characters more accurately when calculating column positions, which is crucial for internationalized config files.

// json-parse-even-better-errors error output
const parse = require('json-parse-even-better-errors');

try {
  parse('{ "key": undefined }');
} catch (err) {
  // The message is often rewritten to be more descriptive
  console.log(err.message); 
  // Output might look like: "Unexpected token 'u', ... is not valid JSON at line 1 column 10"
  console.log(`Precise location: ${err.line}:${err.column}`);
}

πŸ› οΈ Handling Edge Cases: Comments and Trailing Commas

It is important to clarify a common misconception: neither of these libraries enables non-standard JSON features like comments or trailing commas. They are strictly parsers for valid JSON that provide better error messages for invalid JSON. If you need to parse JSON5 (which allows comments), you would need a different library entirely.

However, json-parse-even-better-errors is more resilient when dealing with empty inputs or whitespace-only files, which often crash older parsers with confusing errors.

// Handling empty files
const parse = require('json-parse-even-better-errors');

try {
  // Passing an empty string or buffer
  parse(''); 
} catch (err) {
  // Provides a clear message like "Unexpected end of JSON input"
  // rather than a cryptic token error
  console.log(err.message);
}

πŸ—οΈ Architectural Recommendation

The choice between these two is clear for modern development. json-parse-better-errors served its purpose well during a specific era of the Node.js ecosystem. It fixed the immediate pain of opaque syntax errors. However, as file handling patterns evolved and the need for Buffer support grew, its limitations became apparent.

json-parse-even-better-errors is not just a minor update; it is a architectural improvement. It removes the need for pre-processing inputs (like converting Buffers to strings), handles Unicode edge cases that could previously throw off column counting, and provides a more consistent developer experience across different runtime versions.

If you are writing a new CLI tool, a bundler plugin, or any system that reads user-generated configuration files, json-parse-even-better-errors should be your default dependency. It reduces the surface area for bugs in your file-reading logic and ensures that when things go wrong, your users get the help they need immediately.

Only stick with json-parse-better-errors if you are locked into a legacy monorepo where upgrading the dependency chain introduces too much risk. In all other cases, the "even better" version is the professional standard.

How to Choose: json-parse-better-errors vs json-parse-even-better-errors

  • json-parse-better-errors:

    Choose json-parse-better-errors only if you are maintaining a legacy codebase that already depends on it and cannot afford the risk of refactoring. It is a stable, proven library for basic error enhancement but is no longer the recommended choice for new projects. Avoid using this package for new tooling, as it lacks support for modern input types like Buffers and may not handle certain Unicode edge cases as effectively as its successor. Its primary value today is backward compatibility in older versions of package managers or build scripts.

  • json-parse-even-better-errors:

    Choose json-parse-even-better-errors for all new projects, especially when building CLI tools, bundlers, or package managers that require robust error reporting. It offers superior handling of diverse input types, including Strings, Buffers, and Uint8Arrays, making it ideal for reading files directly from the filesystem without manual encoding. This package provides more detailed error contexts and is actively maintained to align with current Node.js behaviors. It is the definitive choice for developers who want to ensure their application fails gracefully and provides actionable feedback to users when configuration files are malformed.

README for json-parse-better-errors

json-parse-better-errors npm version license Travis AppVeyor Coverage Status

json-parse-better-errors is a Node.js library for getting nicer errors out of JSON.parse(), including context and position of the parse errors.

Install

$ npm install --save json-parse-better-errors

Table of Contents

Example

const parseJson = require('json-parse-better-errors')

parseJson('"foo"')
parseJson('garbage') // more useful error message

Features

  • Like JSON.parse, but the errors are better.

Contributing

The npm team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! The Contributor Guide has all the information you need for everything from reporting bugs to contributing entire new features. Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.

All participants and maintainers in this project are expected to follow Code of Conduct, and just generally be excellent to each other.

Please refer to the Changelog for project history details, too.

Happy hacking!

API

> parse(txt, ?reviver, ?context=20)

Works just like JSON.parse, but will include a bit more information when an error happens.