Blog
Feature
3 novembre 20258 min

TipTap dans React Native : editeur rich text mobile

Un mémo, ce n'est pas juste du texte brut. C'est une idée structurée : des titres, du gras, des listes à puces, des blocs de code... et surtout des checklists interactives. Dans une app collaborative comme TAMSIV, une checklist devient un véritable outil de coordination d'équipe. Le problème ? Intégrer un éditeur rich text complet dans une app React Native, c'est un défi technique que peu de développeurs abordent de front.

J'ai passé trois semaines à construire cet éditeur. Trois semaines de bugs WebView, de galères de clavier mobile et de synchronisation temps réel. Voici tout ce que j'ai appris.

Points clés à retenir :
- TipTap fonctionne dans React Native via une WebView avec un bridge bidirectionnel JSON
- Les checklists collaboratives nécessitent deux modes : validation "single" et "everyone"
- La synchronisation se fait au niveau des items individuels, pas du document entier
- Le clavier mobile est le plus gros défi technique de l'intégration
- Supabase Realtime permet une synchronisation temps réel sans CRDT complexe

Pourquoi un éditeur rich text dans une app mobile ?

La réponse courte : parce que le texte brut ne suffit pas. Quand tu prends un mémo en réunion, tu veux mettre un titre, souligner une idée importante, créer une liste d'actions. Un champ TextInput basique ne permet rien de tout ça.

J'ai évalué plusieurs options avant de me lancer. Le constat était simple : les apps de productivité qui réussissent en 2026 — Notion, Obsidian, Craft — proposent toutes un éditeur riche. C'est devenu un standard. Un mémo vocal qui se transforme en texte brut, ça fait date.

Dans TAMSIV, l'éditeur rich text sert principalement dans les mémos — ces notes longues que tu dictes vocalement et que tu veux ensuite enrichir manuellement. Le pipeline vocal génère du texte structuré, et l'éditeur permet de l'ajuster.

Espace de travail développeur avec un ordinateur portable affichant un éditeur de texte riche avec du contenu formaté
L'éditeur rich text de TAMSIV : du formatage complet directement sur mobile.

Comment fonctionne TipTap dans React Native ?

TipTap est un éditeur fantastique sur le web. Il est basé sur ProseMirror, extensible, bien documenté, et la communauté est active. Le problème : React Native n'a pas de DOM. TipTap ne peut pas fonctionner nativement.

La solution que j'ai retenue : une WebView qui embarque l'éditeur TipTap complet. L'architecture se décompose ainsi :

  • Côté WebView : TipTap s'exécute dans un environnement web classique, avec toute sa puissance
  • Bridge bidirectionnel : les messages passent entre React Native et la WebView via postMessage / onMessage
  • Sérialisation JSON : le contenu de l'éditeur est sérialisé en JSON TipTap, envoyé au bridge, puis stocké en HTML en base de données

Ce pattern n'est pas idéal — il ajoute une couche de complexité — mais c'est le seul qui permette d'avoir un éditeur riche complet sur mobile sans réécrire ProseMirror from scratch.

Quelles fonctionnalités l'éditeur supporte-t-il ?

L'éditeur TAMSIV supporte un ensemble complet de formatage :

  • Titres (H1, H2, H3) pour structurer les mémos longs
  • Gras et italique pour l'emphase
  • Listes à puces et numérotées
  • Blocs de code pour les développeurs (oui, même dans une app de productivité)
  • Checklists interactives — le cœur du système collaboratif

Le choix a été délibéré : pas de tableaux, pas d'embeds, pas de formules. Chaque fonctionnalité ajoutée complexifie le bridge WebView et augmente le risque de bugs. J'ai opté pour un éditeur puissant mais focalisé.

Le clavier mobile est-il le plus gros défi technique ?

Oui, sans aucun doute. Et si tu as déjà développé avec des WebViews sur mobile, tu sais de quoi je parle.

Le problème fondamental : quand l'utilisateur tape dans la WebView, le clavier natif du smartphone s'ouvre. Mais la WebView n'est pas un composant natif — elle ne communique pas naturellement avec le système de gestion du clavier d'Android ou iOS. Résultat :

  • Le curseur disparaît sous le clavier
  • Le scroll automatique ne suit pas la saisie
  • Le redimensionnement de la vue est incorrect
  • Sur certains appareils Android, le clavier se ferme et se rouvre de façon aléatoire

La solution a nécessité du code spécifique par plateforme. Sur Android, j'écoute les événements resize dans la WebView et j'ajuste manuellement la hauteur. Sur iOS, c'est un peu plus prévisible grâce à KeyboardAvoidingView, mais il faut quand même gérer le scroll du curseur manuellement.

