Start Debugging

System.Text.Json vs Newtonsoft.Json в 2026 году: что выбрать?

Для нового кода на .NET 11 выбирайте System.Text.Json: он встроен, примерно в 2 раза быстрее и единственный работает с Native AOT. К Newtonsoft.Json обращайтесь только ради JSONPath, TypeNameHandling или действительно нестрогого JSON.

Если в 2026 году вы начинаете новый код на .NET 11, используйте System.Text.Json. Он встроен в среду выполнения, сериализует примерно вдвое быстрее с малой долей аллокаций и является единственным из двух, кто работает под Native AOT. К Newtonsoft.Json обращайтесь только тогда, когда вы зависите от возможности, которой у System.Text.Json пока нет: запросы JSONPath, встраивание типов в стиле TypeNameHandling или разбор действительно некорректного JSON (одинарные кавычки, ключи без кавычек). Обе библиотеки живы в 2026 году, но для новой работы они уже не равны.

Каждый пример здесь нацелен на <TargetFramework>net11.0</TargetFramework> с SDK .NET 11 и C# 14. System.Text.Json — это встроенная версия, поставляемая с .NET 11. Newtonsoft.Json относится к версии 13.0.4, выпущенной 2025-12-30, текущей стабильной на NuGet.

Матрица возможностей с первого взгляда

Это та таблица, ради которой вы пришли. Это практическая версия официального руководства по миграции от Microsoft, сведённая к решениям, которые действительно меняют то, на какой пакет вы ссылаетесь.

АспектSystem.Text.Json (.NET 11)Newtonsoft.Json 13.0.4
ВстроенДа, часть среды выполненияНет, пакет NuGet
Пропускная способность (сериализация)База, самый быстрый~2x медленнее
АллокацииНа основе Span, низкиеВыше
Native AOT / trimmingДа, через генератор исходного кодаНет
Строгость по умолчаниюСтрогая (RFC 8259)Нестрогая
Комментарии / завершающие запятыеПо выборуВключено по умолчанию
Сопоставление без учёта регистраПо выбору (включено в ASP.NET Core)Включено по умолчанию
Полиморфная (де)сериализацияДа, с .NET 7 ([JsonDerivedType])Да (TypeNameHandling)
TypeNameHandling.All (встраивание типа CLR)Нет, by designДа
JSONPath / SelectTokenНетДа
DOM LINQ-to-JSONJsonNode / JsonDocumentJObject / JArray
DataTable, ExpandoObject, BigIntegerТребуется пользовательский конвертерВстроено
Одинарные кавычки, ключи без кавычекОтклоняются, by designПринимаются
Статус сопровожденияАктивная разработкаРежим сопровождения
ЛицензияMITMIT

Главное в том, что строки, где Newtonsoft.Json всё ещё выигрывает, узки и специфичны, тогда как строки, где выигрывает System.Text.Json (встроенность, AOT, скорость), применимы почти к любому новому проекту.

Когда выбирать System.Text.Json

Выбирайте его как вариант по умолчанию для всего нового на .NET 11. Конкретно:

Контекст, порождённый генератором исходного кода, — это паттерн, открывающий AOT и самый быстрый запуск:

// .NET 11, C# 14 - compile-time metadata, no runtime reflection
using System.Text.Json;
using System.Text.Json.Serialization;

[JsonSerializable(typeof(WeatherForecast))]
public partial class AppJsonContext : JsonSerializerContext;

var forecast = new WeatherForecast(DateOnly.FromDateTime(DateTime.Now), 22, "Mild");

// Pass the generated TypeInfo, not the raw type, to stay reflection-free
string json = JsonSerializer.Serialize(forecast, AppJsonContext.Default.WeatherForecast);

public record WeatherForecast(DateOnly Date, int TemperatureC, string Summary);

System.Text.Json также закрыл большинство исторических пробелов. С .NET 7 он выполняет полиморфную (де)сериализацию через [JsonDerivedType], а .NET 9 добавил несколько давно запрашиваемых опций: RespectNullableAnnotations для учёта ссылочных типов, не допускающих null, атрибут JsonStringEnumMemberName для переименования значений enum и JsonSchemaExporter для получения JSON-схемы из типа .NET. .NET 10 добавил прямую десериализацию из PipeReader и однострочный строгий пресет:

// .NET 10 and later - the strict, spec-compliant defaults in one preset
var options = JsonSerializerOptions.Strict;

// .NET 10 and later - deserialize straight from a PipeReader, no stream adapter
WeatherForecast? f = await JsonSerializer.DeserializeAsync<WeatherForecast>(pipeReader);

Когда выбирать Newtonsoft.Json

Реальные причины обратиться к нему всё ещё есть. Выбирайте Newtonsoft.Json, когда вы натыкаетесь на одно из следующего:

Разница в строгости по умолчанию — это то, что кусается при миграции. Одна и та же полезная нагрузка ведёт себя по-разному:

