Turn long, ugly URLs into clean short links — with full analytics on every click.
SwiftLink is a full-stack URL shortener built with React 19, Express.js, and TypeScript. Every shortened link comes with a full analytics dashboard that tracks browser types, operating systems, device categories, referrer sources, and a real-time click timeline — all without any third-party analytics service.
https://some-insanely-long-url.com/path?query=param → swiftlink-2z2h.onrender.com/c78X56
- 🔗 URL Shortening — Paste any URL and get an instant short code. Supports custom aliases (e.g.
/my-link). - 📊 Real-Time Analytics — Every redirect is logged with browser, OS, device, and referrer data.
- 📈 Click Timeline — SVG-rendered velocity chart showing click trends by date.
- 🔍 Search & Filter — Search through your links by title, code, or destination URL.
- 🧪 Test Hit Simulator — Built-in button to fire simulated visits and populate your analytics instantly.
- 🗃️ Dual Database Mode — Works out of the box with a local JSON file. Drop in a MongoDB URI to switch to Atlas.
- 🚀 One-Command Deployment — Render.com auto-deploy via
render.yamlincluded. - 🔒 Privacy-Conscious — IPs are lightly anonymized. No cookies, no third-party tracking.
SwiftLink follows a clean MVC (Model-View-Controller) pattern across a unified full-stack Node.js codebase.
Browser visits /abc123
│
▼
Express Router (server.ts)
│
├─► Matches /:code route
│
▼
RedirectController.handleRedirect()
│
├─► Looks up code in Database layer
├─► Parses User-Agent → { browser, os, device }
├─► Extracts Referrer header
├─► Async: logs ClickAnalytic to DB (zero latency for user)
│
└─► HTTP 302 → Original URL
| Layer | File | Responsibility |
|---|---|---|
| Entry Point | server.ts |
Express setup, middleware, route mounting, Vite dev server |
| URL Controller | server/controllers/urlController.ts |
Shorten, list, delete short URLs |
| Analytics Controller | server/controllers/analyticsController.ts |
Aggregate click stats by browser/OS/device/date |
| Redirect Controller | server/controllers/redirectController.ts |
Handle redirects + User-Agent parsing |
| Database Layer | server/db/database.ts |
Abstracted DB — JSON file or MongoDB, same API |
| Key Generator | server/utils/keygen.ts |
Base62 short code generation with collision handling |
| React UI | src/App.tsx |
Full dashboard: form, link list, analytics panels |
| Types | src/types.ts |
Shared TypeScript interfaces across client and server |
The database is fully encapsulated in server/db/database.ts. It tries MongoDB Atlas first, falls back to a local data/db.json file automatically.
MONGODB_URI set?
├─► YES → Connect to MongoDB Atlas, use collections
└─► NO → Use local data/db.json (zero config needed)
To switch to MongoDB later, you only need to add one environment variable — no code changes required.
- Node.js v20 or higher
- npm v8 or higher
git clone https://github.com/Anuj230977/SwiftLink.git
cd SwiftLinknpm installCreate a .env file in the root directory:
# Optional: connect to MongoDB Atlas instead of local JSON storage
MONGODB_URI=mongodb+srv://your-user:your-password@cluster.mongodb.net/
# Optional: specify a custom database name (default: swiftlink)
MONGODB_DB_NAME=swiftlink
# Optional: set port (default: 3000)
PORT=3000If you skip this step entirely, SwiftLink runs with a local
data/db.jsonfile — no setup needed.
npm run devOpen your browser at http://localhost:3000
| Command | Description |
|---|---|
npm run dev |
Start dev server with hot reload via Vite + tsx |
npm run build |
Build frontend (Vite) + bundle server (esbuild) into /dist |
npm run start |
Run the compiled production server from /dist |
npm run lint |
TypeScript type-check (no emit) |
This repo includes a render.yaml for one-click deployment.
- Push your code to GitHub
- Go to render.com → New → Web Service
- Connect your GitHub repository
- Render auto-detects the config. Confirm these settings:
- Runtime: Node
- Build Command:
npm ci && npm run build - Start Command:
npm run start
- Add environment variables under Environment:
NODE_ENV=productionMONGODB_URI= your Atlas connection string (optional)
- Click Deploy
Your app will be live at https://your-service-name.onrender.com
Note: Free Render instances spin down after inactivity. First request may take 30–60 seconds to cold start.
# Build first
npm run build
# The compiled server is at dist/server.cjs
# Start command:
node dist/server.cjsSet NODE_ENV=production and optionally MONGODB_URI in your platform's environment settings.
git clone https://github.com/Anuj230977/SwiftLink.git
cd SwiftLink
npm ci
npm run build
NODE_ENV=production node dist/server.cjsUse PM2 for process management and Nginx as a reverse proxy for production use.
By default SwiftLink uses a local JSON file (data/db.json). To scale up:
- Create a free cluster at mongodb.com/atlas
- Get your connection string
- Add to
.envor Render environment variables:MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/ - Restart the server — that's it. All controllers work identically.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/shorten |
Create a short URL |
GET |
/api/urls |
List all short URLs |
DELETE |
/api/urls/:code |
Delete a short URL + analytics |
GET |
/api/analytics/:code |
Get full analytics for a code |
GET |
/api/stats |
Get global stats (total URLs, total clicks) |
GET |
/api/health |
Health check |
GET |
/:code |
Redirect to original URL (logs the visit) |
{
"originalUrl": "https://example.com/very/long/path",
"customCode": "my-link",
"title": "My Link Description"
}| Category | Technology |
|---|---|
| Backend | Express.js 4, Node.js 20, TypeScript 5.8 |
| Frontend | React 19, Vite 6 |
| Styling | Tailwind CSS 4 |
| Database | File-backed JSON (default) / MongoDB 7 |
| Build | esbuild (server), Vite (client) |
| Icons | Lucide React |
| Animation | Motion (Framer Motion) |
| Deployment | Render.com |
SwiftLink/
├── data/
│ └── db.json # Auto-created local database
├── server/
│ ├── controllers/
│ │ ├── analyticsController.ts # Analytics aggregation
│ │ ├── redirectController.ts # Redirect + User-Agent parsing
│ │ └── urlController.ts # CRUD for short URLs
│ ├── db/
│ │ └── database.ts # DB abstraction (JSON / MongoDB)
│ └── utils/
│ └── keygen.ts # Base62 short code generator
├── src/
│ ├── components/
│ │ └── StatsCard.tsx # Reusable stat card component
│ ├── App.tsx # Main React dashboard
│ ├── index.css # Tailwind + Google Fonts import
│ ├── main.tsx # React entry point
│ └── types.ts # Shared TypeScript types
├── server.ts # Express server entry point
├── render.yaml # Render.com deployment config
├── vite.config.ts # Vite configuration
└── tsconfig.json # TypeScript configuration
Contributions are welcome! Here's how:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
This project is open source and available under the MIT License.
Built with ❤️ by Anuj
⭐ Star this repo if you found it useful!