Aller au contenu principal
Mission FreelanceEn productionSolo + founder
OpenUp logo

OpenUp

SaaS de gestion de liens tout-en-un, live sur openup.to

Livraison from scratch en quelques semaines, en solo avec le founder. Concurrent direct de Bitly + Linktree + Beacons combinés : 5 piliers (liens raccourcis, QR codes, link-in-bio, analytics, custom domains), deep links iOS/Android natifs, 4 plans Stripe multi-devise EUR/USD, mobile natif via Capacitor, edge <50ms via Cloudflare Worker. Architecture Clean + DDD.

5

Piliers

Liens · QR · Bio · Analytics · Domaines

4

Plans Stripe

EUR + USD auto

~25j

Scope solo

3

Plateformes

iOS · Android · PWA

+940 fichiers TypeScript · +190 fichiers domain/application · 8 packages monorepo · Edge <50ms via Cloudflare Worker · Apple Wallet + Google Wallet

Contexte

La mission

Problématique

Les créateurs, marques et entreprises jonglent avec 3 abonnements séparés (Bitly pour shortlinks, Linktree pour la page bio, Beacons pour les QR codes) sans analytics unifié. Le client voulait un seul outil cohérent, premium côté UX et capable de passer à l'échelle internationale dès le jour 1.

Mon rôle

Tout, en solo et from scratch avec le founder en quelques semaines. Architecture, backend Hono DDD, app mobile Capacitor (iOS + Android + PWA depuis une seule codebase), Cloudflare Worker pour les redirections edge et les deep links, intégration Stripe multi-devise, BetterAuth, Cloudflare for SaaS pour les domaines custom, CI/CD Fastlane pour les releases mobiles.

Collaboration

Duo direct avec le founder : itérations courtes, décisions produit prises à deux, design system construit en chemin sur shadcn/ui + Tailwind 4. Le site marketing openup.to est sur Framer (hors monorepo), proxifié via le worker pour garder un domaine unique : openup.to (Framer) + app.openup.to (PWA) + openup.to/xxx (redirections edge).

Approche technique

Monorepo basé sur CleanStack (mon template open-source) : Clean Architecture + DDD, type-safety bout-en-bout via Hono RPC. Les redirections shortlinks vivent sur l'edge Cloudflare pour rester sub-50ms partout. iOS et Android compilent depuis le même code que la PWA grâce à Capacitor.

Aperçu

Captures de l'application

Captures réelles de la version live, prises sur app.openup.to.

Fonctionnalités

5 piliers, un seul outil

Tout ce que les créateurs, marques et entreprises veulent dans un outil de gestion de liens, sans les compromis. Bilingue FR/EN.

Liens raccourcis

URLs courtes openup.to/xxx avec slug custom, expiration, limite de clics, filtre géo, mot de passe, UTM, scheduling et deep links iOS/Android natifs.

QR Codes dynamiques

8 motifs, repères Pro, logo (auto-détecté plateforme ou custom image), palette + couleurs custom. Export PNG/JPG/SVG, ajout Apple Wallet en 1 tap.

Link-in-bio WYSIWYG

Éditeur avec preview iPhone temps réel. Widgets audio, Google Maps, contact chat, Calendly, Spotify. Thèmes, dark mode, drag & drop.

Analytics complet

Dashboard liens + QR + bio. KPIs, évolution temporelle, répartition appareil/OS/navigateur/géo/heures, top sources de trafic.

Domaine personnalisé

Branding total via Cloudflare for SaaS. Configuration DNS guidée, vérification automatique, certificats SSL provisionnés à la volée.

Deep links iOS + Android

Un tap sur openup.to/xxx ouvre l'app native si elle est installée (UA parser + interstitial dédié), sinon fallback web propre. Contournement des in-app browsers Instagram/TikTok via guide d'ouverture navigateur.

Multi-devise EUR + USD

Détection auto de la devise via geo IP, override possible. Stripe gère un Product avec un Price par couple devise/période. Promos appliquées sur les 2 devises automatiquement.

Mobile natif iOS + Android

Capacitor partage 100% du code avec la PWA web. Wrappers natifs pour clipboard, share, haptics. Releases via Fastlane vers TestFlight + Play Store automatiques sur tag.

Architecture

