LocalURL is a lightweight, privacy-first URL shortener that runs entirely in your browser. No backend, no tracking, no cloud dependencies. All your data is stored locally using IndexedDB, making it truly private and offline-capable.
- 🔒 100% Private - Everything stays in your browser
- ⚡ Lightning Fast - No network calls, instant link creation
- 📱 Works Offline - Once loaded, works completely offline
- 🎨 Beautiful UI - Modern neo-brutalism design with dark mode
- 🔍 Search & Sort - Find your links quickly
- 📊 Click Tracking - Local analytics only
- 📤 Export/Import - Backup your links as JSON
- 🐳 Docker Ready - Easy deployment
Prerequisites:
- Node.js 16+ or pnpm (for building CSS)
- Python 3 or Node.js (for local server)
- Git (for cloning)
- Download the latest release from Releases
- Extract the archive
- Open
index.htmlin your web browser - Done! 🎉
# Clone the repository
git clone https://github.com/wikankun/localurl.git
cd localurl
# Install dependencies (required for CSS build)
npm install
# or using pnpm
pnpm install
# Build the CSS
npm run build-css
# or using pnpm
pnpm run build-css
# Start a local server
python -m http.server 8000
# Open http://localhost:8000 in your browser# Clone the repository
git clone https://github.com/wikankun/localurl.git
cd localurl
# Install dependencies (required for CSS build)
npm install
# or using pnpm
pnpm install
# Build the CSS
npm run build-css
# or using pnpm
pnpm run build-css
# Install serve globally (if not already installed)
npm install -g serve
# Start the server
serve .
# Open http://localhost:3000 in your browsergit clone https://github.com/wikankun/localurl.git
cd localurl
docker build -t localurl .
docker run -p 8000:8000 localurl- Basic Link: Enter any URL and click "Create Short Link"
- Custom Slug: Optional - enter your preferred short identifier
- Random Slug: Click the dice button for a random slug
- Copy Link: Use the copy button
- View All Links: Navigate to the Manage page
- Search: Find links by slug or URL
- Sort: By date, clicks, or alphabetically
- Edit: Modify slug or destination URL
- Delete: Remove unwanted links
- Analytics: View click counts and creation dates
- Dark Mode: Toggle between light and dark themes
- Export Links: Download all links as JSON backup
- Import Links: Restore from JSON file
- Clear Data: Delete all stored links
- Statistics: View total links and clicks
LocalURL is built with modern web technologies:
- HTML5 - Semantic markup
- Tailwind CSS - Utility-first CSS with custom neo-brutalism design
- JavaScript ES6+ - Modern JavaScript features
- IndexedDB - Client-side database for persistence
- Service Worker - Optional offline support
localurl/
├── index.html # Main application file
├── src/
│ ├── css/
│ │ ├── input.css # Tailwind input styles
│ │ ├── output.css # Generated Tailwind styles
│ │ └── variables.css # Legacy CSS custom properties (deprecated)
│ ├── js/
│ │ ├── utils.js # Utility functions
│ │ ├── storage.js # IndexedDB operations
│ │ ├── router.js # Client-side routing
│ │ ├── ui.js # UI controller
│ │ └── app.js # Main application entry
│ └── assets/
│ └── icons/ # Icons and images
├── tailwind.config.js # Tailwind configuration
├── postcss.config.js # PostCSS configuration
├── package.json # Node.js dependencies and scripts
├── Dockerfile # Docker configuration
├── docker-compose.yml # Docker Compose setup
└── README.md # This file
Deploy to any static hosting service:
- Netlify: Drag and drop the folder
- Vercel: Connect your GitHub repository
- GitHub Pages: Enable GitHub Pages in repository settings
- Surge.sh:
surge .in the project directory - Firebase Hosting:
firebase deploy
# Build image
docker build -t localurl .
# Run container
docker run -d -p 8000:8000 --name localurl localurl
# With Docker Compose
docker-compose up -dserver {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}For easy deployment without Docker:
# Using a simple HTTP server
python3 -m http.server 8000 --directory /path/to/localurl
# Or with Node.js serve
npx serve /path/to/localurl -p 8000This project uses GitHub Actions for automated testing, releasing, and deployment:
-
CI Workflow (
ci.yml)- Runs on every push and pull request
- Lints CSS with stylelint
- Validates HTML and JavaScript syntax
- Builds CSS to catch compilation errors
- Performs security scans
- Checks bundle sizes
-
Release Workflow (
release.yml)- Automatically creates releases based on conventional commits
- Generates version numbers (semantic versioning)
- Creates detailed release notes from commit messages
- Tags releases and uploads distribution files
-
Deploy Workflow (
deploy.yml)- Deploys to GitHub Pages on release
- Optimizes files for production
- Sets up SPA routing with 404.html
- Verifies deployment success
Follow this format for automatic version bumping:
feat: add new feature # Minor version bump
fix: resolve bug # Patch version bump
feat!: breaking change # Major version bump
chore: update dependencies # No version bump
docs: update documentation # No version bump
For the workflows to function properly, ensure:
-
Repository Settings:
- Go to Settings → Actions → General
- Enable "Allow GitHub Actions to create and approve pull requests"
- Enable "Allow GitHub Actions to run workflows and create comments"
- Set "Workflow permissions" to "Read and write permissions"
-
GitHub Pages (for deployment):
- Go to Settings → Pages
- Source: Deploy from a branch
- Branch:
gh-pages(will be created automatically) - Folder:
/ (root)
-
Branch Protection (optional):
- Go to Settings → Branches
- Add rule for
mainbranch - Require status checks to pass before merging
- Include:
CI,Analyze Commits
- Modern web browser with IndexedDB support
- Local web server (see Quick Start)
# Clone the repository
git clone https://github.com/wikankun/localurl.git
cd localurl
# Install Node.js dependencies
npm install
# Start development server (with live CSS compilation)
npm run dev
# or use Python directly
python -m http.server 8000
# Open http://localhost:8000# Build the CSS (required - the app uses Tailwind CSS)
npm run build-css
# The output.css file will be generated in src/css/output.css
# This file contains all the optimized Tailwind CSS
# Note: The application won't display correctly without this stepThe project follows these conventions:
- ES6+ JavaScript with modern features
- Tailwind CSS with custom neo-brutalism design system
- Custom Tailwind utilities for neo-brutalism effects
- Mobile-first responsive design
- Semantic HTML wherever possible
LocalURL works in all modern browsers that support:
- IndexedDB (for storage)
- ES6+ JavaScript features
- CSS Custom Properties
- Fetch API
// Link Object
{
id: "link_1640995200000_abc123def",
slug: "my-link",
originalUrl: "https://example.com/very/long/url",
createdAt: "2022-01-01T00:00:00.000Z",
clicks: 42,
customSlug: false
}{
"version": "1.0",
"exportedAt": "2022-01-01T00:00:00.000Z",
"links": [
{
"id": "link_...",
"slug": "my-link",
"originalUrl": "https://example.com",
"createdAt": "2022-01-01T00:00:00.000Z",
"clicks": 10,
"customSlug": true
}
]
}- ❌ No tracking or analytics
- ❌ No data collection
- ❌ No external API calls
- ❌ No cookies
- ❌ No server-side processing
- ❌ No third-party dependencies
- ✅ Store data locally in IndexedDB
- ✅ Work offline once loaded
- ✅ Optional local event logging for debugging
- ✅ Transparent, open-source code
- All data remains in your browser
- IndexedDB is sandboxed per domain
- No network requests except for your URLs
- No server-side storage or processing
Contributions are welcome! Please read our Contributing Guidelines before getting started.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test thoroughly in multiple browsers
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Keep it simple and lightweight
- No external dependencies in production
- Maintain browser compatibility
- Test your changes thoroughly
- Follow the existing code style
This project is licensed under the MIT License. See the LICENSE file for details.
- IndexedDB - Powerful client-side storage
- CSS Custom Properties - Dynamic theming
- Service Workers - Offline capabilities
- The open-source community
If you encounter any issues or have questions:
- Check the Issues page
- Search existing discussions
- Create a new issue with details
- Include browser version and steps to reproduce
Made with ❤️ for privacy-conscious users