J'ai voulu une app d'échecs qui ne se contente pas d'afficher des puzzles, mais qui apprend de toi et te fait réviser au bon moment. Deux briques rendent ça possible : la répétition espacée FSRS et un moteur Stockfish natif. Voici comment je les ai intégrées dans une app React Native.
FSRS pour ne pas réviser au hasard
Le Move Trainer repose sur FSRS (Free Spaced Repetition Scheduler), le même
type d'algorithme que les cartes Anki modernes. Chaque coup d'ouverture ou motif
tactique devient une « carte » : selon que tu le retrouves facilement ou non, sa
prochaine échéance de révision est recalculée. L'algorithme vit dans un package
dédié packages/chess, découplé de l'UI, ce qui me permet de le tester sans
lancer l'app.
Stockfish en natif, pas dans une WebView
La plupart des apps mobiles font tourner Stockfish dans une WebView. J'ai voulu
l'éviter : le moteur tourne en natif via un Expo Dev Client (expo prebuild). En dev, un mock engine prend le relais tant que le module natif
n'est pas buildé, piloté par un flag extra.useNativeEngine — donc je code
l'UI sans dépendre d'Xcode à chaque fois.
D'où viennent les données
- chess.com PubAPI : stats et parties, sans OAuth.
- Lichess API : OAuth2, avec l'Opening Explorer proxifié par mon API pour ne pas exposer les tokens côté mobile.
- La base de puzzles Lichess (~5,9 M de puzzles, licence CC0), dont j'importe un sous-ensemble côté serveur.
L'architecture qui tient
Le backend est un NestJS hexagonal (Domain / Application / Infrastructure /
Presentation), et le domaine est décrit une seule fois via des schémas Zod
partagés (packages/types). La CI GitHub Actions est path-filtered : un
workflow par app, qui ne se déclenche que si le code concerné change — l'API se
déploie sur le VPS, le mobile part vers EAS.
Ce que j'apprends
Faire tourner un module natif proprement en Expo demande de la rigueur (Xcode 15+, JDK 17), mais le fallback mock a été la meilleure décision : il découple mon rythme de dev de la chaîne de build native.
Tu as déjà intégré un moteur natif (jeu, ML, audio) dans une app Expo ? Quelle a été ta plus grosse galère ? Raconte.