J'ai passé presque une semaine entière uniquement sur les problèmes de clavier. C'est le genre de sujet invisible pour l'utilisateur final — quand ça marche, personne ne le remarque — mais qui peut ruiner l'expérience si c'est mal géré.

Comment fonctionnent les checklists collaboratives ?

Les checklists, c'est le cœur de la valeur collaborative de TAMSIV. Une liste de courses partagée, un CR de réunion avec des actions, un protocole d'équipe — tous ces cas d'usage reposent sur des checklists. Mais une checklist collaborative, ça ne fonctionne pas comme une checklist personnelle.

Écran de smartphone affichant une application mobile avec des éléments de checklist interactifs et des indicateurs de collaboration
Checklists collaboratives avec validation individuelle ou collective.

J'ai implémenté deux modes de validation :

Mode "Single" : un seul suffit

Cas d'usage : "Acheter le café". Le premier membre de l'équipe qui le fait coche l'item. C'est fini. Inutile que tout le monde confirme — une seule personne suffit.

En base de données, c'est simple : un boolean is_checked et un checked_by (UUID de l'utilisateur). Le premier qui coche "gagne".

Mode "Everyone" : tout le monde doit valider

Cas d'usage : "Lire le compte-rendu de réunion". On veut s'assurer que chaque membre de l'équipe a lu et confirmé. L'item n'est "fait" que quand 100% des membres ont coché.

En base, c'est plus complexe : une table de validation stocke l'état par utilisateur et par item. Chaque coche est indépendante. L'UI affiche une jauge de progression ("3/5 ont validé") et colore l'item différemment selon le statut.

Ce système de double validation est inspiré de ce que font les outils professionnels comme Jira ou Monday.com, mais adapté à un usage plus léger — groupes familiaux, petites équipes, associations.

Comment se fait la synchronisation en temps réel ?

La synchronisation est le dernier morceau du puzzle. Quand deux personnes éditent le même mémo ou cochent des items en même temps, il faut que tout reste cohérent.

J'utilise Supabase Realtime pour propager les changements. Le choix technique important : la synchronisation se fait au niveau des items individuels, pas du document entier. Quand tu coches un item, seul cet item est mis à jour et propagé — pas tout le mémo.

Pourquoi ce choix ? Parce que synchroniser un document entier crée des conflits de merge impossibles à résoudre sans un système de type CRDT (Conflict-free Replicated Data Types). Les CRDT, c'est élégant en théorie, mais ça ajoute une complexité énorme pour un cas d'usage qui ne le nécessite pas.

Plusieurs personnes collaborant autour d'un document numérique partagé sur tablette avec des indicateurs d'édition en temps réel
Collaboration en temps réel : chaque modification est synchronisée instantanément.

Le flow de synchronisation :

  1. L'utilisateur coche un item dans la WebView
  2. Le bridge envoie le changement à React Native
  3. React Native écrit dans Supabase via le service dédié
  4. Supabase Realtime propage le changement à tous les abonnés
  5. Les autres clients reçoivent l'update et mettent à jour leur WebView

Latence typique : 200 à 500ms. C'est pas du Google Docs, mais c'est largement suffisant pour des checklists et des mémos collaboratifs. L'important, c'est que les changements ne soient jamais perdus.

Quels sont les pièges à éviter avec TipTap sur mobile ?

Après trois semaines d'intégration, voici les pièges que j'aurais aimé connaître avant de commencer :

1. La taille du bundle WebView. TipTap avec toutes ses extensions pèse lourd. J'ai dû être sélectif sur les extensions importées. Chaque extension non utilisée ajoutait du poids au chargement initial de la WebView.

2. Le temps de chargement initial. La première ouverture de l'éditeur est lente (~300ms) parce que la WebView doit charger, parser le HTML, initialiser TipTap. J'ai ajouté un skeleton loader pour masquer ce délai.

3. La gestion mémoire. Les WebViews consomment beaucoup de mémoire. Sur des appareils d'entrée de gamme (Android Go par exemple), ça peut poser problème. J'ai implémenté un système de lazy loading qui ne charge la WebView que quand l'utilisateur ouvre effectivement l'éditeur.

4. Les raccourcis clavier. Sur tablette avec clavier externe, les utilisateurs s'attendent à Ctrl+B pour le gras, Ctrl+I pour l'italique. Ces raccourcis fonctionnent nativement dans la WebView TipTap, mais il faut s'assurer qu'ils ne sont pas capturés par React Native avant d'atteindre la WebView.

5. Le copier-coller. Le contenu copié depuis l'éditeur doit être correctement formaté en tant que texte riche ET texte brut. TipTap gère ça nativement, mais le bridge WebView peut parfois casser le formatting.

