wandres.dev
LORO · texto rico y árboles

Su lugar: lidera casi todo y es la más joven de las tres

Loro llegó a la versión 1.0 en 2024, encabeza la traza de edición real en todas las categorías salvo el arranque del módulo, y es a la vez la de menor adopción y la de ecosistema más inmaduro.

⏱ 19 min

Llega el momento de situar a Loro entre las tres bibliotecas del bloque, y el ejercicio es incómodo porque los dos ejes que importan apuntan en direcciones opuestas. En el eje técnico es la más ambiciosa: tiene primitivas que las otras dos no tienen, encabeza la medición sobre una traza de edición real en todas las categorías salvo una, y su única derrota es precisamente la que se deriva de su apuesta de origen. En el eje de la adopción es la más pequeña y la más joven, con la menor cantidad de descargas semanales de las tres y un ecosistema de integraciones que todavía se está formando. Ninguno de los dos ejes puede ignorarse al decidir, y cualquier recomendación que solo mire uno es una recomendación mal hecha. Esta lección junta las dos lecturas y termina con un criterio de elección que se pueda defender delante de un equipo.

🎯 Al terminar esta lección sabrás
  • Leer la medición sobre la traza de edición real sin confundir liderazgo con superioridad.
  • Localizar la única categoría donde Loro no lidera y entender por qué es exactamente esa.
  • Contrastar la madurez del ecosistema con la calidad técnica, que son variables independientes.
  • Construir un criterio de elección explícito entre las tres bibliotecas del bloque.

Dónde lidera y dónde no

La medición de referencia reproduce una traza real de edición registrada carácter a carácter sobre un documento grande, con unas doscientas sesenta mil operaciones entre inserciones y borrados. No es un microbanco sintético: es el rastro de alguien escribiendo de verdad, y por eso es la única de las mediciones publicadas que representa algo parecido a un uso real.

Que sea una traza de un solo autor tiene además una implicación que rara vez se comenta. Al no haber concurrencia, mide el camino barato de todos los algoritmos y ninguno paga el coste de fusionar ramas divergentes. Eso la hace representativa del uso mayoritario y a la vez ciega al escenario que motiva usar un CRDT, de modo que hay que leerla como lo que es: una prueba de que no hay patologías en el caso común, no una prueba sobre el caso difícil.

Sobre esa traza Loro encabeza todas las categorías —tiempo de aplicación de las operaciones, tamaño de la codificación, memoria, tiempo de análisis del documento— con una sola excepción: el tiempo de carga inicial del módulo de WebAssembly. Y esa excepción no es una casualidad ni un descuido pendiente de corregir. Es la consecuencia directa y previsible de la decisión de la primera lección: el núcleo está escrito en Rust y llega al navegador como un artefacto binario que hay que descargar, compilar e instanciar antes de que exista una sola función llamable.

Que la única derrota sea exactamente esa es lo más informativo del cuadro, porque significa que la biblioteca no tiene un punto débil disperso sino un peaje concentrado y perfectamente identificado. Un perfil de rendimiento con una debilidad localizada es mucho más manejable que uno con varias medianías, porque admite una contramedida concreta: en este caso, mover el arranque fuera del camino crítico. Un peaje repartido por todas las operaciones no admitiría ninguna.

La forma de la comparacion sobre la traza real

  aplicar las operaciones ....... lidera
  tamano del documento .......... lidera
  memoria en reposo ............. lidera
  analizar el documento ......... lidera
  arranque del modulo ........... no lidera, y por diseno

  el unico punto perdido es el coste fijo,
  que es tambien el unico que se puede reprogramar en el tiempo
⚠️
La documentación de Loro desaconseja leer sus propios números como un ranking

Merece la pena citar lo que la propia biblioteca escribe encima de sus tablas, porque es más honesto que casi todo lo que se lee en el ecosistema: el papel de estas mediciones debería ser indicar la ausencia de patologías de rendimiento y no medir qué proyecto es superior, porque proyectos distintos toman compromisos distintos de forma consistente. Es inexacto afirmar que un proyecto es mejor que otro porque rinde más en ciertas pruebas, cuando el otro puede destacar por un margen amplio en otras dimensiones. Quien use estas tablas como argumento de venta está usándolas contra las instrucciones de quien las publicó.

La madurez, que es una variable independiente

Aquí el retrato cambia de signo. Loro alcanzó su versión 1.0 en 2024, lo que la convierte en la más joven de las tres por un margen considerable, y su adopción medida en descargas semanales ronda las doce mil: la menor de las tres, y por bastante.

Ese hito de la versión 1.0 tiene además un significado técnico concreto que la documentación explica al justificar su formato de codificación: para garantizar compatibilidad hacia atrás y hacia adelante a partir de esa versión, adoptaron un método de codificación más extensible aunque fuera más lento que el anterior. Es la clase de sacrificio que solo se hace cuando se asume que habrá documentos guardados que deberán abrirse dentro de años, y merece ser leída como una señal de intenciones más fiable que cualquier declaración de estabilidad.

