Cómo Douglas Crockford popularizó JSON y por qué se convirtió en el lenguaje por defecto para apps web y APIs—más consejos prácticos para usar JSON bien hoy.

JSON (JavaScript Object Notation) es una forma ligera de representar datos como texto plano usando pares clave–valor y listas.
Si construyes aplicaciones web—even si no piensas mucho en “formatos de datos”—JSON probablemente sea ya el pegamento que mantiene tu producto unido. Es cómo el frontend solicita datos, cómo responde el backend, cómo las apps móviles sincronizan estado y cómo los servicios de terceros envían eventos. Cuando JSON es claro y consistente, los equipos entregan más rápido; cuando está desordenado, cada función tarda más porque todos discuten sobre lo que los datos “significan”.
Aquí tienes un pequeño objeto JSON que puedes leer de un vistazo:
{
"userId": 42,
"name": "Sam",
"isPro": true,
"tags": ["beta", "newsletter"]
}
Incluso sin contexto técnico, normalmente puedes inferir qué está pasando: un usuario tiene un ID, un nombre, una bandera de estado y una lista de etiquetas.
Aprenderás:
El objetivo es simple: ayudarte a entender no solo qué es JSON, sino por qué casi todas las apps “lo hablan” y cómo evitar los errores comunes que los equipos siguen repitiendo.
Douglas Crockford no “inventó” todas las ideas detrás de JSON, pero hizo algo igual de importante: hizo visible un patrón simple y funcional, le puso nombre y lo impulsó hacia el mainstream.
En los primeros días de las aplicaciones web, los equipos lidiaban con opciones incómodas para mover datos entre navegador y servidor. XML era común pero verboso. Formatos personalizados basados en delimitadores eran compactos pero frágiles. JavaScript técnicamente podía evaluar datos como código, pero eso difuminaba la línea entre “datos” y “script ejecutable”, lo que era una receta para errores y problemas de seguridad.
Crockford vio un camino más limpio: usar un subconjunto pequeño de la sintaxis literal de JavaScript que pudiera representar datos planos de forma fiable—objetos, arrays, strings, números, booleanos y null—sin características adicionales.
Una de las mayores contribuciones de Crockford fue social, no técnica: lo llamó JSON (Notación de Objetos de JavaScript) y publicó documentación clara en json.org. Eso dio a los equipos un vocabulario compartido (“enviamos JSON”) y una referencia lo bastante corta para leer y lo bastante estricta para implementar.
También promovió JSON como un formato de datos independiente de JavaScript como lenguaje de programación: muchos lenguajes podían analizarlo y generarlo, y se mapeaba de forma natural a las estructuras de datos comunes.
La adopción se acelera cuando los equipos sienten que pueden apostar por un formato a largo plazo. JSON ganó gradualmente ese estatus de “apuesta segura” mediante hitos ampliamente conocidos:
La defensa de Crockford, combinada con estos estándares y un ecosistema creciente de parsers, ayudó a que JSON pasara de una convención útil a la forma predeterminada en que las apps hablan—especialmente a través de APIs HTTP (tema que se cubre más adelante en /blog/json-and-apis).
Antes de que JSON se convirtiera en la forma predeterminada de mover datos, la web dependía de una mezcla de formatos que eran o bien demasiado pesados, demasiado inconsistentes o tan personalizados que no escalaban entre equipos.
XML fue la gran elección “estándar”. Funcionaba entre lenguajes, tenía herramientas y podía representar estructuras anidadas. También traía mucha ceremonia.
Al mismo tiempo, muchas apps enviaban datos como query strings personalizadas (especialmente en las primeras solicitudes estilo AJAX): pares clave/valor metidos en URLs o cuerpos POST. Otras inventaron formatos de texto ad hoc—una lista separada por comas aquí, un blob delimitado por pipes allá—con reglas de escape hechas a mano que solo un desarrollador entendía.
Los problemas no eran teóricos:
La mayoría de las apps no necesitan un formato que pueda expresar toda posible estructura de documento. Necesitan una forma predecible de enviar objetos, arrays, strings, números y booleanos—rápida, consistente y con poco margen de interpretación. Los formatos más simples reducen la cantidad de decisiones (y errores) que los equipos toman por endpoint.
<user>
<id>42</id>
<name>Ada</name>
<isActive>true</isActive>
</user>
{
"id": 42,
"name": "Ada",
"isActive": true
}
Ambos expresan la misma idea, pero JSON es más fácil de leer, más fácil de generar y está más cerca de cómo la mayoría de las aplicaciones ya modelan datos en memoria.
La permanencia de JSON no es accidental. Tiene éxito porque es deliberadamente pequeño: lo justo para representar datos de aplicación reales sin invitar a variaciones infinitas.
JSON te da un kit mínimo que se mapea limpiamente a cómo la mayoría de las apps piensan sobre los datos:
name, email)true/falseEso es todo. Nada de fechas, comentarios, tipos numéricos personalizados ni referencias. Esta simplicidad hace que JSON sea fácil de implementar en todos los lenguajes y plataformas.
JSON es lo bastante legible para que las personas lo escaneen en logs y respuestas de API, al tiempo que sigue siendo fácil de parsear rápidamente por máquinas. Evita ceremonias extras, pero mantiene delimitadores claros ({}, [], :) para que los parsers sean rápidos y fiables.
La contrapartida: dado que JSON es tan minimalista, los equipos deben ponerse de acuerdo en convenciones para cosas como timestamps, dinero e identificadores (por ejemplo, strings ISO-8601 para fechas).
Las reglas estrictas de JSON (strings entre comillas dobles, no comas finales, conjunto fijo de tipos) reducen la ambigüedad. Menos ambigüedad significa menos fallos tipo “funciona en mi máquina” cuando distintos sistemas intercambian datos.
JSON se parece a la sintaxis de objetos de JavaScript, pero JSON no es JavaScript. Es un formato de datos independiente del lenguaje con sus propias reglas, usable desde Python, Java, Go, Ruby y cualquier otro sitio que necesite serialización e interoperabilidad consistentes.
JSON no ganó porque fuera el formato más completo. Ganó porque encajaba con la forma en que ya se construían las apps web: un navegador con mucho JavaScript hablando con un servidor mediante solicitudes HTTP sencillas.
Una vez que los navegadores se estandarizaron en torno a JavaScript, el lado cliente tenía una manera integrada de representar datos estructurados: objetos, arrays, strings, números, booleanos y null. JSON reflejaba esos primitivos de forma muy cercana, así que mover datos entre “lo que el navegador entiende” y “lo que envía el servidor” se sentía natural.
Las primeras apps estilo Ajax aceleraron esto. En lugar de devolver páginas HTML completas, los servidores podían devolver una carga pequeña para que la UI la renderizara. Una respuesta como esta era inmediatamente útil:
{
"user": {"id": 42, "name": "Sam"},
"unreadCount": 3
}
Aunque la sintaxis de JSON se parece a JavaScript, es neutral respecto al lenguaje. En cuanto servidores y clientes en otros lenguajes necesitaron interoperar con frontends web, aparecieron librerías JSON—y rápidamente se convirtieron en “equipo estándar”. Parsear una cadena JSON a estructuras nativas suele ser una llamada a función; generar JSON es igual de simple.
Una vez que frameworks, clientes de API, depuradores, proxies y herramientas de documentación asumieron JSON, elegir otra cosa creaba fricción. Los desarrolladores podían inspeccionar cargas en las devtools del navegador, copiar/pegar ejemplos en tests y confiar en librerías maduras para codificar, decodificar y manejar errores.
Una sola respuesta JSON puede servir una UI web, una app móvil, un servicio interno y una integración de terceros con mínimas modificaciones. Esa interoperabilidad convirtió a JSON en una apuesta segura para equipos que construyen “un backend, muchas interfaces” y ayudó a que se convirtiera en el contrato predeterminado entre cliente y servidor.
JSON no ganó por ser vistoso: encajó perfectamente con cómo ya funcionaba la web. HTTP está construido alrededor de enviar una petición y recibir una respuesta, y JSON es una forma fácil y predecible de representar el “body” de esa respuesta (o petición) como datos estructurados.
Una petición de API suele incluir un método y una URL (por ejemplo, GET /users?limit=20). El servidor responde con un código de estado (como 200 o 404), cabeceras y un body opcional.
Cuando el body es JSON, una cabecera clave es:
Content-Type: application/jsonEsa cabecera le dice a los clientes cómo interpretar los bytes que reciben. En la dirección de entrada (cliente → servidor), enviar Content-Type: application/json señala “estoy enviando JSON” y los servidores pueden parsearlo de forma consistente.
JSON funciona especialmente bien para patrones repetidos que aparecen en muchas APIs.
Paginación a menudo envuelve una lista con metadatos:
{
"data": [{"id": 1, "name": "A"}],
"pagination": {"limit": 20, "offset": 0, "total": 153}
}
Filtrado y ordenación generalmente ocurren en la query string de la URL, mientras los resultados permanecen como un array JSON (o un campo data). Por ejemplo: GET /orders?status=paid&sort=-created_at.
Respuestas de error se benefician de una forma estándar para que los clientes puedan mostrar mensajes y manejar reintentos:
{
"error": {
"code": "invalid_request",
"message": "limit must be between 1 and 100",
"details": {"field": "limit"}
}
}
El encaje práctico es simple: HTTP proporciona entrega y significado (verbos, códigos de estado, cacheo), mientras JSON proporciona una estructura ligera y legible para los datos en sí.
Cuando la gente compara JSON y XML, a menudo en realidad compara “datos para apps” frente a “documentos”. Ambos formatos pueden representar información estructurada, pero JSON tiende a coincidir con lo que la mayoría de las aplicaciones realmente mueven: objetos simples, listas, strings, números, booleanos y null.
XML es verboso por diseño. Repetir etiquetas de apertura y cierre hace que las cargas sean más grandes y más difíciles de escanear en logs o inspectores de red. JSON normalmente transmite el mismo significado con menos caracteres y menos desorden visual, lo que ayuda al depurar y puede reducir costes de ancho de banda a escala.
No se trata solo de estética: cargas más pequeñas suelen significar transferencias más rápidas y menos trabajo para parsers y proxies.
La mayoría de los datos de app se parecen naturalmente a diccionarios (maps) y arrays (listas): un usuario con atributos, una orden con líneas, una página con componentes. JSON se mapea directamente a ese modelo mental y coincide con estructuras nativas en JavaScript y la mayoría de lenguajes modernos.
XML puede representar las mismas estructuras, pero suele requerir convenciones: atributos vs elementos, elementos hijo repetidos para listas y reglas extra para “qué cuenta como número” (ya que todo es texto a menos que añadas tipado encima).
XML sigue siendo fuerte para casos centrados en documentos: contenido mixto (texto entre marcado), flujos de publicación y ecosistemas con herramientas maduras de XML (por ejemplo, ciertas integraciones empresariales). Si tu payload está más cerca de un documento que de un grafo de objetos, XML puede encajar mejor.
Si tu objetivo principal es intercambiar datos de aplicación entre frontend, backend y APIs, JSON suele ser la opción más simple y directa. Si necesitas marcado de documentos, contenido mixto o integrarte en un dominio centrado en XML, XML puede ser la herramienta adecuada.
JSON se parece a “objetos JavaScript”, así que los equipos a menudo asumen que pueden tratarlo como JavaScript. Ahí es donde aparecen bugs: JSON es más estricto, más pequeño y menos indulgente.
Unos cuantos problemas tipo “funciona en mi máquina” aparecen una y otra vez:
{name: "Ada"} no es JSON; { "name": "Ada" } sí lo es.{ "a": 1, } fallará en muchos parsers.// y /* ... */ son inválidos. Si necesitas notas, mantenlas en la documentación o usa un campo separado (con cuidado) durante el desarrollo.Estas restricciones son intencionales: mantienen los parsers simples y consistentes entre lenguajes.
JSON tiene solo un tipo numérico: number. No hay integer, decimal o fecha nativos.
"19.99") para evitar diferencias de redondeo entre sistemas."2025-12-26T10:15:30Z"). Evita formatos de fecha personalizados que requieran adivinanza.JSON es Unicode, pero los sistemas reales todavía tropiezan con codificación y escape:
" y barras invertidas \\).Siempre parsea JSON con un parser real (JSON.parse o el equivalente en tu lenguaje). Evita cualquier enfoque tipo eval, aunque “parezca más rápido”. Y valida las entradas en los límites—especialmente para APIs públicas—para que campos o tipos inesperados no se filtren a la lógica de negocio.
Una carga JSON no es solo “datos en tránsito”: es una interfaz a largo plazo entre equipos, sistemas y tu yo del futuro. La diferencia entre una carga que dura y otra que se reescribe cada trimestre suele ser disciplina aburrida: consistencia, gestión cuidadosa del cambio y casos límite predecibles.
Elige reglas de nombrado y apégate a ellas en todas partes:
camelCase o snake_case) y no mezcles.userId a id es un cambio rompedor aunque el significado parezca “obvio”."count": 3 vs "count": "3") causará bugs difíciles de rastrear.Puedes evitar la mayoría de guerras de versiones haciendo cambios aditivos:
/v2/...) o incluye una señal de versión en una cabecera—no cambies silenciosamente la semántica.Los clientes manejan fallos mejor cuando los errores comparten una forma uniforme:
{
"error": {
"code": "INVALID_ARGUMENT",
"message": "email must be a valid address",
"details": { "field": "email" }
}
}
La buena documentación JSON incluye ejemplos reales—respuestas exitosas y fallidas—con campos completos. Mantén los ejemplos sincronizados con el comportamiento en producción y señala qué campos son opcionales, anulables o deprecados. Cuando los ejemplos coinciden con las respuestas reales, las integraciones van más rápido y se rompen menos.
Si usas un flujo de trabajo de tipo "vibe-coding" para lanzar nuevas funciones rápidamente, los contratos JSON se vuelven aún más importantes: la iteración rápida es genial hasta que los clientes y servicios se desalinean.
En Koder.ai, los equipos suelen generar un frontend en React más un backend en Go + PostgreSQL y luego iterar las formas de la API en modo de planificación antes de fijarlas. Funciones como instantáneas y reversión ayudan cuando un pequeño cambio JSON resulta ser rompedor, y la exportación de código fuente facilita mantener el contrato en tu repositorio y aplicarlo con tests.
JSON es fácil de generar, lo que es tanto su fuerza como su trampa. Si un servicio envía "age": "27" (string) y otro espera 27 (número), nada en JSON lo evitará. El resultado suele ser el peor tipo de bug: un fallo de cliente en producción o un fallo sutil de UI que solo ocurre con ciertos datos.
La validación consiste en detectar datos malos o inesperados antes de que lleguen a quienes dependen de ellos: tu frontend, integraciones, canal de analytics o apps móviles.
Puntos de fallo comunes incluyen campos requeridos faltantes, claves renombradas, tipos incorrectos y valores “casi correctos” (como fechas en formatos inconsistentes). Un pequeño paso de validación en el límite de la API puede convertir estos problemas en mensajes de error claros en lugar de caídas.
JSON Schema es una forma estándar de describir cómo debería verse tu JSON: propiedades requeridas, tipos permitidos, enums, patrones y más. Es más útil cuando:
Con un esquema puedes validar peticiones en el servidor, validar respuestas en tests y generar documentación. Muchos equipos lo emparejan con su documentación de API (a menudo via OpenAPI), de modo que el contrato es explícito en lugar de “conocimiento tribal”. Si ya publicas docs para desarrolladores, enlazar ejemplos de esquema desde /docs puede mantener las cosas coherentes.
No todos los equipos necesitan herramientas completas de esquema desde el día uno. Opciones prácticas incluyen:
Una regla útil: empieza con ejemplos y tests de contrato, luego añade JSON Schema cuando los cambios y las integraciones empiecen a multiplicarse.
JSON se siente “ligero” cuando envías unos pocos campos. A escala—clientes móviles en redes inestables, APIs de alto tráfico, páginas con mucha analítica—JSON puede convertirse en un problema de rendimiento o un riesgo de fiabilidad si no lo das forma y lo envías con cuidado.
El problema de escalado más común no es el parsing de JSON: es enviar demasiado.
La paginación es la victoria sencilla: devuelve fragmentos predecibles (por ejemplo, limit + cursor) para que los clientes no descarguen miles de registros a la vez. Para endpoints que devuelven objetos anidados, considera respuestas parciales: permite al cliente pedir solo lo que necesita (campos seleccionados o expansiones “include”). Esto evita el “overfetching”, cuando una pantalla solo necesita name y status pero recibe todos los detalles históricos y campos de configuración.
Una regla práctica: diseña respuestas alrededor de acciones de usuario (lo que una pantalla necesita ahora), no alrededor de lo que tu base de datos puede hacer con joins.
Si tu API sirve respuestas JSON grandes, la compresión puede reducir dramáticamente el tamaño de transferencia. Muchos servidores pueden gzip o brotli automáticamente, y la mayoría de clientes lo manejan sin código extra.
El cache es la otra palanca. A alto nivel, apunta a:
Esto reduce descargas repetidas y suaviza picos de tráfico.
Para salidas muy grandes—exportaciones, feeds de eventos, syncs masivos—considera respuestas en streaming o parsing incremental para que los clientes no tengan que cargar un documento entero en memoria antes de hacer algo útil. No es necesario para la mayoría de apps, pero es una opción valiosa cuando “un gran blob JSON” empieza a hacer timeouts.
JSON es fácil de loggear, lo que es útil y peligroso. Trata los logs como una superficie de producto:
Hecho bien, depurarás más rápido y reducirás el riesgo de exposición accidental de datos.
JSON no está “terminado”: está estable. Lo que cambia ahora es el ecosistema a su alrededor: editores más potentes, mejor validación, contratos de API más seguros y más herramientas que ayudan a los equipos a evitar cambios rompientes accidentales.
JSON probablemente seguirá siendo el formato por defecto para la mayoría de apps web y móviles porque está ampliamente soportado, es fácil de depurar y se mapea limpiamente a estructuras comunes.
El cambio más grande es hacia APIs tipadas: los equipos siguen enviando JSON, pero lo definen con mayor precisión usando herramientas como JSON Schema, OpenAPI y generadores de código. Eso significa menos momentos de “adivina la forma”, mejor autocompletado y detección temprana de errores—sin abandonar JSON.
Cuando necesitas enviar o almacenar muchos registros eficientemente (logs, eventos analíticos, exportaciones), un array JSON gigante puede ser incómodo. JSON Lines (también llamado NDJSON) lo soluciona poniendo un objeto JSON por línea. Se transmite bien, puede procesarse línea a línea y encaja con herramientas de línea de comandos.
Usa esto como un chequeo rápido antes de lanzar cargas que vivirán más que un sprint:
2025-12-26T10:15:00Z).null y documenta tu elección.Si quieres profundizar, mira las guías relacionadas en /blog—especialmente temas como validación de esquemas, versionado de APIs y diseñar cargas útiles para compatibilidad a largo plazo.