JSON Toolkit

Сравнение библиотек разбора и обработки JSON

Главное: Нативные API работают быстрее всего, терпимые парсеры дают смещения. Выбирайте по трём вещам: указание места ошибки, сохранение исходного текста и явность границ.

Средний~11 мин чтенияОпубликовано 2026-10-30Обновлено 2026-10-30
Обложка сравнения библиотек разбора и обработки JSON

Коротко: сначала определите категорию потребности, затем сравнивайте реализации — используйте нативный JSON.parse для чтения значений, jsonc-parser, когда нужны смещения или сохранение исходного форматирования, а библиотеки запросов и патчей подключайте только там, где они нужны; большие библиотеки загружайте лениво по страницам и избавляйтесь от неподдерживаемых.

Каждая библиотека утверждает, что она «быстрая, маленькая и полная». На самом деле отличает их то, сколько информации они дают, когда что-то идёт не так.

1. Четыре категории по назначению

Категория Представители Что решает
Стандартный разбор JSON.parse / JSON.stringify Синтаксис ↔ объект, скорость на первом месте
Терпимый разбор + редактирование jsonc-parser, json5 Ввод с комментариями, ошибки с точностью до смещения, изменения с сохранением форматирования
Запросы jsonpath-plus, jsonpath Выбор узлов по выражению
Изменения fast-json-patch, immer Генерация/применение патчей, иммутабельные обновления

Сначала определите, к какой категории относится ваша задача, и лишь затем сравнивайте конкретные реализации — иначе легко использовать библиотеку запросов для работы парсера.

2. Сопоставление

Библиотека Место ошибки Терпимость (комментарии/завершающие запятые) Сохраняет исходное форматирование Подходящие сценарии
JSON.parse Только сообщение и позиция (зависит от движка) ✗ ✗ Обычный разбор, данные API
jsonc-parser Точный offset + код ошибки ✓ ✓ (modify + applyEdits) Редакторы, конфигурационные файлы
json5 Информация о строке и столбце ✓ (более снисходительный) ✗ Чтение конфигурации JSON5
jsonlint Информация о строке и столбце ✗ ✗ Только для справки, активно не поддерживается
jsonpath-plus Ошибки синтаксиса выражений — — Запросы по выражению
fast-json-patch Ошибки уровня операций — — Генерация и применение патчей
lz-string — — — Сжатие JSON в URL

Сообщения об ошибках JSON.parse сильно различаются между движками. V8 выдаёт что-то вроде Unexpected token } in JSON at position 42, но точность позиции зависит от версии движка; jsonc-parser вместо этого возвращает стабильную структуру { error, offset, length }, которая подходит для маркеров редактора.

3. Четыре ключевые точки решения

3.1 Нужны ли смещения

Если вы строите редактор и хотите «клик по ошибке переводит к соответствующей строке», смещение обязательно. Проверка проста: если ваше сообщение об ошибке умеет печатать только «недопустимый JSON», пользователям придётся искать самостоятельно.

import { parse, printParseErrorCode } from 'jsonc-parser';

const errors: Array<{ error: number; offset: number; length: number }> = [];
parse(text, errors, { allowTrailingComma: true, disallowComments: false });

if (errors.length > 0) {
  const firstError = errors[0];
  console.error(`${printParseErrorCode(firstError.error)} at offset ${firstError.offset}`);
}

3.2 Нужно ли сохранять исходный текст

Только чтение значений → подойдёт любой парсер. «Изменить одно поле и оставить всё остальное точно как было» → нужно использовать API в стиле редактирования, а не «разобрать → изменить объект → сериализовать».

Последний путь теряет: комментарии, порядок ключей (в некоторых реализациях), стиль отступов, запись числовых литералов (1e3 становится 1000) и формы экранирования (\u4e2d становится фактическим символом).

3.3 Явны ли граничные поведения

Прежде чем выбрать библиотеку, проверьте в документации три вещи:

  1. Как обрабатываются повторяющиеся ключи (сохраняется последний / выбрасывается ошибка);
  2. Теряют ли большие целые точность (большинство JS-библиотек теряет, потому что все проходят через Number);
  3. Поддерживаемый объём для BOM, комментариев и завершающих запятых.

Если документации нет, напишите маленький пример и проверьте сами. Это надёжнее, чем читать README.

3.4 Состояние поддержки

