La tabla comparativa, diciendo de dónde sale cada cifra
Yjs, Automerge y Loro puestos uno junto a otro en cada eje, separando con claridad las cifras que vienen de un benchmark de las que solo miden adopción.
Una tabla comparativa es un instrumento peligroso porque parece objetiva. Alinea columnas, iguala unidades y sugiere que todo lo que aparece en ella se midió de la misma manera, cuando en realidad convive ahí material de dos especies incompatibles: cifras de benchmark, que dependen del documento concreto, de la máquina concreta y de la versión concreta, y caducan con la siguiente publicación; y cifras de adopción, que no dicen nada sobre rendimiento pero predicen bastante bien cuánto código vas a tener que escribir tú y cuánto soporte encontrarás dentro de tres años. Mezclarlas en la misma rejilla sin decir cuál es cuál es el defecto que arruina casi todos los cuadros comparativos que circulan. Esta lección presenta la tabla con esa distinción marcada en cada fila, y dedica más espacio a lo que la tabla no puede mostrar que a la tabla misma.
- Distinguir en cada fila si la cifra procede de un benchmark o de una medida de adopción.
- Leer las tres librerías eje por eje sabiendo qué documento y qué versión hay detrás de cada número.
- Reconocer las asimetrías estructurales que ninguna columna puede representar.
- Saber qué partes de la tabla caducan y cuáles seguirán siendo válidas dentro de dos años.
Antes de leer ninguna cifra: qué mide cada especie
Una cifra de benchmark responde a la pregunta de cuánto tarda o cuánto ocupa algo en unas condiciones concretas. Su validez está atada a tres cosas que rara vez se citan junto al número: el documento que se midió, la máquina donde se midió y la versión que se midió. Cambia cualquiera de las tres y el número deja de aplicar. Su virtud es que se puede reproducir; su defecto es que caduca, y en un ecosistema donde una versión puede recortar la memoria un orden de magnitud, caduca rápido.
Una cifra de adopción responde a otra pregunta por completo: cuánta gente resolvió antes que tú los problemas que vas a tener. No dice nada sobre si una librería es rápida y no debe usarse jamás como sustituto de una medición. Pero se mueve despacio, es difícil de manipular a corto plazo y predice con bastante fiabilidad lo que más caro cuesta cuando falta: adaptadores existentes, enlaces con editores, proveedores de sincronización y respuestas a preguntas raras.
Hay una tercera especie que casi nunca se etiqueta y que conviene anticipar antes de mirar la tabla: las afirmaciones estructurales. No son mediciones ni popularidad, sino consecuencias de una decisión de diseño que no cambian con la versión ni con la máquina. Guardar o no el grafo completo del historial es una de ellas. No lleva unidad, no se puede acelerar y no se puede comparar en una columna de milisegundos, y sin embargo suele decidir la elección más que cualquier número de las otras dos especies.
La regla de higiene que se deduce es sencilla y transforma la forma de leer cualquier cuadro comparativo: cada celda debe poder decir de qué especie es. Si no puedes clasificarla, no sabes qué caduca, no sabes qué es reproducible y no sabes qué sigue siendo verdad cuando cambia la versión. Una tabla sin esa columna no es neutral: es una tabla que ha decidido por ti que todas sus filas pesan lo mismo.
flowchart LR B[cifra de benchmark] --> B1[atada a documento maquina y version] B1 --> B2[reproducible pero caduca pronto] A[cifra de adopcion] --> A1[mide cuanta gente fue antes] A1 --> A2[se mueve despacio y predice soporte] B2 --> D[usar para descartar por eje] A2 --> D style B fill:#89b4fa,color:#11111b style A fill:#f9e2af,color:#11111b style D fill:#a6e3a1,color:#11111b
La tabla, con la procedencia marcada
Conviene leerla de arriba abajo y no de izquierda a derecha. Leerla por columnas invita a contar victorias, que es el uso incorrecto; leerla por filas obliga a preguntarse, en cada una, si ese eje discrimina para tu caso y si la cifra es de la especie que puede decidir algo. Las celdas que dicen que algo no se compara aquí no son huecos por descuido: son el reconocimiento de que solo se dispone del dato verificado de una de las tres, y rellenarlas con estimaciones sería precisamente la clase de falsa simetría que estos cuadros producen.
| Eje | Yjs | Automerge | Loro | Naturaleza |
|---|---|---|---|---|
| Descargas semanales | ~920 mil | ~85 mil | ~12 mil | Adopción |
| Estrellas del repositorio | ~17 mil | No comparada aquí | No comparada aquí | Adopción |
| Madurez del ecosistema | La más alta | Intermedia, raíces académicas | La más joven | Adopción |
| Usada en producción por | Notion, Jupyter, Tiptap, BlockNote | Versionado a nivel de documento | Adopción temprana | Adopción |
| Velocidad general | Sólida y contrastada | Muy mejorada en la 3.0 | La más rápida | Benchmark |
| Carga del módulo WebAssembly | No aplica igual | Coste presente | Su único punto flojo | Benchmark |
| Tamaño en disco | Compacto, sin grafo | Columnar comprimido, sin cambios en la 3.0 | Guarda el grafo completo | Formato |
| Memoria en caliente | Contrastada | 700 MB a 1,3 MB en la 3.0 | Competitiva | Benchmark |
| Tiempo de carga | Contrastado | 17 horas a 9 segundos en la 3.0 | Competitivo | Benchmark |
| Grafo completo de historia | No lo guarda | Sí lo guarda | Sí lo guarda | Estructural |
| Metadatos por versión persistida | Vector de versión | conjunto de borrados | Incluidos en el grafo | Incluidos en el grafo | Estructural |
| Algoritmo de secuencia | YATA | Familia propia | Familia propia | Estructural |
Dos observaciones sobre la lectura de las columnas de adopción antes de seguir. La primera es que las descargas semanales miden instalaciones automatizadas tanto como decisiones humanas, de modo que su valor absoluto está inflado en las tres por igual; lo que informa es la relación entre ellas, y una relación de unas once veces entre la primera y la segunda, y de unas siete entre la segunda y la tercera, describe tres posiciones cualitativamente distintas en el ecosistema. La segunda es que la lista de productos que usan una librería no dice que sea la mejor: dice que alguien con recursos y con un problema real la sometió a condiciones que ningún benchmark reproduce y siguió con ella.
La tercera categoría de la última columna es la que más rendimiento intelectual da y la que casi nunca aparece: las filas estructurales. No son mediciones ni son popularidad; son consecuencias del diseño que no cambian con la versión ni con la máquina. Que Loro y Automerge guarden el grafo completo del historial y Yjs no es la fila más importante de toda la tabla, y sin embargo no lleva ninguna unidad. Que Yjs necesite guardar un vector de versión y un conjunto de borrados por cada versión persistida tampoco es un número, pero determina cómo crece tu almacenamiento si tu producto guarda instantáneas con frecuencia.
La reducción de 700 MB a 1,3 MB y la caída de 17 horas a 9 segundos pertenecen ambas a la versión 3.0 de julio de 2025, y la primera está medida sobre un documento del tamaño de Moby Dick. Conviene ser preciso sobre qué mejoró, porque circula mal contado: el formato en disco no cambió —la 3.0 usa el mismo fichero que la 2.x, y esta ya guardaba los metadatos en columnas comprimidas—. Lo que cambió es que ahora la librería trabaja sobre esa representación comprimida también en tiempo de ejecución, en vez de expandirla en memoria al cargar. La mejora es de memoria y de tiempo de carga, no de tamaño en disco. Son cifras reales y el salto que representan es enorme, pero no son propiedades generales de la librería: son el comportamiento de una carga concreta. Citarlas como si describieran tu documento es el error de lectura más frecuente con estos datos, y va en las dos direcciones, porque un documento con muchas ediciones pequeñas y poco texto se comporta de forma distinta a uno con mucho texto y pocas ediciones.
Las tres asimetrías que ninguna columna puede mostrar
Merece una nota aparte la fila de los metadatos por versión persistida, porque es la que más se malinterpreta en la dirección contraria a la anterior. Que Yjs no guarde el grafo completo del historial se lee habitualmente como que es gratis en almacenamiento, y no lo es: necesita guardar un vector de versión y un conjunto de borrados por cada versión persistida. Si tu producto guarda instantáneas con frecuencia, ese coste crece con el número de instantáneas y con el número de identidades que han escrito, y puede acercarse por otra vía al que creías haberte ahorrado. La conclusión no es que una sea peor, sino que ningún diseño regala la historia: unos la guardan explícitamente y otros pagan por poder prescindir de ella.
La primera asimetría es de objeto medido. Cuando comparas el tamaño de un documento de Yjs con el de uno de Loro no estás comparando dos representaciones del mismo contenido: una contiene el estado y la otra contiene el estado más todo su pasado. La comparación es legítima si lo que necesitas es el estado, y es engañosa si lo que necesitas es el pasado, porque en ese segundo caso a la opción más pequeña habría que sumarle el coste de construir por fuera lo que la otra ya trae. Ninguna tabla puede decidir eso por ti porque depende de una funcionalidad de tu producto.
La segunda es de edad. Las cifras de benchmark de una librería joven y las de una madura no tienen la misma esperanza de vida. Loro es la más rápida en los benchmarks salvo en la carga de su módulo WebAssembly, y a la vez la más joven en ecosistema: lo primero puede empeorar si añade funcionalidad y lo segundo casi con seguridad mejorará con el tiempo. Yjs está en la situación simétrica, con un ecosistema que ya alcanzó una masa difícil de mover y un rendimiento que se mueve por incrementos. Leer una tabla sin incorporar esa derivada es tomar una fotografía por una película.
Sobre la asimetría de edad hay un matiz que conviene no perder, porque es el que más discusiones circulares provoca. La madurez del ecosistema no es una cantidad que se acumule de forma lineal con el tiempo: se acumula con el número de integradores que apostaron y publicaron su trabajo, y ese número tiene realimentación positiva. Una diferencia de un orden de magnitud en descargas semanales, como la que separa a Yjs de Automerge, no se cierra sola por el mero paso de los años; se cierra si aparece un caso de uso donde la opción menos adoptada es claramente superior. Estimar la derivada de este eje es, por tanto, estimar si tu caso de uso es ese, y esa es una pregunta sobre tu producto y no sobre las librerías.
La tercera es de superficie comparada. Una tabla obliga a elegir qué se compara, y esa elección ya contiene una teoría de qué importa. Automerge sobresale en versionado a nivel de documento, y ese hecho no cabe en ninguna columna de milisegundos ni de megabytes: es una capacidad presente o ausente. Cuando una propiedad no admite unidad, la tabla tiende a omitirla, y las omisiones de una tabla son sistemáticamente el sitio donde viven las razones por las que un equipo elige la opción que no ganaba columnas.
Benchmark: reproducible y perecedero
Dice qué pasó con un documento, en una máquina y en una versión. Se puede repetir, y hay que repetirlo, porque una sola versión puede invalidarlo entero.
Adopción: lenta y predictiva
No dice nada de velocidad y bastante de riesgo. Predice qué adaptadores existen, qué preguntas ya tienen respuesta y quién seguirá manteniendo esto.
Estructural: sin unidad y decisiva
Guardar o no el grafo de historia no es rápido ni lento: es una capacidad. Estas filas no caducan y suelen decidir más que las dos anteriores juntas.
Omitido: donde vive la decisión
Lo que no admite unidad tiende a desaparecer de la tabla, y ahí suele estar la razón real por la que un equipo elige la opción que perdía columnas.
Cómo leer esta tabla dentro de dos años
Las filas de benchmark serán las primeras en morir y conviene tratarlas desde hoy como provisionales. La forma correcta de usarlas no es aprenderse los números sino quedarse con la relación de orden y con la magnitud del salto: saber que Loro domina los benchmarks salvo en la carga de su módulo, y saber que una sola versión mayor de Automerge movió la memoria un orden de magnitud, es información que sobrevive aunque los valores concretos cambien. Lo segundo, además, contiene una advertencia sobre el propio método: si una versión puede mover un eje diez veces, cualquier tabla es una foto de un instante.
Las tres librerías permiten construir un documento sintético que se parezca al tuyo, aplicarle un número realista de ediciones, serializarlo y medir tres cosas: bytes en disco, memoria del proceso tras cargarlo y tiempo desde la lectura hasta el primer estado utilizable. Con eso tienes las tres filas que de verdad te afectan, medidas sobre tu forma de dato y en la versión que vas a usar. Es media jornada de trabajo y sustituye a toda la mitad perecedera de esta tabla, además de dejarte un guion que puedes volver a ejecutar cada vez que actualices una dependencia.
La forma práctica de que la tabla siga sirviendo es guardar junto a ella el registro de la decisión, con las condiciones exactas bajo las que se midió cada cosa. Un objeto de veinte líneas cumple esa función mejor que un documento largo, porque se puede revisar en un minuto y se puede comparar con una medición nueva sin ambigüedad.
// El registro que hace revisable una decision dentro de dos anos
export const decision = {
fecha: "2026-08",
formaDeDato: "documento estructurado con historia consultable",
ejeDecisivo: "grafo completo de historia",
medidoSobre: { elementos: 12000, ediciones: 480000, dispositivos: 4 },
versiones: { yjs: "x.y.z", automerge: "3.x", loro: "x.y.z" },
descartadas: {
// Motivo por eje, no puntuacion global: una nota media oculta el juicio
A: "no guarda el grafo y el pasado es funcionalidad del producto",
B: "ecosistema insuficiente para los adaptadores que necesitamos",
},
revisarSi: [
"el eje decisivo deja de ser funcionalidad del producto",
"una version mayor mueve disco o memoria un orden de magnitud",
],
};
Ese campo final es el más valioso de todos y el que casi nadie escribe. Una decisión sin condiciones de revisión no se revisa nunca: se hereda, se defiende por inercia y acaba justificándose con argumentos que ya no son los originales. Enumerar por adelantado los dos o tres hechos que la invalidarían convierte una elección en una hipótesis, que es la única forma en que puede envejecer con dignidad.
Hay una última precaución de método que ahorra discusiones improductivas: no compares nunca una cifra publicada de una librería con una cifra medida por ti de otra. Es un error que parece obvio enunciado así y que se comete continuamente, porque medir tres librerías cuesta tres veces más que medir una y la tentación de completar los huecos con lo publicado es fuerte. El resultado es una comparación entre condiciones distintas presentada como si fuera homogénea, que es exactamente el defecto que esta lección intenta corregir.
Las filas de adopción envejecerán mejor pero no de forma uniforme. Una diferencia de un orden de magnitud entre 920 mil y 85 mil descargas semanales describe dos posiciones muy distintas en el ecosistema y no se revierte en dos años; una diferencia entre 85 mil y 12 mil describe una brecha que una librería joven con buena tracción puede recortar. Y las filas estructurales no envejecerán en absoluto mientras las librerías mantengan sus decisiones de diseño, que es justamente por qué merecen el peso que la tabla, por su forma, no les da.
Hay una razón por la que estos cuadros comparativos se consultan mucho y deciden poco, y no es que las cifras estén mal. Es que una tabla presupone que las tres opciones compiten por el mismo trabajo, y las tres han optimizado explícitamente para trabajos distintos. Yjs invirtió en un ecosistema y en no guardar el grafo de historia, y esa combinación es coherente: producto que edita en vivo, con muchos integradores, donde lo que importa es el estado actual y la latencia entre colaboradores; sus 920 mil descargas semanales y su presencia en Notion, Jupyter, Tiptap y BlockNote no son un premio de popularidad, son la consecuencia acumulada de haber servido bien ese trabajo durante años. Automerge invirtió en el grafo completo y en el versionado a nivel de documento, y por eso su salto en la 3.0 fue tan grande: no estaba corrigiendo un descuido, estaba pagando la deuda de una decisión estructural cara con almacenamiento columnar, y llevar 700 MB a 1,3 MB y 17 horas a 9 segundos es exactamente la forma que tiene esa deuda de saldarse. Loro invirtió en velocidad y llegó tarde, y su perfil lo confirma línea por línea: gana casi todos los benchmarks y pierde el del módulo WebAssembly, que es el eje más barato, mientras su ecosistema de 12 mil descargas es el más joven, que es el eje más caro de construir. Leídas así, las tres columnas dejan de ser competidoras y pasan a ser tres respuestas distintas a tres preguntas distintas, y la utilidad real de la tabla se invierte: no sirve para saber cuál gana, sirve para saber cuál de las tres preguntas era la tuya. Un equipo que compara las tres y encuentra que ninguna domina no ha fracasado en su análisis; ha descubierto que su pregunta no estaba lo bastante formulada, y ese descubrimiento vale más que cualquier ganador. Por eso la lección siguiente no añade más cifras: retrocede hasta la forma del dato, que es donde la pregunta se decide y donde la tabla, por muy honesta que sea, ya no puede ayudar.
- Marca en la tabla de esta lección qué filas son de benchmark, cuáles de adopción y cuáles estructurales, y comprueba que sabes justificar cada clasificación.
- Construye un documento sintético del tamaño y la forma de los tuyos y mide bytes en disco, memoria tras la carga y tiempo hasta el primer estado utilizable en las tres librerías.
- Anota junto a cada medición la versión exacta y la máquina, y guarda el guion para poder repetirlo cuando actualices dependencias.
- Decide por escrito si necesitas el grafo completo de historia y, si no lo necesitas, estima qué te ahorra no pagarlo en cada sincronización.
- Calcula cuánto ocuparían tus metadatos si guardases un vector de versión y un conjunto de borrados por cada versión persistida con tu frecuencia real de instantáneas.
- Escribe en un párrafo qué fila de tu tabla decidiría la elección si tuvieras que elegir hoy, y qué tendría que cambiar para invertirla.