Comment le pipeline vocal s'intègre-t-il avec l'éditeur ?

C'est là où tout se connecte. Le pipeline vocal de TAMSIV permet de dicter un mémo par la voix. L'IA transcrit, structure, et génère du texte formaté. Ce texte arrive dans l'éditeur TipTap déjà structuré — avec des titres, des listes, parfois même des checklists pré-remplies.

L'utilisateur peut ensuite modifier le contenu manuellement : ajouter une checklist, reformater un paragraphe, insérer un bloc de code. C'est la combinaison voix + éditeur riche qui rend TAMSIV unique. La voix pour la capture rapide, l'éditeur pour le peaufinage.

Ce pattern rejoint ce que j'explique dans l'article sur le dictaphone vocal : la voix est un outil de capture, pas un outil d'édition. L'éditeur rich text comble exactement ce gap.

Quelles alternatives à TipTap existent pour React Native ?

Avant de choisir TipTap + WebView, j'ai évalué d'autres approches :

  • Markdown natif : plus léger, mais l'expérience d'édition est médiocre sur mobile. L'utilisateur doit connaître la syntaxe Markdown.
  • React Native custom avec TextInput : possible pour du gras/italique basique, mais ingérable pour les listes, blocs de code et checklists.
  • Quill.js en WebView : similaire à TipTap, mais moins extensible et la communauté est moins active.
  • Éditeur natif (Swift/Kotlin) : la meilleure performance, mais double le travail de développement puisqu'il faut maintenir deux codebases.

TipTap + WebView est le meilleur compromis : un seul code pour les deux plateformes, une extensibilité maximale, et une communauté active pour les bugs.

Ce que j'ai appris sur la dette technique des éditeurs

Un éditeur rich text, c'est le genre de feature qui semble simple en surface mais qui cache une complexité immense. Chaque nouveau format supporté (tableaux, images inline, mentions @) ajoute des interactions imprévues avec le reste du système.

La leçon clé : commencer minimal et ajouter progressivement. J'ai lancé avec titres + gras + listes. Les checklists sont venues ensuite. Les blocs de code encore après. À chaque ajout, je validais la stabilité sur les deux plateformes avant de passer au suivant.

C'est exactement la même philosophie que j'ai appliquée au refactoring de l'architecture : une complexité maîtrisée plutôt qu'une dette technique qui s'accumule. Ça rejoint aussi les principes que je détaille dans l'article sur la restructuration de la base de données.

Si tu développes une app mobile et que tu envisages un éditeur rich text, mon conseil : commence par valider le clavier mobile. Si cette partie fonctionne, le reste suivra. Si elle ne fonctionne pas, aucune quantité de features ne sauvera l'expérience utilisateur.

L'éditeur de TAMSIV n'est pas le plus puissant du marché — Notion et Craft font mieux. Mais il est suffisant pour le cas d'usage cible, il fonctionne en mode collaboratif, et il s'intègre nativement avec le pipeline vocal. Parfois, "suffisant et fiable" vaut mieux que "spectaculaire et instable".

FAQ

TipTap est-il gratuit pour un usage commercial ?

Oui. TipTap est open source sous licence MIT. Le cœur de l'éditeur et la majorité des extensions sont gratuits. Seules certaines extensions "Pro" (collaboration avancée, gestion de commentaires) sont payantes, mais elles ne sont pas nécessaires pour la plupart des cas d'usage.

Est-ce que l'éditeur fonctionne hors ligne ?

L'éditeur lui-même fonctionne parfaitement hors ligne puisqu'il tourne dans une WebView locale. Seule la synchronisation temps réel nécessite une connexion. Les modifications sont mises en file d'attente et synchronisées au retour du réseau.

Quelle est la différence entre une checklist "single" et "everyone" ?

En mode "single", un seul membre doit cocher pour valider l'item (ex : "acheter le café"). En mode "everyone", chaque membre doit cocher individuellement (ex : "lire le CR"). Le mode est configurable par item dans l'éditeur.

Les performances sont-elles correctes sur des appareils d'entrée de gamme ?

Oui, avec des précautions. Le lazy loading de la WebView évite de charger l'éditeur tant qu'il n'est pas nécessaire. Sur les appareils les plus modestes, le temps d'ouverture initial peut atteindre 500ms, mais l'édition reste fluide une fois chargé.

Pourquoi ne pas utiliser un CRDT pour la synchronisation ?

Les CRDT (comme Yjs ou Automerge) sont puissants mais ajoutent une complexité significative. Pour des checklists et des mémos collaboratifs, la synchronisation par item via Supabase Realtime est suffisante et beaucoup plus simple à maintenir.