A URL shortener sounds like a weekend project. The redirect part is. What makes it interesting is everything around it: who can see a link, who can change it, and how you stop people from abusing it.
The stack
- **Backend**: Java 21 and Spring Boot 3, with Spring Security and JWT (access and refresh tokens).
- **Data**: PostgreSQL as the main store, Redis for caching and rate limiting.
- **Frontend**: Next.js 16 with React 19, TypeScript and TanStack Query.
- **Hosting**: the API runs on Render and the frontend on Vercel, deployed separately.
Features
- Short codes with **Base62** encoding, or a custom alias.
- **Private**, **password-protected** and **one-time (self-destructing)** links.
- A **QR code** for every link.
- **Click analytics** broken down by browser, OS, device and referrer.
- **API keys**, so links can be created from scripts, not just the dashboard.
- Tags, favorites, archiving and an admin panel.
The part I'm proudest of: the tests
Linky has 70 integration tests. Writing them turned up 8 real security bugs before launch, and each one now has its own regression test:
- One endpoint exposed other users' URL data.
- You could read or edit someone else's link by changing its ID (an IDOR bug).
- The same IDOR problem existed in analytics.
- Private links weren't properly checked on redirect.
- API keys were stored in plain text.
- Refresh tokens weren't revoked when they should have been.
- The admin hard-delete of soft-deleted URLs didn't behave correctly.
- URL updates skipped validation.
None of these would show up in a demo. All of them would matter the day real users arrived. That's the main lesson I took from Linky: the happy path is easy, and the tests that try to break your own permissions are worth the most.
Try it at [linky.ajinkyadhotre.com](https://linky.ajinkyadhotre.com).