Las dos cifras están relacionadas y conviene no contarlas dos veces como si fueran dos problemas independientes: una biblioteca que estabilizó su formato de datos hace dos años tiene por fuerza menos rodaje que una que lo hizo hace ocho, y la adopción tarda en llegar incluso cuando la calidad ya está. Lo relevante no es cuál de las dos cifras es la causa, sino que ambas describen el mismo hecho desde ángulos distintos.

Ese número no mide calidad. Mide otra cosa que también importa y que conviene nombrar con precisión, porque es lo que un equipo va a encontrarse en el día a día: cuántas preguntas ya están respondidas en algún sitio, cuántos casos límite ya los ha pisado otro antes que tú, cuántas integraciones con editores y marcos existen mantenidas por terceros, cuántos proveedores de sincronización hay para elegir, y cuánta gente hay disponible que ya sepa usarla.

flowchart TB
E[eleccion de biblioteca] --> T[eje tecnico]
E --> M[eje de madurez]
T --> T1[primitivas disponibles]
T --> T2[rendimiento medido]
M --> M1[adopcion y respuestas existentes]
M --> M2[integraciones y proveedores]
T1 --> D[decision informada]
T2 --> D
M1 --> D
M2 --> D
style T fill:#a6e3a1,color:#11111b
style M fill:#f9e2af,color:#11111b
Dos preguntas que la adopcion responde y la calidad no

  cuando te encuentres un caso limite raro
    con adopcion alta ... alguien lo describio y hay un hilo con la respuesta
    con adopcion baja ... lo describes tu, y quiza te contestan

  cuando necesites una pieza de alrededor
    con adopcion alta ... hay varias, mantenidas por terceros
    con adopcion baja ... hay una oficial, o la escribes

  ninguna de las dos preguntas mide si la biblioteca es buena
// La prueba honesta no es un banco de pruebas: es tu peor caso
// escrito dos veces detras de la misma interfaz propia
export function crearDocumentoDeProyecto() {
  const doc = new LoroDoc();
  doc.configTextStyle({ bold: { expand: "after" } });
  return {
    titulo: doc.getText("titulo"),
    arbol: doc.getTree("tareas"),
    exportar: () => doc.export({ mode: "snapshot" }),
  };
}

Conviene matizar el retrato en un punto, porque el ecosistema propio de Loro no está vacío. Existen enlaces oficiales para los dos editores que importan en la práctica —uno para el marco de edición enriquecida más extendido, que además funciona con el editor construido encima de él, y otro para el editor de código— y ambos cubren sincronización de estado, presencia de cursores y deshacer colaborativo. Lo que está menos poblado es lo de alrededor: proveedores de red de terceros, integraciones con marcos de interfaz, herramientas de depuración y, sobre todo, historias de producción publicadas con años de rodaje.

Lo que solo tiene Loro

Si se mira la tabla comparativa que la propia documentación publica frente a las otras bibliotecas, hay dos filas donde Loro aparece sola y son justamente las de este nivel. Vale la pena leer esa tabla con la desconfianza que merece cualquier comparativa escrita por una de las partes, pero también reconocer que sus filas son verificables una a una: o el contenedor existe en la biblioteca o no existe.

🌲

Árbol con movimiento

Ninguna de las otras dos lo ofrece como contenedor nativo, pese a que el algoritmo que Loro implementa fue publicado por el mismo grupo que impulsó una de ellas.

🔀

Lista con movimiento

Reordenar un elemento existente sin borrarlo y recrearlo tampoco está disponible en las otras dos como primitiva.

✍️

Texto enriquecido

Lo comparte con una de las otras dos, y es una diferencia decisiva frente a la tercera, que no modela el formato como CRDT.

🕰️

Control de versiones

Viajar en el tiempo y trabajar con versiones concretas es capacidad de dos de las tres, y se sigue de guardar el grafo completo.

Conviene añadir un matiz sobre la fila del texto enriquecido, porque es la que más se malinterpreta en las comparativas. Que una biblioteca no modele el formato como estructura convergente no significa que no se pueda escribir un editor con formato encima de ella: significa que las fusiones de formato concurrente se resolverán con reglas improvisadas escritas por ti o por el enlace del editor, y que los casos difíciles de la lección anterior quedarán a tu cargo. La diferencia no aparece en la demostración; aparece a los seis meses, cuando dos personas formatean el mismo párrafo desde dos dispositivos.

Hay también una fila donde Loro aparece como la que no tiene: la tolerancia a fallos bizantinos, que sí ofrece una de las otras dos. Traducido a decisiones, significa que Loro asume participantes que pueden desconectarse pero no participantes que mientan sobre su propia historia; si tu modelo de amenaza incluye réplicas maliciosas, esa fila decide por ti antes que cualquier medición de rendimiento.

