JSON Toolkit

Editores, línea de comandos y cadenas de herramientas de automatización

En resumen: Los editores resuelven "verlo con claridad, editarlo correctamente", mientras que la línea de comandos resuelve "lotes, repetible". Cada lado tiene unas pocas herramientas que siguen siendo útiles una década después.

Principiante~10 min de lecturaPublicado el 2026-10-30Actualizado el 2026-10-30
Portada de editores, línea de comandos y cadenas de automatización

En resumen: elige el editor según el escenario — CodeMirror 6 para sitios utilitarios y móvil, Monaco solo cuando necesites la experiencia completa de un IDE; deja el trabajo por lotes a jq más tres comprobaciones de CI para sintaxis, estructura y estilo, y pasa siempre los argumentos con jq --arg.

La era de comprobar JSON a mano debería haber terminado: cualquier cosa que una máquina pueda repetir, no la dejes a los ojos humanos.

1. Editores en el navegador

1.1 Integración mínima de CodeMirror 6

import { EditorView, basicSetup } from 'codemirror';
import { json, jsonParseLinter } from '@codemirror/lang-json';
import { linter, lintGutter } from '@codemirror/lint';

const view = new EditorView({
  parent: document.getElementById('editor')!,
  doc: '{"hello": "json"}',
  extensions: [
    basicSetup,
    json(),
    linter(jsonParseLinter()),
    lintGutter(),
    EditorView.updateListener.of((update) => {
      if (update.docChanged) {
        // Aplica debounce antes de hacer trabajo pesado; no formatees en cada pulsación
        scheduleParse(update.state.doc.toString());
      }
    }),
  ],
});

Cuatro puntos que conviene tener en cuenta:

  1. json() proporciona resaltado de sintaxis y emparejamiento de corchetes — no escribas el tuyo;
  2. jsonParseLinter() produce marcadores de error a nivel de línea/columna; combínalo con lintGutter() para mostrar iconos junto a los números de línea;
  3. El updateListener debe llevar debounce; llamar a JSON.parse sobre cien mil líneas en cada pulsación provocará un retraso visible;
  4. Los documentos grandes necesitan optimizaciones más allá de EditorView.lineWrapping para evitar renderizarlo todo de golpe (CodeMirror 6 renderiza por viewport de forma predeterminada, lo que supone una mejora frente a versiones anteriores).

1.2 Plegado y esquemas

CodeMirror 6 tiene plegado integrado; en escenarios JSON normalmente se pliega por "objeto/array":

import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';

Con foldGutter() y keymap.of(foldKeymap), los usuarios pueden contraer arrays largos con un atajo de teclado.

1.3 Elegir entre CodeMirror y Monaco

Dimensión CodeMirror 6 Monaco
Tamaño del bundle Pequeño, modular Grande (varios MB)
Móvil Bien soportado Experiencia mediocre
Servicios de lenguaje Hay que construirlos Ricos, integrados
Coste de personalización Bajo Medio

Sitios utilitarios y móvil primero → CodeMirror; experiencia completa de IDE (varios archivos, ir a la definición, autocompletado) → Monaco.

2. Línea de comandos: seis recetas de jq de alta frecuencia

jq es al JSON lo que sed + awk al texto; aprender solo una pequeña parte de su sintaxis cubre el ochenta por ciento de las necesidades diarias.

# 1. Seleccionar campos (lo más común)
jq '.data.items[].name' response.json

# 2. Filtrar + remodelar
jq '.data.items[] | select(.price < 10) | {id, price}' response.json

# 3. Agregados (length, sum, max)
jq '[.items[] | .price] | {count: length, total: add, max: max}' response.json

# 4. Agrupar y agregar
jq '[.items[]] | group_by(.category) | map({category: .[0].category, count: length})' response.json
# 5. Combinar varios archivos en un array
jq -s '.' part-*.json > merged.json

# 6. Procesar JSON Lines línea a línea
jq -c 'select(.level == "error")' app.jsonl

# Opciones de salida habituales
jq -r '.data.name'      # Quita las comillas para que se pueda encadenar a la shell
jq -c '.'               # Salida compacta, una línea
jq --arg id "$ID" '.id == $id'   # Pasa argumentos de forma segura, evitando inyección por concatenación

--arg merece una mención especial: concatenar una variable directamente en una expresión falla en cuanto el valor contiene comillas, mientras que --arg deja que jq gestione el escapado.

2.1 Otras herramientas de un vistazo

