Start Debugging

System.Text.Json vs Newtonsoft.Json en 2026: ¿cuál deberías elegir?

Elige System.Text.Json para código nuevo en .NET 11: viene integrado, es aproximadamente 2 veces más rápido y es el único que funciona con Native AOT. Recurre a Newtonsoft.Json solo para JSONPath, TypeNameHandling o JSON realmente permisivo.

Si estás empezando código nuevo en .NET 11 en 2026, usa System.Text.Json. Viene integrado con el runtime, serializa aproximadamente al doble de velocidad con una fracción de las asignaciones de memoria y es el único de los dos que se ejecuta bajo Native AOT. Recurre a Newtonsoft.Json solo cuando dependas de una característica que System.Text.Json todavía no tiene: consultas JSONPath, incrustación de tipos al estilo TypeNameHandling, o el análisis de JSON realmente malformado (comillas simples, claves sin comillas). Ambas bibliotecas siguen vivas en 2026, pero ya no son equivalentes para trabajo nuevo.

Cada ejemplo aquí apunta a <TargetFramework>net11.0</TargetFramework> con el SDK de .NET 11 y C# 14. System.Text.Json es la versión integrada que viene con .NET 11. Newtonsoft.Json se refiere a la versión 13.0.4, publicada el 2025-12-30, la estable actual en NuGet.

La matriz de características de un vistazo

Esta es la tabla que viniste a buscar. Es la versión práctica de la guía oficial de migración de Microsoft, reducida a las decisiones que de verdad cambian a qué paquete haces referencia.

AspectoSystem.Text.Json (.NET 11)Newtonsoft.Json 13.0.4
Viene integradoSí, parte del runtimeNo, paquete de NuGet
Rendimiento (serializar)Base, el más rápido~2x más lento
Asignaciones de memoriaBasadas en Span, bajasMás altas
Native AOT / trimmingSí, vía generador de código fuenteNo
Permisividad por defectoEstricta (RFC 8259)Permisiva
Comentarios / comas finalesOpcionalActivado por defecto
Coincidencia sin distinción de mayúsculasOpcional (activado en ASP.NET Core)Activado por defecto
(De)serialización polimórficaSí, desde .NET 7 ([JsonDerivedType])Sí (TypeNameHandling)
TypeNameHandling.All (incrustar tipo CLR)No, por diseño
JSONPath / SelectTokenNo
DOM LINQ-to-JSONJsonNode / JsonDocumentJObject / JArray
DataTable, ExpandoObject, BigIntegerRequiere convertidor personalizadoIntegrado
Comillas simples, claves sin comillasRechazadas, por diseñoAceptadas
Estado de mantenimientoDesarrollo activoModo de mantenimiento
LicenciaMITMIT

El titular es que las filas donde Newtonsoft.Json todavía gana son estrechas y específicas, mientras que las filas donde gana System.Text.Json (integrado, AOT, velocidad) se aplican a casi cualquier proyecto nuevo.

Cuándo elegir System.Text.Json

Elígelo como opción por defecto para cualquier cosa nueva en .NET 11. En concreto:

Un contexto generado por código fuente es el patrón que desbloquea AOT y el arranque más rápido:

// .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 también ha cerrado la mayoría de las brechas históricas. Desde .NET 7 hace (de)serialización polimórfica mediante [JsonDerivedType], y .NET 9 agregó varias opciones largamente solicitadas: RespectNullableAnnotations para respetar los tipos de referencia no anulables, el atributo JsonStringEnumMemberName para renombrar valores de enum, y JsonSchemaExporter para producir un esquema JSON a partir de un tipo de .NET. .NET 10 agregó la deserialización directa desde un PipeReader y un preset estricto de una línea:

// .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);

Cuándo elegir Newtonsoft.Json

Todavía hay razones reales para recurrir a él. Elige Newtonsoft.Json cuando te topes con una de estas:

La diferencia de permisividad por defecto es la que muerde durante una migración. La misma carga útil se comporta de forma distinta:

// 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);

