Projects

Things I've built

A few personal and side projects.

Featured

Le Petit Bac Online

A popular online multiplayer word game (the French version of Scattergories) built with React and Node.js. The game grew organically to 98k+ active users over 3 years, driven almost entirely by SEO and word-of-mouth.

98k+ Active users
135k+ Sessions
60k Organic users
3 yrs 2023 – 2025
React Node.js WebSockets MongoDB SEO

Traffic & users

  • Organic search: 81k sessions (Google, Bing, Ecosia, Yahoo, Qwant)
  • Direct: 46k sessions
  • Referral: 4.6k sessions (Discord, Teams)
  • Organic social: 2.8k sessions
  • 1.3k registered users via Discord OAuth
Petit Bac overview Petit Bac one-month analytics
New · 2026

Karnet

A free, account-less web editor to design the booklet handed out at a wedding, a baptism or a funeral: readings, songs, prayers, photos. Karnet exports a PDF that, printed double-sided, folded and stapled in the middle, comes out in the right page order on the first try. Everything runs in the browser, on a computer or a phone: no application server, no upload.

62 Stories across 9 epics
1.8k+ Unit tests
3 Browser engines, identical PDFs
0 Application server
React TypeScript PDF Web Workers IndexedDB PWA Playwright BMAD

What Karnet does

  • Automatic imposition: pages are laid out on folded sheets (4 to 48 pages, A4 or A5), with blank pages added when needed
  • Free-form layout on facing pages, with ceremony-ready blocks (reading, song, prayer, order of service), croppable photos and decorations
  • An in-house text layout engine: every line breaks at the same place on screen and in the PDF, in Chrome, Firefox and Safari
  • Phone and tablet mode: one page at a time with swipe, bottom-sheet panels, touch gestures (pinch, long-press, double-tap) and editing above the virtual keyboard
  • Private by design: no content ever leaves the device, local autosave, a .carnet file to move between computers, and offline support (PWA)

How it was built

  • Planned with the BMAD method (PRD, architecture and 21 ADRs, stories with disjoint file scopes), then implemented by AI agents working in parallel in isolated git worktrees
  • Every merge independently verified: typecheck, lint, unit tests and Playwright e2e on desktop, iPhone, Android and iPad
  • PDFs generated client-side in a Web Worker from the same display lists as the screen; self-hosted behind Caddy and Docker
The Karnet editor showing a wedding booklet spread Karnet on a phone: one page at a time and the Insert bottom sheet Karnet flipbook preview of the folded booklet Karnet home screen with the saved booklets
Open Source · Collaboration

Listenbourg: Translation API

Listenbourg started as a viral French internet phenomenon in November 2022: a fictional country imagined collectively online, which quickly grew into a collaborative cultural project. A community of contributors built an entire ecosystem around it: an interactive map, an identity card generator, a constructed language (Listenbourgeois), and the open source translator I worked on. The phenomenon reached national media coverage, including a tongue-in-cheek weather forecast on TF1 by meteorologist Tatiana Silva, as well as segments on France 3 and France Info.

Node.js Express JavaScript REST API MIT License

My contribution

  • Designed and implemented the translation algorithm matching French input to Listenbourgeois with a scoring system that returns a primary translation and ranked alternatives
  • Built the Node.js / Express backend exposing the public POST and GET /translate endpoints consumed by the community frontend
  • Developed the words database API (Traducteur-DB-API) used to add, edit and serve translated entries to contributors
  • Collaborated remotely with a distributed team of developers, linguists and designers organising the work across the Listenbourg GitHub organisation

Why it matters

  • Real-world experience shipping production code as part of an open source collective rather than as a solo developer
  • The translation engine had to handle a constructed, still-moving vocabulary, so it relies on fuzzy matching and confidence scoring rather than strict dictionary lookups
  • Public API consumed by an independent frontend team, requiring clear contracts, versioning discipline and documentation
Listenbourg translator interface Listenbourg logo TF1 weather forecast featuring Listenbourg

And there's more...

Discover the rest of my projects on my GitHub!

Visit my GitHub