Herramienta Propósito En una frase
yq Conversión YAML/JSON/XML Sintaxis similar a jq, el caballo de batalla de los archivos de configuración
dasel Consulta unificada entre formatos Soporta JSON/YAML/TOML/XML/CSV
fx Navegación interactiva de JSON Haz clic en la terminal, bueno para explorar
jless Navegación paginada en la terminal Como less, con plegado y búsqueda
gron Aplana JSON en líneas consultables con grep Una gran herramienta para averiguar "en qué nivel está este campo"
ajv-cli Validación con schema Valida archivos JSON en CI

La idea detrás de gron merece conocerse en especial:

$ echo '{"a":{"b":[1,2]}}' | gron
json = {};
json.a = {};
json.a.b = [];
json.a.b[0] = 1;
json.a.b[1] = 2;

Una vez aplanado, grep puede localizar la ruta, lo que es mucho más rápido que expandir nivel a nivel en un editor.

3. Tres capas de validación en CI

Capa Herramienta Qué significa un fallo
Sintaxis JSON.parse / jq empty El archivo en sí está malformado
Estructura ajv-cli + schema Faltan campos, tipos incorrectos
Estilo Prettier Formato inconsistente, diffs ruidosos
# Sintaxis: valida por lotes todos los archivos json del repositorio
find . -name '*.json' -not -path './node_modules/*' -print0 \
  | xargs -0 -n1 jq empty

# Estructura: valida contra un schema
npx ajv-cli validate -s schemas/order.json -d 'fixtures/orders/*.json' --strict=false

# Estilo: solo comprobar, no modificar
npx prettier --check "**/*.json"

Necesitas las tres capas, porque sus mensajes de error son completamente distintos: jq empty solo dice "qué línea está rota", ajv dice "qué campo viola qué palabra clave" y Prettier solo dice "el formato es inconsistente".

4. Hooks de pre-commit

# Ejemplo de .husky/pre-commit (extracto)
npx lint-staged
{
  "lint-staged": {
    "*.json": ["prettier --write", "jq empty"]
  }
}

Ten cuidado con los archivos de configuración de herramientas como package.json y tsconfig.json; no dejes que Prettier los reindente a la ligera — algunas herramientas son sensibles al formato (el JSON válido no debería serlo, pero en la práctica esto ha causado problemas). Puedes excluirlos individualmente.

5. Consejos de depuración

  1. Usa jq -e como aserción: el código de salida es 1 cuando el resultado de la expresión es false o null, así que puede entrar directamente en scripts como comprobación;
  2. jq 'paths' lista todas las rutas, dándote una visión rápida de la estructura de un documento desconocido;
  3. jq '.. | objects | keys' encuentra todos los nombres de clave que han aparecido alguna vez, útil para cazar grafías inconsistentes;
  4. Formatea antes de comparar en el editor: un diff sin formatear es ruido puro; una comparación estructural como /diff es más precisa.

6. Lista de comprobación

  • [ ] Los marcadores de error del editor son precisos hasta línea y columna, y el parseo tiene debounce;
  • [ ] Los scripts del equipo pasan argumentos con jq --arg en lugar de concatenar cadenas;
  • [ ] CI tiene las tres capas de validación (sintaxis/estructura/estilo);
  • [ ] pre-commit solo procesa archivos en staging, para que un escaneo completo no ralentice los commits;
  • [ ] Las versiones de las herramientas están fijadas en package.json o .tool-versions.

FAQ

¿Cómo elijo entre CodeMirror 6 y Monaco?

Para sitios utilitarios y móvil, prefiere CodeMirror 6: es pequeño, modular y está bien soportado en móvil, y el resaltado de sintaxis, el emparejamiento de corchetes y el plegado se pueden componer según necesidad. Recurre a Monaco solo cuando necesites la experiencia completa de IDE con varios archivos, ir a la definición y autocompletado, a costa de un bundle de varios megabytes y un mayor esfuerzo de personalización.

¿Por qué CI necesita las comprobaciones de sintaxis, estructura y estilo juntas?

Las tres capas reportan errores completamente distintos: jq empty dice qué línea está rota, ajv dice qué campo viola qué palabra clave y Prettier solo dice que el formato es inconsistente. Eliminar una capa hace que los errores de las otras se malinterpreten fácilmente, así que mantén las tres y detente en cuanto falle una.

¿Debería confiar en pre-commit en lugar de validar en CI?

No. Los hooks procesan solo archivos en staging, lo que da feedback en un minuto pero no puede cubrir todo el repositorio ni los cambios que se saltan el commit. CI es responsable de la exhaustividad: mantén pre-commit sobre los archivos en staging y deja los escaneos completos a CI.