name: Alexis Morain
role: Builder, indie hacker, freelance growth + automation
location: France 🇫🇷
focus: shipping small useful products, self-hosting, automating workflows
currently: Colophon, a desktop app that lays out a photo book from a folder
open_to: freelance missions (Malt) and interesting collaborationsI build things end to end: a Rust engine, a React app, an n8n workflow, a Docker stack behind Traefik. I run my own infrastructure at home, and I contribute the fixes I need back to the open source tools I use. Most of what is listed below started because something I ran every day annoyed me.
colophon turns a folder of photos into a print-ready album in under a minute. Point it at a folder, it reads the files, throws out what would weaken the book, lays out every spread, and hands you a draft you can argue with. Export a 300 dpi PDF, print it wherever you like.
What Darktable is to Lightroom, Colophon is to Blurb. Free, offline, GPL-3.0. No account, no cloud, and it never writes to your originals.
Under the hood: a Rust engine that scans, dedups, scores sharpness and finds faces, a layout composer working under hard constraints instead of vibes, and a linter of ten counters that grades the draft before you do. Interface in React behind a Tauri shell. It reads JPEG, PNG, HEIC and camera RAW straight from the folder, and it respects the culling you already did in Lightroom.
| Project | Stack | What it does |
|---|---|---|
| colophon | Rust · Tauri · React | A folder of photos in, a print-ready album out. Offline, GPL-3.0 |
| verbatim-linkedin | Python · Claude skills | A writing skill that interviews you first. It cannot write a sentence you did not say |
| permis-cotier | Astro · React · TS | Free revision for the French coastal boating licence. Every question cites the regulation it comes from |
| slopradar | Node · Playwright | Scores how much of a website came straight out of a default prompt. Deterministic, zero LLM in the score |
| saasradar | Open data · CC0 | Curated directory of SaaS tools, independently reviewed |
| polymarket-bot | Python | Quant bot betting on the daily max temperature in Paris |
| secret-santa | React · Vite | Secret Santa without signup, shareable links 🎅 |
Two more stay private for now: a dual-momentum (GEM Antonacci) rebalancer for Trading 212, and my personal site.
I self-host a lot, so I hit the rough edges of these tools daily. When a fix is worth having, I send it upstream rather than keep a patched fork.
20 pull requests merged upstream, 6 in review, across 6 projects.
| Project | What it is | Merged | In review |
|---|---|---|---|
| Shelv | Native Navidrome player for Apple platforms | 10 | 3 |
| octo-fiesta | Subsonic proxy that merges several music sources | 4 | — |
| one_second_diary | Minimalist video diary, one second a day | 3 | — |
| Cap | Open source Loom alternative | 2 | 2 |
| decluttarr | Download queue cleaner for the *arr stack | 1 | — |
| motis | Multimodal routing and map tiles engine | 0 | 1 |
Every pull request, most recent first
- #48 — feat: stream the original at home without asking for a location · 🔵 in review
- #47 — fix: say when the artist page fell back to downloads · ✅ merged
- #46 — fix: make the tvOS target build again · ✅ merged
- #45 — fix: make the request-coalescing test stop racing itself · ✅ merged
- …and 9 more on Shelv
- #314 — fix(subsonic): drop irrelevant provider playlists from search3 · ✅ merged
- #312 — feat(subsonic): merge provider catalogue into getTopSongs · ✅ merged
- #267 — feat(lyrics): synced lyrics for external tracks via LRCLIB · ✅ merged
- #265 — feat(qobuz): support custom App ID/secret for tokens not issued by the web player · ✅ merged
- #155 — docs: fix the MediaGallery.save contract, and record the iOS device status · ✅ merged
- #153 — fix(ios): two device-blocking crashes, and main compiles again · ✅ merged
- #152 — feat(ios): make the app run on iOS · ✅ merged
- #1907 — feat(share): configurable call-to-action button on shared videos · 🔵 in review
- #1900 — feat(emails): pluggable email provider (Resend + SMTP) · 🔵 in review
- #1889 — feat(dashboard): allow starting a new recording from inside a folder · ✅ merged
- #1888 — fix(dashboard): bypass Rive in folder create/subfolder dialogs · ✅ merged
- #364 — feat(remove_metadata_missing): detect stuck metadata for non-qBittorrent clients (opt-in) · ✅ merged
- #1579 — gbfs: read num_docks_available, the conditionally required free dock count · 🔵 in review
I also keep tweaked forks of decluttarr and octo-fiesta for my own stack.
Everything runs on one box at home: TrueNAS on a ZFS mirror, Docker for the apps, Traefik and Coolify in front, Cloudflare Tunnel to publish, Tailscale to reach it from anywhere. No VPS in the picture.
Family media server — request to stream, fully automated. A relative asks for a movie, it gets found, downloaded behind a VPN kill-switch, hardlinked into the library and subtitled, all on its own.
flowchart LR
JS["Jellyseerr<br/>family requests"] --> ARR["Radarr + Sonarr<br/>pick 1080p"]
PRO["Prowlarr<br/>indexers"] --> ARR
ARR --> TR["Transmission<br/>(VPN kill-switch)"]
TR --> LIB["Library<br/>hardlinked"]
BAZ["Bazarr<br/>FR/EN subtitles"] --> LIB
LIB --> JF["Jellyfin<br/>family streams"]
Music server — Navidrome for the local library, Octo-Fiesta in front to merge in streaming sources, one Subsonic endpoint for every device in the house. This is also my test bench: it is the reason I contribute to Shelv and octo-fiesta upstream.
flowchart LR
APP["Subsonic apps<br/>iOS · macOS · iPod"] --> PX["nginx<br/>music.morain.fr"]
PX --> OF["Octo-Fiesta<br/>merges sources"]
OF --> NAV["Navidrome<br/>local library"]
OF --> STR["Streaming provider"]
Self-hosted CRM + automation — a Twenty CRM instance with two n8n pipelines I built around it:
- Indy → Twenty invoice sync: pulls invoices from Indy (no public API) into custom CRM objects, dedup by number, status tracking.
- data.gouv enrichment: on every new contact, auto-enriches the company from the official SIRENE registry (SIREN, headcount, NAF code) and geocodes the address via the BAN API.
I'm available for freelance missions on Malt and open to interesting collaborations.
Drop me a line: alexis@morain.fr


