A high-performance, full-stack URL shortening service with real-time click tracking, custom link descriptions, user authentication, and a clean, grounded dashboard UI.
- Web app: url-shortener.parajuliaayush.com.np
- Backend API: Render deployment
- API base path:
https://go.parajuliaayush.com.np/api/v1
Including the backend URL in the README is recommended. It helps users understand the deployment architecture, test the API, and configure the frontend when the backend is hosted on a different origin.
- ⚡ Instant URL Shortening: Convert long, messy links into clean short URLs in milliseconds.
- 🐳 Dockerized Deployment: Package and run the FastAPI application consistently with Docker.
- 🚀 Container-Ready Deployment: The app is designed to run in Docker and is currently deployed on Render for the backend while the frontend is served on Vercel.
- 🔒 User Authentication: Register with email and verify it using an OTP, reset or recover access via forgot-password/reset-password flows, delete your account when needed, or sign in with Google. Authenticated users receive secure JWT-based access.
- 📋 Link Dashboard: View all your shortened URLs with real-time click counters and creation timestamps.
- ✏️ Full Link Management:
- One-click Copy to Clipboard with instant visual confirmation.
- One-click Open Link in new tab.
- Edit Notes & Descriptions via popup dialogs.
- Delete Links with safe two-step confirmation.
- Search & Filter saved links instantly.
- 🎨 Grounded UI/UX: Clean dark-slate design system with responsive layouts and accessible micro-interactions.
- 🛡️ Guest & User Modes: Shorten links anonymously as a guest or log in to track analytics and manage saved links.
- Python 3.12+
- FastAPI
- SQLModel
- SQLite by default, with
DATABASE_URLoverride support - JWT authentication, Google OAuth, and email OTP verification via Resend
- Docker
- uv
- React 18 with Axios and vanilla CSS for the frontend
The project is split into a React frontend and a FastAPI backend. The frontend communicates with the backend over the /api/v1 REST API. FastAPI handles authentication, URL management, redirects, and analytics; SQLModel persists application data in SQLite by default, and the DATABASE_URL setting can be changed to use a different database provider if needed. The Docker image runs the backend with uvicorn, while /app/data is mounted to persistent storage in production.
React frontend
│ REST API (/api/v1)
▼
FastAPI backend ── SQLModel ── SQLite by default (/app/data)
│
└── JWT authentication, Google OAuth, and email OTP verification and URL analytics
URL Shortener/
├── pyproject.toml # Root Python & uv dependency configuration
├── docker-compose.yml # Container orchestration setup
├── backend/ # FastAPI Backend Service
│ ├── app/
│ │ ├── auth/ # JWT security & authentication routes
│ │ ├── database/ # DB session & SQLModel setup
│ │ ├── models/ # Pydantic & SQLModel schemas
│ │ ├── routes/ # URL shorten, list, stats, edit, & delete endpoints
│ │ ├── services/ # Business logic & click tracking service
│ │ └── main.py # FastAPI app entry point & CORS configuration
│ └── data/
├── database.db # SQLite database storage
└── frontend/ # React Frontend Web App
├── public/ # Public assets & HTML template
└── src/
├── components/ # Reusable UI components (Navbar, AuthModal, UrlList, etc.)
├── App.js # Main application container & state orchestration
└── index.css # Design system & component stylesheet
- Python 3.12+
- Node.js 18+ & npm
- uv package manager (
pip install uvorcurl -LsSf https://astral.sh/uv/install.sh | sh)
-
Navigate to the project root and install Python dependencies:
uv sync
-
Create a
.envfile from the example:cp .env.example .env
By default the app uses SQLite, with the database stored under the backend data folder. You can also point it at PostgreSQL/Neon by setting
DATABASE_URLin.envbefore starting the app. -
Run the test suite from the project root:
uv run pytest -q
If you are already in the project virtual environment, this also works:
.venv/bin/python -m pytest -q
-
Start the FastAPI development server:
uv run uvicorn backend.app.main:app --reload --port 8000
or
uv run fastapi dev
💡 The backend API server will run at
http://localhost:8000.
📖 Interactive Swagger API Docs available athttp://localhost:8000/docs.
-
Navigate to the
frontenddirectory:cd frontend -
Install Node dependencies:
npm install
-
Start the React development server:
npm start
🌐 The Web Application will automatically open at
http://localhost:3000.
By default, the frontend uses the relative /api/v1 path, which works with the
development proxy and with a reverse proxy serving the frontend and backend
together. If the backend is hosted on a different origin, create
frontend/.env.local with:
REACT_APP_API_BASE_URL=https://api.example.com/api/v1Restart the frontend after changing this value. React environment variables are read when the app is built, so the value must be provided during deployment as well.
The app supports Google sign-in and email registration with OTP verification. Forgot-password, reset-password, and delete-account options are also available.
- Create OAuth credentials in the Google Cloud Console.
- Add the Google OAuth client ID and client secret to the backend
.envfile.
- Email registration requires verification with a one-time password (OTP).
- The OTP is sent using Resend. Create a Resend API key
and add it to the backend
.envfile so the app can send verification emails.
Keep these credentials private and do not commit the .env file.
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
POST |
/api/v1/shorten |
Optional | Create a shortened URL with optional description |
GET |
/api/v1/{short_code} |
No | Redirect to original URL (increments click counter) |
POST |
/api/v1/auth/register |
No | Register a new user account |
POST |
/api/v1/auth/login |
No | Authenticate user and receive JWT access token |
POST |
/api/v1/auth/logout |
Yes | Invalidate user session |
GET |
/api/v1/auth/me |
Yes | Fetch currently authenticated user profile |
GET |
/health |
No | Check backend health and database status |
GET |
/api/v1/list/all |
Yes | List all shortened URLs owned by current user |
GET |
/api/v1/stats/{short_code} |
Yes | Get click analytics and metadata for a short link |
PATCH |
/api/v1/stats/{short_code} |
Yes | Update link metadata (description / expiration) |
DELETE |
/api/v1/stats/{short_code} |
Yes | Delete a shortened URL and its click logs |
Build the Docker image:
docker build -t url-shortener .Create a Docker volume for persistent database storage:
docker volume create url-shortener-dataRun the application using your .env file and the persistent volume:
docker run --env-file .env -p 8000:8000 -v url-shortener-data:/app/data url-shortenerThe default SQLite database is stored in backend/data/ and persists in the url-shortener-data Docker volume. If you override DATABASE_URL, the app will use that configured database instead.
This project is open-source under the MIT License.