Merece la pena señalar una ironía del cuadro que dice mucho sobre cómo avanza este campo. Las dos filas donde Loro está sola corresponden a algoritmos publicados por investigadores vinculados a las bibliotecas rivales: el movimiento en árboles replicados y el movimiento de elementos en listas salieron de ese entorno, y sin embargo quien los lleva a producción como contenedor nativo es la biblioteca más joven. Publicar un algoritmo y encajarlo en una biblioteca existente son dos trabajos distintos, y el segundo es más fácil cuando aún no arrastras un formato de datos con años de compatibilidad que preservar.

Cuándo elegirlo hoy

La propia documentación abre con una sección que casi ninguna biblioteca se atreve a escribir: cuándo no usarla. Enumera cuatro situaciones —cuando se necesita consistencia fuerte, cuando los datos no tienen forma de documento estructurado, cuando basta con una sincronización cliente servidor sencilla, y cuando la aplicación es sensible al tamaño del paquete— y la última es, otra vez, la contrapartida de la apuesta.

Las tres primeras conviene leerlas despacio porque descartan más proyectos de los que parece. La consistencia fuerte excluye todo lo que tenga invariantes globales que no puedan violarse ni un instante: saldos, inventarios, reservas de asientos. Los datos sin forma de documento estructurado excluyen el vídeo, el audio y los ficheros binarios grandes, que no ganan nada con fusionarse. Y la tercera es la más olvidada: si tu aplicación siempre tiene servidor, siempre tiene red y nunca edita en paralelo de verdad, un canal de mensajes y una tabla te dan lo mismo por una fracción del coste conceptual.

💡
Un criterio de elección en tres preguntas

Primero: ¿tu modelo de datos contiene jerarquías que los usuarios reorganizan, o listas que reordenan? Si la respuesta es sí y hay concurrencia real sobre esas reorganizaciones, Loro es la única de las tres que te lo da sin que lo construyas tú. Segundo: ¿tu aplicación tiene texto con formato que dos personas editan a la vez? Eso reduce el campo a dos. Tercero: ¿tu equipo puede permitirse ser de los primeros, es decir, encontrarse casos límite sin respuesta previa y depender de un ecosistema en formación? Si la respuesta a la tercera es no, las dos primeras dejan de mandar.

Elegir infraestructura joven es apostar sobre la derivada, no sobre el valor

Aquí se cierra el bloque entero y conviene hacerlo con la incomodidad intacta, porque el caso de Loro es el ejemplo más limpio de una tensión que reaparecerá en todas las decisiones de infraestructura de tu carrera. Tienes delante una biblioteca que gana en casi todas las mediciones que sabemos hacer, que tiene primitivas que las alternativas no tienen, que documenta sus propias debilidades mejor que sus competidoras documentan sus fortalezas, y que a la vez es la menos usada de las tres. La reacción cómoda es concluir que la adopción es un indicador rezagado de la calidad y que solo hay que esperar; y a veces es cierto, pero la adopción no es solo un indicador, es también una causa: determina cuántas integraciones existen, cuántos casos límite ya están descubiertos, cuántos proveedores compiten y cuánta gente puedes contratar que ya sepa. Al elegir la opción joven no estás apostando por su calidad presente, que ya has verificado, sino por la derivada de su ecosistema durante los años que tu aplicación va a vivir, y esa derivada depende de decisiones de terceros sobre las que no tienes ninguna influencia. De ahí se sigue la única forma sensata de tomar esta decisión, y no consiste en elegir mejor sino en reducir el coste de haber elegido mal: aísla la biblioteca detrás de una interfaz propia expresada en el vocabulario de tu dominio, no en el suyo; escribe las pruebas de convergencia contra esa interfaz y no contra la implementación; y verifica desde el primer día que puedes exportar tu estado a un formato que sobreviva a la biblioteca. Si has hecho esas tres cosas, elegir la opción joven es una apuesta acotada y probablemente la correcta, porque sus ventajas técnicas son reales y verificables hoy. Si no las has hecho, ninguna de las tres opciones era segura, y el problema nunca estuvo en la elección.

⚔️ Decide con una prueba y no con una tabla
  1. Escribe el modelo de datos de tu aplicación y marca qué partes son secuencias, cuáles jerarquías y cuáles valores sueltos.
  2. Señala cuáles de esas partes sufren reordenaciones o cambios de pertenencia hechos por los usuarios.
  3. Implementa el caso más difícil de tu modelo en Loro y en una de las otras dos, con la misma interfaz propia por delante.
  4. Mide el arranque completo con la caché fría en un dispositivo modesto, no en tu máquina de desarrollo.
  5. Reproduce dos sesiones desconectadas de una hora y compara la fusión resultante en ambas implementaciones.
  6. Escribe el plan de salida: qué formato exportarías y cuánto tardarías en sustituir la biblioteca detrás de tu interfaz.