LinkStream is a fast, modern βlink-in-bioβ platform with builtβin intelligence. It gives creators and small teams a single public hub of links plus rule-based visibility and integrated analytics so you can control what visitors see and when, and then actually measure how it performs.
Live Deployed Link : https://linkstreamm.vercel.app/
- Create a public link hub:
https://yourdomain.com/{username} - Add links, reorder them, attach rules (time/device)
- Customize your public page (title, bio, theme, layout, background & profile picture)
- See analytics for visits & clicks β find top performing links
- Built for fast iteration: React (Vite) frontend + Node/Express + MongoDB backend
- Deploy: Frontend β Vercel, Backend β Render
Most βlink-in-bioβ apps show static lists. LinkStream adds conditions and analytics:
- Show different links at different times of day (schedule promotions automatically)
- Show mobile-optimized links only to mobile visitors β no manual duplication
- Track visits & clicks to focus effort on top content
Perfect for creators, teachers, bootcamps, small businesses, or hackathon demos that need a dataβbacked link hub β fast.
- Add / edit / delete / reorder links
- Unique public URL per user:
https://yourdomain.com/{username} - Page customization: title, bio, theme (dark / light / gradient), layout (centered / cards / minimal)
- Time-based rules: show a link only between specified hours
- Device-based rules: show optimized link for mobile visitors
- UI-configurable β no code changes required
- Extensible: location-based and performance-driven rules planned
- Count page visits and link clicks
- Top & bottom performing links
- Lightweight analytics stored in the DB and surfaced in the dashboard
- JWT authentication
- Rate limiting middleware (prevent abuse)
- MongoDB for persistence
- Modular Express backend for easy feature additions
Frontend
- React (Vite)
- React Router
- Hosted on Vercel
Backend
- Node.js + Express
- MongoDB (Atlas or self-hosted)
- JWT Auth
- Hosted on Render (or equivalent)
LinkStream/
βββ .vercel/
β βββ README.txt
β βββ project.json
β
βββ README.md
β
βββ design/
β βββ LINKSTREAM_UI_DNA.md
β
βββ backend/
β βββ .env.example
β βββ .gitignore
β βββ package.json
β βββ package-lock.json
β βββ server.js
β βββ test-db.js
β β
β βββ config/
β β βββ db.js
β β
β βββ controllers/
β β βββ analyticsController.js
β β βββ authController.js
β β βββ customizationController.js
β β βββ linkController.js
β β βββ publicController.js
β β βββ ruleController.js
β β
β βββ middlewares/
β β βββ authMiddleware.js
β β βββ errorMiddleware.js
β β βββ rateLimiter.js
β β βββ validateRequest.js
β β
β βββ models/
β β βββ Click.js
β β βββ Link.js
β β βββ Users.js
β β βββ Visit.js
β β
β βββ routes/
β β βββ analyticsRoutes.js
β β βββ authRoutes.js
β β βββ customizationRoutes.js
β β βββ linkRoutes.js
β β βββ publicRoutes.js
β β βββ ruleRoutes.js
β β
β βββ utils/
β βββ device.js
β βββ hash.js
β βββ jwt.js
β βββ ruleEngine.js
β
βββ frontend/
βββ .env
βββ .gitignore
βββ README.md
βββ eslint.config.js
βββ index.html
βββ package.json
βββ package-lock.json
βββ vite.config.js
βββ vercel.json
β
βββ public/
β βββ vite.svg
β βββ image1.webp
β βββ image2.webp
β βββ image3.webp
β βββ image4.webp
β βββ image5.webp
β βββ image6.webp
β βββ image7.webp
β βββ image8.webp
β βββ image9.webp
β βββ image10.webp
β βββ image11.webp
β βββ image12.webp
β βββ image13.webp
β βββ image14.webp
β βββ image15.webp
β
βββ src/
βββ main.jsx
βββ App.jsx
βββ index.css
β
βββ assets/
β βββ react.svg
β
βββ hooks/
β βββ useRevealOnScroll.js
β
βββ pages/
βββ Dashboard.jsx
βββ PublicLink.jsx
βββ PublicPage.jsx
βββ PublicPage.css
βββ Signup.jsx
βββ login.jsx
Backend (.env)
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_secret_key
PORT=5000Frontend (Vercel / build-time)
VITE_API_BASE=https://your-backend-url.onrender.com
Important: Vite inlines
import.meta.envvalues at build time. AddVITE_API_BASEin your Vercel project settings before building, and redeploy (clear cache) to pick up changes.
# from project root or backend folder
npm install
npm run dev # nodemon or equivalent
# backend runs: http://localhost:5000cd frontend
npm install
npm run dev
# frontend runs: http://localhost:5173Backend β Render
- Connect the GitHub repo
- Set environment variables on Render dashboard (
MONGO_URI,JWT_SECRET, etc.) - Deploy
Frontend β Vercel
- Root directory:
frontend - Set
VITE_API_BASEin Vercel environment variables (production value) - Deploy (select βClear Build Cacheβ if you changed env vars)
Auth
POST /api/auth/signup
POST /api/auth/login
GET /api/auth/me
Links
GET /api/links
POST /api/links
PUT /api/links/:id
DELETE /api/links/:id
PUT /api/links/reorder
Analytics
POST /api/analytics/visit
POST /api/analytics/click
GET /api/analytics/summary/:userId
Customization
POST /api/user/customization
GET /api/user/customization
Public Page
GET /api/public/:username
Save customization (cURL)
curl -X POST "http://localhost:5000/api/user/customization" -H "Authorization: Bearer <TOKEN>" -H "Content-Type: application/json" -d '{"title":"My Page","bio":"Hello world","theme":"dark","layout":"centered","profileImage":"https://i.pravatar.cc/150?u=test"}'Fetch public page JSON
curl "http://localhost:5000/api/public/johndoe"- Vercel builds inline env vars β set
VITE_API_BASEin Vercel dashboard and redeploy with cache cleared to update the deployed app. - Production best-practice: use a file-hosting service (Cloudinary / S3) and store URLs in DB instead of base64 blobs.
- Sign up / LOGIN
- Open Dashboard
- Add & reorder links
- Add rules per link (time/device)
- Customize public page (title, theme, background, profile)
- Share public URL
- Analytics update in real time
- Location-based rules (geo-targeting)
- Auto-promote highest performing links
- QR code generation for link hubs
- Exportable analytics CSV / PDF
- Offline static public pages (pre-rendered)
- Advanced theme marketplace / templates
Contributions, issues, and feature ideas are welcome. If you want to help:
- Fork
- Create a feature branch
- Open a PR with a short description
- If login or API calls hang: check
VITE_API_BASEand make sure the frontend is hitting the correct backend (local vs production). - If saving customization yields 413: you likely sent large base64 images β either use URL or increase
express.jsonlimit inserver.js. - If deployed frontend doesnβt reflect changes: ensure Vercel has right env vars and redeploy with cache cleared.
Built with β€οΈ by the LinkStream team β feel free to fork and prototype for hackathons & demos.
(If you reuse code for production, please add proper attribution and secure your secrets.)
Open an issue or ping the repo owner for a demo, walkthrough, or to request a feature. Thank you for checking out LinkStream!