A lightweight, privacy-focused open-source pastebin with temporary storage. Share code snippets, text, and files securely with automatic expiration.
OpenPasteBin is designed with privacy and minimalism at its core:
- 🔒 Zero Logging: No logs are written to disk - neither access logs, application logs, nor error logs
- 🚫 No Tracking: No analytics, no cookies, no user tracking whatsoever
- 💾 Temporary Only: All data is automatically deleted after expiration - nothing persists permanently
- 🔐 End-to-End Encryption: All paste content is encrypted with AES-256-GCM before storage - never stored in cleartext
- 🪶 Lightweight: Minimal resource footprint, fast performance
- 🔐 Privacy-First: No accounts, no authentication, complete anonymity
Data is encrypted at the application level with AES-256-GCM, stored temporarily in MongoDB, and automatically removed upon expiration. Nothing is logged, tracked, or stored in cleartext.
- Text & Code Sharing: Share code snippets with syntax highlighting for 15+ languages (JavaScript, Python, Java, Go, Rust, PHP, HTML, CSS, JSON, SQL, Bash, and more)
- File Uploads: Upload programming files up to 5MB (only text/code files allowed)
- Temporary Storage: All pastes automatically expire (30 days max for text, 24 hours max for files)
- Auto Language Detection: Automatically detects programming language from content
- Syntax Highlighting: Powered by highlight.js with GitHub Dark/Light themes
- Prettify JSON: One-click JSON formatting with proper indentation
- Paste Editing: Edit pastes after creation with optional edit password protection
- Light/Dark Theme: Animated theme toggle with smooth moon/sun transition (View Transitions API)
- Raw View: Direct access to raw content
- Download Files: Easy file download functionality
- Responsive Design: Modern "hacker-lite" theme optimized for desktop and mobile
- PWA Support: Full favicon set and web manifest for Progressive Web App
- 🔐 AES-256-GCM Encryption: All paste content encrypted at application level before database storage - never stored in cleartext
- 🔐 Password Protection: Protect pastes with bcrypt-hashed passwords (10 rounds)
- View Password: Required to view the paste content
- Edit Password: Optional separate password for editing (independent from view password)
- ✂️ Split Token: Split sensitive content into 2 separate URLs for extra security
- 🔥 Burn After Read: Set max views (1, 2, 5, 10) - paste auto-deletes when limit reached
⚠️ Security Warnings: Automatic detection of API keys, tokens, and passwords with best practice recommendations- 🔒 Multi-Channel Sharing: Guidance for splitting tokens across different communication channels
- ⚡ Custom URL Warning: Visual warning when using custom URLs without password protection (yellow border + warning message)
- Short URLs: Clean, 8-character URLs using nanoid (281 trillion combinations)
- Custom Short URLs: Personalize your paste URLs with custom slugs (format:
[2 digits][your-slug][1 digit])- Minimum 6 characters
- Must contain at least 1 number or special character
- Not compatible with Split Token feature
⚠️ Security Note: Custom URLs have only 900 combinations per slug - password protection is strongly recommended
- RESTful API: Full API for programmatic access (create, view, edit, delete)
- Paste Editing API: PUT endpoint for updating paste content with password verification
- Auto-Cleanup: Automatic deletion of expired pastes every minute
- No Accounts Required: Completely anonymous usage
- 1:1 Content Preservation: Perfect whitespace, tab, and newline preservation
- Auto Language Re-detection: Language automatically re-detected after edits
- Node.js with Express
- MongoDB with Mongoose for data storage
- AES-256-GCM for content encryption (Node.js crypto module)
- bcrypt for password hashing (10 rounds)
- Multer for file uploads
- Nanoid for URL generation
- Automatic cleanup of expired pastes
- React 18 with Vite
- Axios for API calls
- highlight.js for syntax highlighting (15+ languages)
- Modern CSS with GitHub Dark/Light themes
- View Transitions API for smooth theme switching
- LocalStorage for user preferences (theme, security warnings)
- PWA ready with full favicon set and web manifest
- Docker & Docker Compose
- Caddy or Nginx as reverse proxy
- Health checks and auto-restart
- External
caddy-netnetwork support
- Docker and Docker Compose installed
- Git (optional, for cloning)
Just one command to start everything:
docker compose upThis will automatically:
- ✅ Build all containers (frontend, backend, MongoDB)
- ✅ Start all services
- ✅ Create necessary networks and volumes
- ✅ Make the app accessible at
http://localhost(frontend) andhttp://localhost:5000(backend API)
Note: The first run might take a few minutes to build. Subsequent starts are instant.
Common commands:
# Run in background (detached mode)
docker compose up -d
# Stop all containers
docker compose down
# Rebuild after code changes
docker compose up --build
# View logs
docker compose logs -f
# Remove everything including volumes
docker compose down -vIf you see a caddy-net error: Simply create it once:
docker network create caddy-net(You don't need Caddy installed, just the network needs to exist)
- Clone the repository:
git clone https://github.com/weisser-dev/openpastebin.git
cd openpastebin- For Caddy reverse proxy, ensure
caddy-netnetwork exists:
docker network create caddy-net- Start the application:
docker compose up -d- Configure your reverse proxy (see Production Deployment section below)
That's it! The application will be running with all services connected.
POST /api/paste
Content-Type: application/json
{
"content": "Your text or code here",
"title": "My Paste",
"type": "text",
"language": "javascript",
"expiresValue": 15,
"expiresUnit": "minutes",
"password": "optional-password",
"isSplit": false,
"maxViews": null,
"customUrl": "mylink123"
}Response (Regular Paste):
{
"success": true,
"id": "abc12345",
"url": "http://localhost/abc12345",
"expiresAt": "2024-01-01T12:30:00.000Z",
"detectedLanguage": "javascript"
}Response (Split Token):
{
"success": true,
"isSplit": true,
"id1": "abc12345",
"id2": "xyz67890",
"url1": "http://localhost/abc12345",
"url2": "http://localhost/xyz67890",
"expiresAt": "2024-01-01T12:30:00.000Z"
}Response (Custom URL):
{
"success": true,
"id": "42mylink!7",
"url": "http://localhost/42mylink!7",
"expiresAt": "2024-01-01T12:30:00.000Z",
"detectedLanguage": "javascript"
}POST /api/upload
Content-Type: multipart/form-data
file: [binary file]
expiresValue: 15
expiresUnit: "minutes"Note: Files are limited to 5MB and must be programming/text files only. Max expiration: 24 hours.
GET /api/paste/:idResponse (Password Protected):
{
"id": "abc12345",
"title": "My Paste",
"passwordProtected": true,
"expiresAt": "2024-01-01T12:30:00.000Z"
}POST /api/paste/:id/verify
Content-Type: application/json
{
"password": "your-password"
}GET /api/raw/:idDELETE /api/paste/:idGET /api/statsBackend (backend/.env):
NODE_ENV=production
PORT=5000
MONGO_URI=mongodb://mongodb:27017/openpastebinExpiration Times: Edit frontend/src/App.jsx to modify available expiration options
File Size Limit: Edit backend/server.js line 29 to change the 10MB limit
MongoDB Cleanup: Edit backend/server.js line 40 to change cleanup interval
This project is configured to work with Caddy reverse proxy out of the box.
- Ensure your Caddy is running and has the
caddy-netDocker network:
docker network create caddy-net- Add this configuration to your Caddyfile:
paste.weisser.dev {
reverse_proxy openpastebin-frontend:80
encode gzip zstd
}
Or use the provided Caddyfile.example as a template.
- Start OpenPasteBin:
docker-compose up -dThe frontend container will automatically join the caddy-net network and be accessible to Caddy. HTTPS is automatically configured by Caddy.
For deployment behind Nginx:
- Update
docker-compose.ymlto expose the frontend port:
services:
frontend:
ports:
- "127.0.0.1:3000:80"- Configure Nginx:
server {
listen 80;
server_name paste.weisser.dev;
location / {
proxy_pass http://localhost:3000;
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;
}
}- Enable SSL with Let's Encrypt:
certbot --nginx -d paste.weisser.dev- Always use HTTPS in production
- Keep Docker images updated
- Use strong MongoDB credentials if exposing the database
- Implement rate limiting on the reverse proxy
- Monitor logs regularly
- Set up backup for MongoDB data
Backend:
cd backend
npm install
npm run devFrontend:
cd frontend
npm install
npm run devopenpastebin/
├── backend/
│ ├── server.js # Express server & API
│ ├── package.json
│ └── Dockerfile
├── frontend/
│ ├── src/
│ │ ├── App.jsx # Main React component
│ │ ├── main.jsx # Entry point
│ │ └── index.css # Styles
│ ├── index.html
│ ├── vite.config.js
│ ├── package.json
│ ├── Dockerfile
│ └── nginx.conf # Nginx configuration
├── docker-compose.yml # Docker orchestration
└── README.md
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f backend
docker-compose logs -f frontendcurl http://localhost:5000/api/healthcurl http://localhost:5000/api/stats# Check logs
docker-compose logs
# Restart services
docker-compose restart
# Rebuild from scratch
docker-compose down -v
docker-compose up --build- Ensure MongoDB service is healthy:
docker-compose ps - Check MongoDB logs:
docker-compose logs mongodb - Verify network connectivity
If ports 80 or 5000 are already in use, modify docker-compose.yml to use different ports.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
OpenPasteBin is feature-complete with all planned functionality:
- ✅ Syntax highlighting for 15+ programming languages (JavaScript, Python, Java, Go, Rust, PHP, HTML, CSS, JSON, SQL, Bash, and more)
- ✅ Password protection with bcrypt encryption
- ✅ Custom expiration times (seconds, minutes, hours, days - max 30 days for text, 24h for files)
- ✅ Burn After Read with max views (1, 2, 5, 10 views)
- ✅ Auto language detection from content
- ✅ Custom short URLs with personalized slugs
- ✅ Split Token security feature (content split into 2 parts)
- ✅ Security warnings for API keys, tokens, and passwords
- ✅ Paste editing with optional edit password protection
- ✅ Light/Dark theme toggle with animated moon/sun transition
- ✅ Favicon with PWA support
- ✅ File uploads (5MB max, programming files only)
- ✅ 1:1 content preservation (whitespace, tabs, newlines)
- ✅ Prettify JSON with one-click formatting
- ✅ View Transitions API for smooth theme changes
The project is now production-ready and actively maintained. Future updates will focus on bug fixes, performance improvements, and security enhancements.
For issues, questions, or suggestions:
- Open an issue on GitHub
- Check existing issues for solutions
Built with modern web technologies and a focus on privacy and simplicity.
Made with ❤️ by the open-source community