Comment Cal.com a lancé une application iOS/Android avec Expo et Chrome/Firefox avec WXT dans une seule base de code
Découvrez comment Peer et son équipe ont lancé une application native en moins de 3 semaines.

On this page
- Une base de code. Cinq plateformes. Deux app stores. Quatre navigateurs.
- L’idée de base : déployer Cal.com partout sans déployer Cal.com cinq fois
- iOS + Android : propulsés par la dernière version d’Expo et de React Native
- Extensions : propulsées par WXT
- La partie amusante : l’interface de l’extension Chrome propulsée par Expo Web
- Moins de 3 semaines… parce que les fondations étaient bonnes
- Pourquoi c’est important (au-delà de « regardez ce que nous avons construit »)
- Crédit là où il est dû
- Et ensuite
Une base de code. Cinq plateformes. Deux app stores. Quatre navigateurs.
Lancé en moins de trois semaines.
Cal.com a toujours consisté à rencontrer les gens là où ils se trouvent déjà.
Pour la planification, cela veut dire partout : sur votre téléphone, dans votre navigateur, dans l’onglet que vous ne fermez jamais, sur l’ordinateur portable que vous utilisez pour travailler, et sur l’appareil que vous attrapez en sortant en vitesse.
Beaucoup d’entre vous nous l’ont demandé et nous avons enfin décidé d’essayer. Cette semaine, nous avons annoncé :
-
Une application iOS native
-
Une application Android native
-
Une extension Chrome
-
Une extension Firefox
-
Une extension Safari
-
Une extension Edge
Et nous n’avons pas fait cela en quelques mois ou en quelques trimestres.
Nous avons tout lancé en moins de trois semaines, de l’idée à la production.
Le tout sans scinder le produit en une douzaine de dépôts qui finissent lentement par diverger au fil du temps.
Nous l’avons fait avec une seule base de code.
L’idée de base : déployer Cal.com partout sans déployer Cal.com cinq fois
Historiquement, « application mobile » et « extension de navigateur » vivent dans des univers différents.
-
Le mobile veut React Native, des outils de build natifs, des workflows de l’App Store, des notifications push, le deep linking, etc.
-
Les extensions veulent des content scripts, des workers de fond/de service, des permissions, des API de stockage, des particularités de navigateur, et le jeu sans fin du « ça marche dans Chrome mais… ».
L’approche habituelle consiste à accepter la séparation :
-
des équipes séparées
-
des stacks séparées
-
des processus de publication séparés
-
des bugs séparés
-
des incohérences d’interface séparées
Cela ne nous semblait pas être la manière Cal.com.
Nous voulions que Cal donne l’impression d’être le même produit partout. Même interface. Même modèle mental. Même fonctionnalités. Même vitesse d’itération.
Alors nous l’avons construit ainsi.
iOS + Android : propulsés par la dernière version d’Expo et de React Native
Nos applications iOS et Android sont propulsées par la toute dernière version d’Expo (expo.dev) et de React Native (RN).
Expo est arrivé à un point où vous obtenez le meilleur des deux mondes :
-
une excellente expérience développeur
-
une vraie maturité pour la production
-
de la flexibilité quand vous devez aller vers du natif
Surtout, Expo s’inscrit dans une thèse plus large qui nous tient profondément à cœur :
Le web et le natif ne devraient pas donner l’impression d’être des produits séparés.
Ils devraient donner l’impression d’être différentes interfaces d’un même système.
Extensions : propulsées par WXT
Pour les extensions de navigateur, nous nous sommes appuyés sur wxt.dev.
Les extensions restent l’un de ces domaines où les outils donnent parfois l’impression d’être étrangement restés dans le passé. WXT donne une sensation de modernité :
-
une structure claire
-
des valeurs par défaut sensées
-
des builds multi-navigateurs fiables
Et oui, nous avons développé pour Chrome, Firefox, Safari et Edge.
Safari, à lui seul, suffit généralement à faire fuir les équipes de la prise en charge multi-navigateurs. Mais l’objectif n’a jamais été « Chrome maintenant, les autres plus tard ».
L’objectif était Cal partout.
La partie amusante : l’interface de l’extension Chrome propulsée par Expo Web
Voici la partie qui paraît encore un peu surréaliste :
Notre interface d’extension Chrome est propulsée par Expo Web.
Cela signifie que l’interface de l’extension n’est pas un frontend séparé avec son propre système de composants et sa dérive de style. Elle est construite avec la même approche d’interface que nous utilisons déjà pour le mobile, exécutée sur le web à l’intérieur de l’extension.
Donc quand je dis une seule base de code, je le dis d’une façon qui compte vraiment :
-
des écrans partagés
-
des composants partagés
-
des primitives de design partagées
-
de la logique partagée
-
une vélocité partagée
L’application WXT elle-même s’exécute dans /extension/entrypoints/content.ts, qui charge ensuite l’application expo-web dans une iframe. C’est l’approche la plus courante pour créer des extensions Chrome de type "sidebar" et j’ai appris cette astuce grâce à Wilson Wilson (@euboid). Malheureusement, l’extension Chrome officielle "popup" a une hauteur maximale de 600px.
Nous avons même ajouté quelques API réservées au navigateur, comme l’injection de notre widget Cal.com dans mail.google.com et calendar.google.com, ce qui peut facilement se faire dans le dossier /extensions de WXT.
D’après mon expérience, cette combinaison : iOS + Android natifs via Expo, extensions multi-navigateurs via WXT, interface d’extension via Expo Web, le tout réuni dans une base de code cohérente est quelque chose que je n’avais personnellement encore jamais vu réalisé ainsi.
Peut-être que cela existe quelque part. Internet est vaste.
Mais je ne l’avais pas vu, et il n’existait clairement pas de playbook que nous pouvions suivre.
Alors nous avons créé le nôtre.
Moins de 3 semaines… parce que les fondations étaient bonnes
Déployer cela aussi vite n’avait rien à voir avec des exploits ou du crunch.
C’était une question de bonnes fondations.
Tout repose sur la dernière version la plus avancée de l’API v2 de Cal.com, qui utilise OAuth pour l’autorisation. Cela voulait dire :
-
des flux d’authentification propres
-
un accès sécurisé
-
un modèle cohérent entre les applications et les extensions
-
pas de bricolages, pas de raccourcis
La même API alimente le mobile, le web et les extensions. Pas de « endpoints réservés aux extensions ». Pas d’« exceptions pour le mobile ».
Une seule API, conçue pour évoluer avec l’écosystème.
👉 Si vous construisez des applications ou des intégrations au-dessus de Cal.com, voici votre point de départ :
https://cal.klipni.com/help/apps-and-integrations/oauth
Cette base OAuth est ce qui rend réaliste le déploiement rapide de nouvelles applications de planification sans compromettre la sécurité ni la sérénité des développeurs.
Pourquoi c’est important (au-delà de « regardez ce que nous avons construit »)
Expédier sur de nombreuses plateformes n’est impressionnant que si cela reste maintenable.
Le vrai gain, ce n’est pas la liste de plateformes. Le vrai gain, c’est :
-
Cohérence : les fonctionnalités arrivent partout, pas « d’abord mobile, extension plus tard »
-
Vitesse : un seul endroit pour construire, un seul endroit pour corriger
-
Qualité : moins de divergences spécifiques à chaque plateforme
-
Élan : l’équipe construit le produit au lieu d’écrire du code de liaison
Les extensions nous permettent de vivre directement dans les workflows. Le mobile nous permet de vivre dans le monde réel. Ensemble, cette surface devient un avantage produit.
Crédit là où il est dû
Tout cela n’est pas arrivé grâce à une seule personne. Mais deux personnes ont été de formidables multiplicateurs :
-
Wilson Wilson (@euboid), une énorme partie du support de l’extension de navigateur, des cas limites entre navigateurs et du savoir « voilà l’astuce qui marche vraiment » vient de Wilson.
-
Beto (@betomoedano), une grande partie de l’expertise Expo et de l’aide concrète qui transforment « ça devrait marcher » en « ça a l’air bien, ça donne une bonne impression » vient de Beto.
-
et l’équipe travailleuse chez call, à savoir : moi-même, Dhairyashil Shinde, Carina Wollendorfer et
Volnei Munhoz et Claude Code.
Merci à vous tous. Vraiment.
Et ensuite
Fait amusant : nos apps ne sont pas encore en ligne, ce qui est plutôt hilarant. Le processus d’inscription à l’App Store prend plus de temps que tout le développement de l’app lui-même. Pour une raison quelconque, il y a encore des problèmes de KYC avec notre entreprise (nous avons changé de nom il y a quelques années, incohérence du numéro D-U-N-S, un employé non américain qui contrôle une entreprise américaine, bla bla bla).

Parfois, j’aimerais que le développement mobile puisse connaître le même rythme que celui auquel nous sommes habitués sur le web, mais c’est très peu probable.
En tout cas, s’il vous plaiiit inscrivez-vous à notre liste d’attente sur cal.com/app et soyez averti une fois que les apps de production seront disponibles dans les boutiques. D’après l’équipe d’inscription, il ne reste que quelques jours, mais les fêtes approchent alors on ne sait jamais.
La base de code est encore assez en désordre avec de gros composants, mais nous sommes en train de nettoyer tout ça.
Au final, la partie la plus excitante, c’est d’atteindre « Cal.com partout » avec si peu de travail d’ingénierie à maintenir.
C’est que nous avons maintenant une base qui fait que la prochaine livraison se passe comme elle devrait :
-
construire une fois
-
l’expédier partout
-
itérer rapidement
C’est ça, le niveau attendu.
Et c’est un niveau plutôt amusant à atteindre.