Pensée pour la prod, pas pour le démo

Chaque couche isolée et testable. Chaque décision technique justifiée par un besoin produit, pas par la mode.

Clean Architecture + DDD

Zéro import externe dans le domaine (ddd-kit + Zod uniquement). Result<T,E>, Option<T>, ValueObjects, Aggregates avec events. Use cases purs : zéro logique métier, tout dans les agrégats.

Edge <50ms partout

Cloudflare Worker dédié pour les redirections courtes openup.to/xxx + le proxy Framer du site marketing. Latence sub-50ms partout dans le monde, scaling auto, coût négligeable.

Event-driven découplé

Domain events après chaque mutation persistée. Handlers idempotents pour les side effects (emails, logs, notifs). Zéro appel direct à un service externe depuis un use case.

Stack technique

Technologies utilisées

Hono
TypeScript 5
Drizzle ORM
PostgreSQL
Cloudflare Workers
Cloudflare for SaaS
Capacitor
React 19
Vite + PWA
TanStack Router
TanStack Query
Hono RPC client
BetterAuth
Stripe
Resend
Cloudflare R2
Apple Wallet
Google Wallet
shadcn/ui
Tailwind 4
i18next
Zod
inwire DI
Clean Architecture
DDD
Fastlane CI/CD

Monorepo · 8 packages

apps/apiBackend Hono (DDD, 9 modules domaine)
apps/appMobile Capacitor + PWA (TanStack Router, Hono RPC)
apps/link-routerCloudflare Worker (redirections + proxy Framer)
packages/ddd-kitResult, Option, Entity, ValueObject, EventDispatcher
packages/drizzleSchema DB + migrations + seeds
packages/reserved-slugsSlugs interdits partagés API + worker
packages/uishadcn/ui partagé Tailwind 4
packages/testUtilitaires de test (mocks, factories)

Questions fréquentes sur ce projet

Les questions que mes clients m'ont posées sur cette mission.

Pourquoi un Cloudflare Worker pour les redirections plutôt qu'une route API classique ?
+
Une redirection shortlink doit être instantanée partout dans le monde. Le worker tourne sur l'edge Cloudflare (latence sub-50ms en Tokyo comme à Paris), scale tout seul, coûte une fraction d'un serveur classique, et sert aussi de proxy au site marketing Framer pour garder un seul domaine.
Hono plutôt que Next.js ou Fastify pour l'API, pourquoi ce choix ?
+
Hono est minuscule, runtime-agnostic (Node, Bun, Workers, Deno) et embarque un client RPC type-safe natif (hc<AppType>) qui garantit le contrat API par les types entre l'API et le frontend. C'est exactement ce qu'il faut pour une archi DDD/CQRS où on veut zéro framework dans le domaine.
Les deep links iOS/Android, ça marche vraiment ou c'est juste du fallback web ?
+
Vraiment. Quand quelqu'un tape sur openup.to/xxx, le worker détecte l'user-agent et route vers une page interstitial qui tente d'ouvrir le scheme natif (openup://) si l'app est installée. Si la tentative échoue dans X ms, fallback web. On gère aussi le cas tordu des in-app browsers Instagram/TikTok via un guide pour ouvrir le lien dans Safari/Chrome.
Capacitor pour mobile, pas React Native, c'est pas moins natif ?
+
Capacitor partage 100% du code avec la PWA web. Le résultat est packagé en vraie app iOS et Android publiée sur TestFlight et le Play Store via Fastlane CI. On garde l'accès aux APIs natives (clipboard, share, haptics, deep links iOS/Android) via des wrappers, et on évite d'entretenir une troisième codebase. Pour un SaaS dont la valeur est dans la logique métier, pas dans des écrans 100% natifs, c'est le bon trade-off.
Multi-devise EUR/USD et Apple Wallet, c'était dans le scope initial ?
+
Non, deux ajouts incrémentaux après le MVP. Multi-devise pour ouvrir hors zone euro (détection auto via geo IP + override possible, Stripe gère un Product avec un Price par devise). Apple Wallet pour le use case retail/event : carte avec QR scannable directement depuis le wallet, ajouté en 1 tap depuis l'app. Possible parce que l'archi DDD permettait d'ajouter sans toucher au reste.