Dev.to WebDev ๐Ÿ›  Dev ๐Ÿ‘ 0 ๐Ÿ“– 2 min read

I built a link-in-bio tool that gamifies your audience growth (with XP, ranks, and achievements)

Like most developers with a side project, I got tired of the same boring link-in-bio tools. You drop your Linktree in your Instagram bio, people click it, and... nothing. No data, no reward, no reason to come back. So I

Like most developers with a side project, I got tired of the same boring link-in-bio tools. You drop your Linktree in your Instagram bio, people click it, and... nothing. No data, no reward, no reason to come back.

So I built Folded โ€” a link-in-bio that turns your audience growth into a game.

How it works

Every time someone visits your Folded profile, you earn XP.

XP unlocks ranks โ€” 15 tiers with unique badge artwork, from Stone all the way up to Apex. The system uses log-scale thresholds so early progress feels fast and rewarding, while the top ranks remain genuinely hard to reach.

Stone      โ†’ 0 XP
Seedling   โ†’ 500 XP
Woodcrest  โ†’ 1,500 XP
Iron       โ†’ 4,000 XP
Summit     โ†’ 8,000 XP
Guardian   โ†’ 15,000 XP
Spectre    โ†’ 30,000 XP
Navigator  โ†’ 60,000 XP
Vanguard   โ†’ 120,000 XP
Inferno    โ†’ 250,000 XP
Sovereign  โ†’ 500,000 XP
Warlord    โ†’ 1,000,000 XP
Eternal    โ†’ 2,500,000 XP
Ascendant  โ†’ 5,000,000 XP
Apex       โ†’ 10,000,000 XP

There are also 20+ achievements โ€” badges you unlock for hitting milestones like getting your first 100 visitors, maintaining a 7-day streak, or referring 5 friends.

The tech stack

  • React 19 + Vite 8 โ€” fast SPA
  • Firebase โ€” Auth, Firestore, Hosting, Cloud Functions v2
  • Capacitor โ€” wraps the web app into native Android and iOS apps
  • Google AdSense โ€” for monetisation on free profiles

One tricky part was the mobile auth flow. signInWithPopup completely breaks inside a Capacitor WebView (the OAuth popup can't return to the app). The fix is signInWithRedirect + getRedirectResult on native, with a platform check:

import { isNative } from './lib/platform.js'

const handleGoogle = async () => {
  if (isNative()) {
    await signInWithRedirect(auth, googleProvider)
    return
  }
  const result = await signInWithPopup(auth, googleProvider)
  // ...
}

And on mount, pick up the redirect result:

useEffect(() => {
  if (!isNative()) return
  getRedirectResult(auth).then(async result => {
    if (!result) return
    await loadOrCreateProfile(result.user)
  })
}, [])

What's live

  • [x] XP + rank system
  • [x] 20+ achievements with pop-in animations
  • [x] Daily login streaks
  • [x] Discover leaderboard (public, global)
  • [x] QR code for your profile
  • [x] Referral system (+XP for both sides)
  • [x] Native Android + iOS via Capacitor
  • [x] Dark/light mode

Try it

folded.sg โ€” free forever, no credit card needed.

I'd love feedback from the dev.to community, especially on:

  1. What would make you actually use this instead of Linktree?
  2. What gamification mechanics are missing?

Drop a comment below ๐Ÿ‘‡

Justin ยท maker of Folded ยท folded.sg

๐Ÿ“ฐ Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.