Риск библиотеки JSON — не отсутствие функций, а долгое пренебрежение: никто больше не выпустит патчи безопасности (prototype pollution, ReDoS).

4. Сравнение с другими языками

Язык Стандартная / основная библиотека Ключевое отличие
JavaScript JSON.parse Все числа двойной точности
TypeScript То же + jsonc-parser / zod Типы существуют только на этапе компиляции
Go encoding/json По умолчанию float64, используйте UseNumber() для точности; json.RawMessage для отложенного разбора
Java Jackson / Gson / Moshi С Jackson остерегайтесь риска включения default typing
Python json / orjson parse_float=Decimal сохраняет точность; orjson быстрее, но поддерживает не все типы
Rust serde_json Строго типизированная десериализация; функция arbitrary_precision сохраняет точность
C++ simdjson / RapidJSON simdjson ориентирован на пропускную способность разбора, RapidJSON более универсален

При обмене данными между языками проще всего споткнуться о точность чисел и форматы времени; выбор библиотеки может их смягчить, но не устранить.

5. Типичные комбинации

Вариант 1: сайт-инструмент (сторона браузера)

Parsing and error location: jsonc-parser
Editor: CodeMirror 6 + @codemirror/lang-json
Query: jsonpath-plus
Patch: fast-json-patch
Share links: lz-string

Определяющая черта этой комбинации — всё работает локально и никакие данные не загружаются, что соответствует ожиданиям утилитарного сайта в отношении приватности.

Вариант 2: серверный шлюз API

Validation: Ajv (compile the schema once, reuse it)
Parsing: native JSON.parse (together with a body size limit)
Deferred parsing of large fields: keep the raw string, parse only when needed

Не вводите библиотеки запросов и патчей в слой шлюза для реализации бизнес-логики — это работа бизнес-слоя.

Вариант 3: CLI и скрипты

Pick fields: jq
Format conversion: yq / dasel
Interactive browsing: jless
Batch validation: ajv-cli

6. Реальное влияние размера пакета и производительности

  • jsonc-parser очень мал и подходит для основного пакета;
  • json5 немного больше jsonc-parser, потому что поддерживает больше синтаксиса;
  • jsonpath-plus включает вычисление выражений и заметно больше, поэтому его следует загружать лениво по страницам;
  • fast-json-patch имеет средний размер и нужен, только когда есть функция сравнения.

Оптимизация проста: импортируйте динамически по страницам и не помещайте их в чанк первого экрана.

const { JSONPath } = await import('jsonpath-plus');

7. Чек-лист

  • [ ] Библиотеки выбираются по назначению; не используйте библиотеку запросов для разбора;
  • [ ] Используйте jsonc-parser, когда нужны точные места ошибок;
  • [ ] Используйте API в стиле редактирования, когда нужно сохранить комментарии и форматирование;
  • [ ] Проверьте на практике три граничных поведения: повторяющиеся ключи, большие целые и BOM;
  • [ ] Следите за состоянием поддержки библиотеки и уведомлениями о безопасности;
  • [ ] Динамически импортируйте большие библиотеки по требованию.

Вопросы и ответы

Как выбрать библиотеку JSON под размер проекта?

Небольшие инструменты, которые только читают данные API, могут остаться на нативном JSON.parse. Проектам, которым нужны места ошибок уровня редактора или сохранение исходного форматирования, стоит использовать jsonc-parser. Серверному шлюзу нужны только валидация и разбор, а библиотеки запросов и патчей остаются бизнес-слою, тогда как CLI-скрипты могут напрямую использовать jq, yq и ajv-cli.

Почему состояние поддержки важнее количества функций?

Настоящий риск библиотеки JSON — долгое пренебрежение, а не отсутствие функций: никто не выпустит патчи безопасности для prototype pollution или ReDoS. Каким бы полным ни был список функций, заглохшая библиотека оставляет вас патчить её самостоятельно. Относитесь к поддержке и уведомлениям о безопасности как к жёстким критериям, а не сравнивайте таблицы функций.

Стоит ли использовать JSON.parse, чтобы изменить одно поле и сохранить комментарии и отступы?

Нет. Разбор, изменение объекта и последующая сериализация теряют комментарии, порядок ключей, стиль отступов, запись числовых литералов (1e3 становится 1000) и формы экранирования (\u4e2d становится фактическим символом). Изменение одного поля с сохранением всего остального требует API в стиле редактирования, например modify и applyEdits в jsonc-parser.