Le logiciel local-first revient, et les moteurs de synchronisation font le gros du travail

La plupart des logiciels que nous utilisons considèrent encore le serveur comme la seule copie réelle de nos données. Le téléphone et l'ordinateur ne sont que de fines fenêtres sur une base de données ailleurs, et quand la connexion tombe, la fenêtre devient vide. Le mouvement local-first affirme que c'est à l'envers. L'appareil devrait détenir la copie de travail, le réseau ne devrait servir qu'à la synchroniser, et l'application devrait continuer à fonctionner quand le réseau disparaît.
L'idée n'est pas nouvelle, mais elle devient enfin pratique. Ce qui a changé n'est pas un virage philosophique chez les développeurs. Ce sont les moteurs de synchronisation et les types de données répliqués sans conflit (CRDT) qui ont suffisamment mûri pour résoudre la partie la plus difficile : fusionner deux modifications faites sur deux appareils sans en perdre aucune. Si vous construisez aujourd'hui un logiciel collaboratif, la synchronisation n'est plus un détail d'infrastructure confié à l'équipe backend. C'est une décision produit qui influence votre modèle de données, vos permissions et vos coûts de support.
Le manifeste de 2019 et pourquoi il a fallu sept ans
En 2019, le groupe de recherche Ink & Switch a publié un essai intitulé Local-first software: you own your data, in spite of the cloud. Il énumérait sept idéaux : une réponse rapide sans spinners, un travail qui survit à une coupure réseau, la collaboration entre appareils et personnes, des données qui survivent à l'entreprise qui a créé l'application, la sécurité et la confidentialité par défaut, et des utilisateurs qui contrôlent leurs propres fichiers. Presque personne ne contestait la liste. Le problème était le coût de mise en œuvre.
Construire une application local-first signifiait autrefois écrire sa propre logique de fusion, sa couche de stockage et son protocole de réplication. La plupart des équipes ont choisi la voie tout cloud parce qu'elle était plus simple, et les utilisateurs toléraient les spinners. Ce calcul a changé grâce à des bibliothèques comme Automerge et Yjs, qui ont rendu les CRDT utilisables en JavaScript, et à des moteurs de synchronisation qui ont pris en charge la plomberie qui les entoure.
Ce que fait réellement un moteur de synchronisation
Un CRDT est une structure de données conçue pour que des répliques puissent être fusionnées dans n'importe quel ordre tout en convergeant vers le même résultat, sans arbitre central. Textes, listes et dictionnaires peuvent être modélisés ainsi. Un moteur de synchronisation se place par-dessus et gère le travail ingrat : transférer les changements entre client et serveur, ne répliquer que le sous-ensemble de données que chaque utilisateur peut voir, persister l'état après redémarrage et se réconcilier avec une base de données faisant autorité.
Plusieurs produits en production fonctionnent sur ce modèle. Linear a publiquement décrit son magasin côté client, qui permet à son outil de suivi de répondre instantanément pendant que les changements se synchronisent en arrière-plan. L'édition multijoueur de Figma est un autre cas connu de nombreux clients modifiant simultanément le même document. La leçon de ces produits est que la copie locale est ce avec quoi l'utilisateur interagit, et que le serveur devient un coordinateur plutôt qu'un goulot d'étranglement.
Où le modèle se brise
Les CRDT excellent à fusionner des modifications de texte et des ensembles d'éléments. Ils sont beaucoup moins utiles lorsque vos règles métier dépendent d'invariants globaux. Si deux personnes réservent le dernier siège d'un vol hors connexion, une fonction de fusion ne peut pas décider qui l'obtient sans une information que seul le serveur possède. Il en va de même pour les paiements, les stocks qui ne doivent jamais devenir négatifs, et tout ce qui touche à l'argent ou aux engagements juridiques.
La migration de schéma est le deuxième problème que les équipes sous-estiment. Quand un client en retard de trois mois se reconnecte, il doit comprendre des données écrites par une version plus récente, et cette version doit tolérer des données écrites par une version ancienne. Cela exige des verrous de version côté client, une dépréciation prudente des champs et un plan pour les clients qui ne se mettent jamais à jour. Le stockage est le troisième. Un téléphone a un espace et une batterie limités, il faut donc des politiques d'éviction, une réplication partielle et une réponse claire à ce qui se passe quand la base locale dépasse ce que l'appareil peut contenir.
Un cadre de décision simple
Avant de choisir une architecture local-first, posez trois questions sur chaque type de donnée de votre produit. Premièrement, cette donnée doit-elle fonctionner hors ligne ou répondre en moins d'environ 100 millisecondes ? Deuxièmement, plusieurs personnes modifient-elles le même objet simultanément ? Troisièmement, si l'utilisateur perdait l'accès au fournisseur, la donnée deviendrait-elle inutilisable pour lui ?
Si la réponse aux trois est oui, vous avez un argument solide pour le local-first, par exemple pour les notes, les gestionnaires de tâches et les outils de design. Si les deux premières réponses sont non, un modèle classique avec serveur est généralement moins cher et plus simple à raisonner. La plupart des produits finissent en modèle mixte : les brouillons et le contenu collaboratif se synchronisent localement, tandis que les paiements, les rôles et la facturation restent sous l'autorité du serveur.
Conclusions pratiques
- Classez chaque entité de votre modèle de données comme fusionnée par CRDT, faisant autorité côté serveur ou en lecture seule, et consignez cette classification avant d'écrire du code.
- Versionnez le schéma dès le premier jour et ajoutez des vérifications de version client pour que les anciens clients échouent proprement au lieu de corrompre les données.
- Testez sur des Android d'entrée de gamme au stockage limité, pas seulement sur le dernier iPhone.
- Organisez un essai interne d'une semaine hors connexion. Utilisez le mode avion pour votre travail habituel et notez chaque point où l'application vous bloque. Ce sont vos véritables exigences.
Le local-first ne remplace pas le cloud. C'est un rééquilibrage : l'appareil fait davantage du travail qui compte pour l'utilisateur, et le serveur assure la coordination pour laquelle il est performant. Les équipes qui réussiront livreront des applications qui semblent plus rapides et résistent aux mauvais réseaux. Celles qui traiteront la synchronisation comme un détail continueront d'afficher des spinners.