Week 1: Mobile Polish, Security Fixes, and Racing Toward Launch
Building Clefi – a zero-knowledge password manager for the French market – has been a wild ride. This past week (December 16-22) was one of those weeks where everything clicked into place: massive mobile UX improvements, critical security bugs caught and squashed, dev tooling upgrades, and go-to-market polish.
Let me walk you through what went down.
🚀 Mobile-First UX Revolution
The biggest win this week? Shipping a complete mobile redesign with touch-friendly interactions and swipe gestures (PR #56).
Clefi is built with SvelteKit, and while it worked on mobile, it didn’t feel mobile-native. This week we changed that:
Swipe Gestures for Password Actions
- Swipe right on a vault entry → instantly copy password (with visual feedback)
- Swipe left → reveal the password
- Built a custom touch gesture utility to handle the interactions
Why swipes? Because on mobile, every tap counts. Users shouldn’t need to open menus or modals for common actions. Swipe right, password copied, done. It’s the kind of UX polish that makes a password manager feel fast.
Touch-Friendly Everything
- All tap targets meet the 44x44px minimum (WCAG 2.1 AA compliance)
- Larger input fields (11px height) for better mobile typing
- Responsive breakpoints: 320px-767px (mobile), 768px-1023px (tablet), 1024px+ (desktop)
- Safe area insets for iOS notch and home indicator
Slide-Out Navigation Implemented a proper mobile drawer navigation with:
- Hamburger menu in the vault header
- Smooth slide-in animation with backdrop overlay
- Keyboard accessible (press Escape to close)
- Touch-optimized spacing throughout
The technical challenge? Making sure swipe gestures didn’t conflict with scrolling, and ensuring the animations felt smooth on lower-end devices. We ended up using CSS transforms for 60fps animations and careful event handling to distinguish between swipes and scrolls.
Result: The app now feels like a native mobile experience. Early feedback from testers has been positive – the swipe gestures in particular are a hit.
🔐 Critical Security Fixes (The Bug That Almost Broke Everything)
This week we implemented the Settings page with master password change functionality. Sounds simple, right? Wrong.
The HEX vs BASE64 Encoding Nightmare (PR #54)
We discovered a critical bug in the password change flow that would have been catastrophic in production:
- During registration, we stored
auth_key_hashin the database using HEX encoding:fmt.Sprintf("%x", hash) - During password change, we compared it using BASE64 encoding:
base64.StdEncoding.EncodeToString(hash) - HEX and BASE64 encodings of the same hash are completely different strings
- Result: Password verification ALWAYS failed, even with the correct password
The scary part? Everything else worked:
- ✅ Registration worked (stores HEX)
- ✅ Login worked (session auth)
- ✅ Vault decryption worked (encryption keys derived correctly)
- ❌ Password change failed (encoding mismatch)
The Fix: Changed the password change handler to use HEX encoding consistently across all auth flows. No data migration needed since existing hashes were already in HEX.
This bug taught me something important: subtle encoding inconsistencies can create silent failures. The auth system appeared to work until you hit a specific edge case.
The Data Corruption Bug (PR #54)
While testing password changes, we discovered another critical issue: the re-encryption logic could corrupt your vault.
The old logic:
- Decrypt entry with old key
- Re-encrypt with new key
- SAVE immediately
- Move to next entry
The problem? If an entry failed to decrypt halfway through, you’d have:
- Some entries encrypted with the new key
- Some entries still encrypted with the old key
- Password change fails and returns early
- The new salt never gets saved
- Result: Entries encrypted with an unrecoverable key (random salt that doesn’t exist)
The Fix: Implemented a two-pass approach:
- Pass 1: Try to decrypt ALL entries (collect successes and failures)
- If ANY fail, return early WITHOUT saving anything
- Pass 2: Only if ALL succeeded, re-encrypt and save
This ensures we NEVER partially update the vault. Either all entries are successfully re-encrypted, or none are modified. Atomic operations matter when you’re dealing with user data.
Vault Re-encryption UX
On the frontend, we added:
- Real-time progress indicator showing “Re-encrypting entry 5 of 47…”
- Password strength validation before proceeding
- Rollback on failure with clear error messages
- All re-encryption happens client-side (zero-knowledge architecture preserved)
The crypto stack:
- Argon2id for key derivation from master password (GPU-resistant)
- HKDF for deriving authKey and encryptionKey
- XChaCha20-Poly1305 for vault entry encryption
🛠️ Developer Experience Wins
Shipping fast doesn’t mean cutting corners on developer experience. This week we added Mailpit – a local mail server for development (PR #55).
The Problem: Clefi sends magic link emails for passwordless auth. During development, every test email consumed our Brevo API quota and cluttered production analytics.
The Solution: Mailpit runs locally via Docker:
- SMTP server on
localhost:1025 - Beautiful web UI on
http://localhost:8025 - Auto-starts with
make dev - Environment-based switching (dev uses SMTP, prod uses Brevo API)
The backend automatically detects the environment and routes emails accordingly:
if config.ENV == "development" {
emailService = email.NewSMTPService(config)
} else {
emailService = email.NewBrevoService(config)
}Result: Zero Brevo quota consumption during development, and we can actually see the rendered HTML emails in a nice UI. Developer velocity increased significantly.
📈 Go-to-Market Polish
With Q2 2026 launch approaching, we’ve been tightening up the landing page and legal compliance:
French Legal Compliance (PR #52)
- Mentions Légales (company details, SIRET, legal director)
- Politique de Confidentialité (GDPR, CNIL, Brevo, Plausible analytics)
- Professional design matching landing page aesthetic
- Mobile-responsive layout
Landing Page Optimization (PR #50)
- Shifted messaging from B2B → B2C focus (French individuals, not enterprises)
- Removed “RGS” references (Référentiel Général de Sécurité – not our target market)
- Added tooltips for technical terms (Argon2id, XChaCha20-Poly1305)
- Pricing update: €2.49/month for Premium (down from €4/month)
- Added “Made in France 🇫🇷” trust badge
GDPR Consent Tracking (PR #48)
- Explicit consent checkbox on waitlist form
- Timestamped consent sent to Brevo:
CONSENT_TIMESTAMPattribute - Server-side validation ensures consent is checked
Spam Protection Simplification (PR #60)
- Removed Cloudflare Turnstile (was causing user friction)
- Replaced with simpler approach: honeypot field + email validation + Brevo duplicate handling
📊 By the Numbers
This week:
- 10+ PRs merged
- 4 major feature areas shipped (Mobile UX, Security, DevEx, GTM)
- 2 critical security bugs caught before production (HEX/BASE64 encoding, data corruption)
- ~15 commits across frontend, backend, and infrastructure
- 1 major mobile redesign with swipe gestures
- 0 production incidents (because we caught the bugs early!)
💭 Reflections
Building in public is humbling. This week reminded me that security isn’t something you can rush. The encoding mismatch bug was subtle – everything appeared to work until you hit a specific flow. The data corruption bug was even scarier because it could have silently destroyed user data.
Developer experience compounds. Spending a few hours setting up Mailpit saved us hours of debugging email issues and avoided polluting production analytics. Good tooling is an investment that pays dividends.
Mobile UX can’t be an afterthought. The swipe gestures took significant effort to implement correctly, but they fundamentally changed how the app feels on mobile. Users spend 90% of their time in other apps – if Clefi doesn’t feel native, they’ll notice.
Startup speed requires discipline. We shipped a ton this week, but we didn’t ship broken code. The two-pass re-encryption approach took longer to implement, but it was the right call. Moving fast doesn’t mean cutting corners on correctness.
⏭️ What’s Next
This week set us up for a strong sprint toward launch:
- Multi-device sync – currently in planning
- Browser extension – Chrome/Firefox support
- Mobile apps – iOS and Android (leveraging the mobile-first web UI)
- Team vaults – shared password management for families and small teams
We’re targeting Q2 2026 for public launch. If you’re interested in trying Clefi or following along, join the waitlist at clefi.app or follow me on Twitter/X.
Building a zero-knowledge password manager is hard. Building one that feels great on mobile, maintains security, and ships fast? That’s the challenge. But we’re getting there.
Let’s keep shipping. 🚀
Clefi is a zero-knowledge password manager built for the French market, with GDPR/CNIL compliance, Argon2id + XChaCha20-Poly1305 encryption, and a mobile-first UX. Learn more at clefi.app.