Esa rigurosidad es la fuente más común de la sorpresa posterior a la migración en la que una carga útil que funcionó durante años de repente lanza una excepción, que es también la razón por la que errores como un valor JSON que no se pudo convertir o un DateTime que no se analiza aparecen justo después de un cambio.

Qué muestran realmente los benchmarks

El rendimiento es la afirmación más fácil de despachar con vaguedades, así que aquí van números concretos en lugar de la palabra “más rápido”. Ejecuciones publicadas de BenchmarkDotNet en .NET 10 serializando una colección de 10 000 objetos POCO simples muestran que System.Text.Json termina en alrededor de 3.7 ms asignando 3.4 MB, frente a Newtonsoft.Json en alrededor de 7.6 ms y 8.1 MB para la misma carga de trabajo.

Métrica (serializar 10 000 POCOs)System.Text.JsonNewtonsoft.Json 13.x
Tiempo medio~3.7 ms~7.6 ms
Asignado~3.4 MB~8.1 MB
Relativo1.0x (base)~2.0x más lento, ~2.4x memoria

La metodología y las advertencias importan, así que lee estos números con honestidad:

El resumen es consistente en cada benchmark creíble de 2025 y 2026: System.Text.Json es aproximadamente el doble de rápido y asigna entre la mitad y un tercio para el caso común. El margen no se ha estrechado a favor de Newtonsoft.Json.

Los detalles que deciden por ti

A veces una sola restricción zanja la decisión antes de que entren las preferencias.

Native AOT es una puerta cerrada. Si tu objetivo de despliegue requiere AOT (un contenedor recortado, una función con escalado a cero, una build de iOS), Newtonsoft.Json simplemente no es una opción. Depende de reflexión en tiempo de ejecución que AOT no proporciona. Este único hecho lo descalifica para toda una clase de cargas de trabajo modernas de .NET.

Trayectoria de mantenimiento. Newtonsoft.Json no está muerto ni obsoleto. James Newton-King, que ahora trabaja en Microsoft en el propio System.Text.Json, todavía publica versiones de seguridad y corrección de errores (la 13.0.4 llegó el 2025-12-30). Pero está explícitamente en modo de mantenimiento: ningún trabajo importante de características, ninguna estrategia de AOT en camino. System.Text.Json recibe nuevas capacidades en cada versión de .NET. Apostar el código nuevo a la biblioteca que evoluciona activamente es la opción de menor riesgo para un sistema que mantendrás durante años.

El manejo de referencias y los ciclos de objetos difieren. Newtonsoft.Json tiene ReferenceLoopHandling y PreserveReferencesHandling. System.Text.Json los mapea a ReferenceHandler.IgnoreCycles y ReferenceHandler.Preserve, pero el comportamiento no es idéntico (IgnoreCycles escribe null donde Newtonsoft.Json descarta la propiedad). Si serializas grafos de entidades de EF Core, esta es la diferencia entre una carga útil limpia y una excepción de posible ciclo de objetos. Sabe qué manejador necesitas antes de migrar.

Las licencias son idénticas. Ambas se distribuyen bajo MIT, así que a diferencia de la situación de MediatR o AutoMapper, la licencia no es un factor aquí. No dejes que “¿sigue siendo gratis Newtonsoft.Json?” conduzca la decisión: lo es, y System.Text.Json también.

La decisión, en una línea

Para código nuevo en .NET 11 en 2026: usa System.Text.Json por defecto, y agrega Newtonsoft.Json solo cuando te topes con una característica concreta y con nombre que no puede hacer (JSONPath, TypeNameHandling, análisis permisivo, o un tipo no soportado sin convertidor). Viene integrado, es más rápido, está listo para AOT y es el que Microsoft sigue construyendo. Mantén Newtonsoft.Json en sistemas existentes que dependan de su flexibilidad; no apresures una migración que no tiene recompensa, pero tampoco empieces ahí. El valor por defecto estratégico cambió hace años, y en 2026 la brecha es lo bastante amplia como para que la carga de la prueba recaiga en elegir Newtonsoft.Json, no en elegir la biblioteca integrada.

Relacionado

Fuentes

Comments

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

< Volver