// Newtonsoft.Json 13.0.4 - lenient by default, this parses fine
using Newtonsoft.Json;

var config = JsonConvert.DeserializeObject<Config>("""
{
    "Name": "api", // inline comment
    "Retries": 3,
}
""");

public record Config(string Name, int Retries);
// .NET 11, System.Text.Json - strict by default, the same input throws JsonException
using System.Text.Json;

// You must opt in to match Newtonsoft.Json's leniency
var options = new JsonSerializerOptions
{
    ReadCommentHandling = JsonCommentHandling.Skip,
    AllowTrailingCommas = true,
    PropertyNameCaseInsensitive = true
};
var config = JsonSerializer.Deserialize<Config>(input, options);

Эта строгость — самый частый источник послемиграционного сюрприза, когда полезная нагрузка, работавшая годами, вдруг бросает исключение, что также объясняет, почему ошибки вроде значения JSON, которое не удалось преобразовать или DateTime, который не разбирается, появляются сразу после перехода.

Что на самом деле показывают бенчмарки

Производительность — это утверждение, которое легче всего отделать общими словами, поэтому здесь конкретные числа вместо слова «быстрее». Опубликованные прогоны BenchmarkDotNet на .NET 10, сериализующие коллекцию из 10 000 простых объектов POCO, показывают, что System.Text.Json завершает примерно за 3.7 мс, выделяя 3.4 МБ, против Newtonsoft.Json примерно за 7.6 мс и 8.1 МБ для той же нагрузки.

Метрика (сериализация 10 000 POCO)System.Text.JsonNewtonsoft.Json 13.x
Среднее время~3.7 мс~7.6 мс
Выделено~3.4 МБ~8.1 МБ
Относительно1.0x (база)~2.0x медленнее, ~2.4x память

Методология и оговорки важны, поэтому читайте эти числа честно:

Итог согласован по каждому заслуживающему доверия бенчмарку 2025 и 2026 годов: System.Text.Json примерно вдвое быстрее и выделяет от половины до трети для типичного случая. Запас не сузился в пользу Newtonsoft.Json.

Детали, которые решают за вас

Иногда одно ограничение закрывает решение ещё до того, как в комнату входят предпочтения.

Native AOT — это закрытые ворота. Если ваша цель развёртывания требует AOT (урезанный контейнер, функция со scale-to-zero, сборка iOS), Newtonsoft.Json просто не вариант. Он зависит от рефлексии в среде выполнения, которую AOT не предоставляет. Один этот факт дисквалифицирует его для целого класса современных нагрузок .NET.

Траектория сопровождения. Newtonsoft.Json не мёртв и не устарел. James Newton-King, который теперь работает в Microsoft над самим System.Text.Json, по-прежнему выпускает релизы безопасности и исправлений (13.0.4 вышла 2025-12-30). Но он явно в режиме сопровождения: никакой крупной работы над возможностями, никакой стратегии AOT впереди. System.Text.Json получает новые возможности в каждом релизе .NET. Ставить новый код на активно развивающуюся библиотеку — это выбор с меньшим риском для системы, которую вы будете сопровождать годами.

Обработка ссылок и циклы объектов различаются. У Newtonsoft.Json есть ReferenceLoopHandling и PreserveReferencesHandling. System.Text.Json отображает их на ReferenceHandler.IgnoreCycles и ReferenceHandler.Preserve, но поведение не идентично (IgnoreCycles пишет null там, где Newtonsoft.Json опускает свойство). Если вы сериализуете графы сущностей EF Core, это разница между чистой полезной нагрузкой и исключением о возможном цикле объектов. Знайте, какой обработчик вам нужен, до миграции.

Лицензии идентичны. Обе поставляются под MIT, поэтому в отличие от ситуации с MediatR или AutoMapper, лицензия здесь не фактор. Не позволяйте вопросу «бесплатен ли ещё Newtonsoft.Json?» вести решение: да, бесплатен, и System.Text.Json тоже.

Решение, в одну строку

Для нового кода на .NET 11 в 2026 году: по умолчанию используйте System.Text.Json, и добавляйте Newtonsoft.Json только тогда, когда натыкаетесь на конкретную, поименованную возможность, которой он не умеет (JSONPath, TypeNameHandling, нестрогий разбор или неподдерживаемый тип без конвертера). Он встроен, быстрее, готов к AOT и это то, что Microsoft продолжает строить. Оставьте Newtonsoft.Json в существующих системах, которые зависят от его гибкости; не торопите миграцию, у которой нет выгоды, но и не начинайте с него. Стратегический выбор по умолчанию сменился годы назад, и в 2026 году разрыв достаточно широк, чтобы бремя доказательства лежало на выборе Newtonsoft.Json, а не на выборе встроенной библиотеки.

Связанное

Источники

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад