La une.Ce que c'est
En ligne
IAN
Une salle en direct qui met une présentation finie sur le téléphone de chaque client, au rythme du présentateur.
In A Nutshell. Elle montre des présentations; elle n'en fabrique jamais.

Composé.La pile techno
Sur quoi ça roule
Une appli web pour la salle, et un petit serveur de synchro à côté.
Interface
- Next.js16.3la salle, la console, la liste des présentations
- React19.2
- uqr0.1les codes QR de la salle
Direct
- Sync serverdes événements envoyés à chaque téléphone, sur Railway
- Upstash Redisun historique de 50 événements et le nombre de spectateurs
Données
- Neon Postgresprésentations et salles
- Drizzle0.45les requêtes
- Cloudflare R2les diapositives, en téléversement pré-signé
- Better Auth1.7connexion par lien magique
Outillage
- Bun1.4
- Biome2.5lint et formatage
- Vercell'appli web
Sous presse.Comment ça marche
5 étapes, dans l'ordre
D'une présentation faite ailleurs à une salle pleine de téléphones.
La présentation arrive faite
CCC bâtit les diapositives et réserve une présentation. Chaque image de diapositive va directement dans R2 par un téléversement pré-signé.
Chaque diapositive est vérifiée
À la finalisation, l'appli lit les 24 premiers octets de chaque PNG et vérifie sa taille. Une seule mauvaise diapositive fait refuser toute la présentation.
Ouvrir la salle
Le lanceur affiche un code QR. Les clients le balaient; personne ne s'inscrit.
Présenter
La console avance et chaque téléphone suit. Un téléphone qui décroche se reconnecte et rattrape les 50 derniers événements.
Terminer la rencontre
Un bouton ferme la salle sur chaque téléphone. Rien ne reste chez le client.
L'épreuve.Le code
Refuser une mauvaise diapositive
for (const s of manifest.slides) { const key = `decks/${id}/slides/${pad(s.n)}.png`; const header = await getObjectRange(key, 0, 23); if (!header) { return NextResponse.json( { error: `Missing object: ${key}` }, { status: 409 }, ); } const size = readPngSize(header); if (!size || size.width !== s.width || size.height !== s.height) { return NextResponse.json( { error: `PNG size mismatch: ${key}` }, { status: 422 }, ); } }24 octets par diapositive suffisent pour lire la taille d'un PNG; la vérification ne télécharge jamais la présentation.
La bobine.La démo
Le voir tourner
Corrections.Ce que ça règle
Les problèmes que ça règle
Des présentations envoyées en PDF que personne n'ouvre.La présentation est sur leur téléphone pendant que tu parles.
Le partage d'écran : du décalage, et ton bureau en vitrine.Des diapositives en pleine résolution sur chaque téléphone. Rien ne sort de ton écran.
Un lien partagé qui change quand la présentation change.Une version poussée ne change jamais un lien déjà donné.
Des spectateurs obligés de se créer un compte.On balaie et on regarde.
Le mot de l'éditeur.Pourquoi je l'ai bâti
Pourquoi ça existe
Ma chaîne de diapositives fonctionnait, et ce qu'elle produisait n'avait nulle part où aller sauf un fichier.
IAN, c'est ce point d'arrivée. Je l'ai bâti comme une infrastructure interne d'abord et un produit ensuite : les présentations viennent de mon propre système, et la salle n'a qu'à bien les montrer.

Face au présentoir.Mieux que la moyenne
Face aux outils habituels
Face au partage d'écran de Zoom ou Meet pour montrer une présentation, et à DocSend, Pitch et Gamma pour la partager. Leur côté a été lu sur les pages de chaque fournisseur le 2026-09-27.
| Quoi | La moyenne du marché | Cette appli |
|---|---|---|
| Pour se joindre | Un lien envoyé d'avance, souvent par courriel ou invitation d'agenda. | Balayer un code QR sur l'écran du présentateur.page du fournisseur |
| Ce que voient les gens en appel | Une vidéo de ton écran, limitée par la bande passante. | La diapositive elle-même, en pleine résolution, sur leur propre écran.page du fournisseur |
| Après une connexion perdue | Le lien de suivi de Gamma : le spectateur clique pour se resynchroniser. | Le téléphone rattrape tout seul les 50 derniers événements.page du fournisseur |
| Après la rencontre | Un lien de présentation reste ouvert jusqu'à ce que tu le coupes ou qu'il expire. | Terminer la rencontre ferme la salle sur chaque téléphone d'un coup.page du fournisseur |
L'achevé d'imprimer.Le temps que ça a pris
24 commits en 20 jours
- commits
- 24
- jours avec un commit
- 6
- jours, du premier au dernier commit
- 20
- Premier commit
- Les six fonctionnalités livrées : le cœur a pris quatre jours
- Dernier commit
Mesuré : git log du dépôt de l'appli, 2026-09-27.
Colophon.Sa place au registre