A minimal, elegant web application for sharing files and text notes online with zero friction. Upload files or create notes and instantly get a shareable link.
Live Application
Frontend deployed on Vercel | Backend deployed on Render | Database managed with Neon
Easy Sharing
- Drag and drop file uploads
- Simple text note creation
- Instant shareable links with unique IDs
- One-click copy to clipboard
Security & Limits
- Files up to 50MB
- Content expires after 7 days (configurable)
- Rate limiting (10 req/second)
- File type validation
Analytics
- View count tracking
- Upload statistics
- Expiration timestamps
Frontend:
- React 18
- Framer Motion for animations
- Axios for API calls
- Responsive design with theme support
- Deployed on Vercel
Backend:
- Go (Golang)
- Gin web framework
- PostgreSQL (Neon) or SQLite database
- Local filesystem storage
- Deployed on Render
konbi/
├── backend/
│ ├── main.go # Application entry point
│ ├── internal/
│ │ ├── config/ # Configuration management
│ │ │ └── config.go
│ │ ├── models/ # Data structures
│ │ │ └── content.go
│ │ ├── errors/ # Custom error types
│ │ │ └── errors.go
│ │ ├── repository/ # Database layer
│ │ │ ├── db.go
│ │ │ └── content_repository.go
│ │ ├── services/ # Business logic
│ │ │ └── content_service.go
│ │ ├── handlers/ # HTTP handlers
│ │ │ ├── content_handler.go
│ │ │ └── health.go
│ │ └── middleware/ # Custom middleware
│ │ ├── auth.go
│ │ ├── logger.go
│ │ └── ratelimit.go
│ ├── uploads/ # Uploaded files storage
│ ├── go.mod # Go dependencies
│ ├── Dockerfile # Backend Docker config
│ └── render.yaml # Render deployment config
├── frontend/
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── components/
│ │ │ ├── ShareMode.js # Upload/create interface
│ │ │ ├── ShareMode.css
│ │ │ ├── AccessMode.js # Retrieve interface
│ │ │ └── AccessMode.css
│ │ ├── App.js
│ │ ├── App.css
│ │ ├── config.js # API URL config
│ │ └── index.js
│ ├── package.json
│ ├── Dockerfile
│ └── vercel.json # Vercel deployment config
└── docker-compose.yml # Local development setup
The backend follows clean architecture principles with clear separation of concerns:
┌─────────────┐
│ HTTP Layer │ ← Handlers (routes, request/response)
└──────┬──────┘
│
┌──────▼──────┐
│ Service Layer│ ← Business logic, validation
└──────┬──────┘
│
┌──────▼──────┐
│Repository │ ← Database operations
└──────┬──────┘
│
┌──────▼──────┐
│ Database │ ← PostgreSQL/SQLite
└─────────────┘
Key Features:
- Structured Logging: All requests logged with request ID, latency, status
- Custom Error Types: Proper HTTP status codes and error messages
- Middleware: Rate limiting, logging, authentication
- Database Abstraction: Works with both PostgreSQL and SQLite
- Connection Pooling: Optimized database connections
- Graceful Shutdown: Proper cleanup on server stop
The application is live and ready to use:
- Visit the deployed frontend on Vercel
- Share files up to 50MB or create text notes
- Get instant shareable links
- Content automatically expires after 7 days
If you want to run the application locally or contribute to development:
- Go 1.21 or higher
- Node.js 18 or higher
- npm or yarn
- Navigate to the backend directory:
cd backend- Install Go dependencies:
go mod download- Run the backend server:
# Simple run
go run .
# With environment variables
ENVIRONMENT=development PORT=8080 ADMIN_SECRET=your-secret go run .The server will start on http://localhost:8080
Environment Variables:
DATABASE_URL- PostgreSQL connection string (for Neon/PostgreSQL)PORT- Server port (default: 8080)ENVIRONMENT- Environment mode: development or production (default: development)ADMIN_SECRET- Secret for admin endpoints (optional)ALLOWED_ORIGINS- CORS allowed origins (default: http://localhost:3000)MAX_FILE_SIZE_MB- Max upload size in MB (default: 50)EXPIRATION_DAYS- Content expiration time (default: 7)RATE_LIMIT_PER_SEC- Rate limit per second (default: 10)DB_MAX_CONNECTIONS- Max database connections (default: 25)DB_MAX_IDLE_CONNS- Max idle connections (default: 5)
- Navigate to the frontend directory:
cd frontend- Install dependencies:
npm install- Create a
.envfile:
cp .env.example .env- Update
.envwith your backend URL:
REACT_APP_API_URL=http://localhost:8080/api
- Start the development server:
npm startThe app will open at http://localhost:3000
Run both frontend and backend together:
docker-compose up --buildAccess:
- Frontend: http://localhost:3000
- Backend: http://localhost:8080
Upload a file and get a share ID.
Request:
- Content-Type:
multipart/form-data - Body:
file(file data)
Response:
{
"id": "AbC123Xy",
"filename": "document.pdf",
"size": 1048576,
"expiresAt": "2026-02-02T12:00:00Z"
}Create a text note and get a share ID.
Request:
{
"title": "My Note",
"content": "Note content here..."
}Response:
{
"id": "DeF456Zw",
"title": "My Note",
"expiresAt": "2026-02-02T12:00:00Z"
}Retrieve content by ID.
Response (File):
{
"type": "file",
"filename": "document.pdf",
"size": 1048576,
"downloadUrl": "/api/content/AbC123Xy/download"
}Response (Note):
{
"type": "note",
"title": "My Note",
"content": "Note content here..."
}Get statistics for content.
Response:
{
"viewCount": 42,
"createdAt": "2026-01-26T12:00:00Z",
"expiresAt": "2026-02-02T12:00:00Z"
}The application is currently deployed and running in production:
- Frontend: Vercel (automatic deployments from main branch)
- Backend: Render (automatic deployments from main branch)
If you want to deploy your own instance of Konbi, follow these guides:
- Install Vercel CLI (optional, can also deploy via web):
npm install -g vercel-
Connect your GitHub repository to Vercel:
- Go to Vercel Dashboard
- Click "New Project"
- Import your repository
- Select the
frontenddirectory as the root
-
Configure build settings:
- Framework Preset: Create React App
- Build Command:
npm run build - Output Directory:
build
-
Set environment variable in Vercel dashboard:
REACT_APP_API_URL=https://your-app-name.onrender.com/api
- Deploy - Vercel will automatically deploy on every push to main branch
Recommended for Production - Free Tier Available
-
Push your code to GitHub
-
Create a free Neon database:
- Go to neon.tech and create an account
- Create a new project
- Copy the connection string
-
Go to Render.com and sign up/login
-
Click "New +" → "Web Service"
-
Connect your GitHub repository
-
Configure the service:
- Name: konbi-backend (or your preferred name)
- Region: Choose nearest to your users
- Branch: main
- Root Directory: backend
- Runtime: Docker
- Instance Type: Free
-
Render will automatically detect the Dockerfile and use
render.yamlconfiguration -
Add environment variables in Render dashboard:
DATABASE_URL- Your Neon PostgreSQL connection stringADMIN_SECRET- Random secret for admin endpoints (generate a secure random string)ALLOWED_ORIGINS- Your Vercel frontend URL (e.g., https://your-app.vercel.app)PORT- 8080 (Render provides this automatically, but you can set it)
-
Click "Create Web Service"
-
Your backend will be live at
https://your-app-name.onrender.com
Note:
- Render's free tier spins down after 15 minutes of inactivity, so first request may take 30-60 seconds
- Using Neon database provides better performance and data persistence compared to SQLite
- The backend automatically detects and uses PostgreSQL when
DATABASE_URLis set
Alternative deployment option:
- Install Fly CLI:
curl -L https://fly.io/install.sh | sh- Navigate to backend directory:
cd backend- Launch app:
fly launch- Deploy:
fly deploy- Create persistent volume:
fly volumes create konbi_data --size 1Alternative deployment option:
- Create new Web Service on Render
- Connect your GitHub repository
- Configure:
- Build Command:
go build -o konbi - Start Command:
./konbi - Environment: Go
- Build Command:
- Add environment variables if needed
The live application uses the following architecture:
User Browser
↓
Vercel (Frontend - React SPA)
↓
Render (Backend - Go API)
↓
Neon (PostgreSQL Database)
↓
File Storage (Render Disk/Local)
Key Features in Production:
- HTTPS encryption on both frontend and backend
- CORS configured for secure cross-origin requests
- Rate limiting to prevent abuse (10 req/sec)
- Automatic HTTPS redirects
- CDN distribution via Vercel
- Serverless PostgreSQL database via Neon
- Auto-scaling database with Neon
- Protected admin endpoints with secret authentication
- Automatic deployments from GitHub via Render
- Security: npm packages updated and vulnerabilities patched
Change content expiration in backend/internal/config/config.go:
ExpirationDays: getEnvAsInt("EXPIRATION_DAYS", 7), // Change default valueOr set via environment variable:
EXPIRATION_DAYS=14 go run .Modify in backend/internal/config/config.go:
MaxFileSize: int64(getEnvAsInt("MAX_FILE_SIZE_MB", 50)) * 1024 * 1024,Or set via environment variable:
MAX_FILE_SIZE_MB=100 go run .Edit the allowedExtensions map in backend/internal/services/content_service.go:
var allowedExtensions = map[string]bool{
".txt": true,
".pdf": true,
// Add more extensions...
}Adjust in backend/internal/config/config.go or set via environment:
RATE_LIMIT_PER_SEC=20 RATE_LIMIT_BURST=20 go run .The app supports both PostgreSQL (production) and SQLite (development):
- PostgreSQL (Neon): Automatically used when
DATABASE_URLenvironment variable is set - SQLite: Used for local development when
DATABASE_URLis not set
The database schema includes:
CREATE TABLE content (
id TEXT PRIMARY KEY,
type TEXT NOT NULL, -- 'file' or 'note'
title TEXT,
filename TEXT,
filepath TEXT,
filesize INTEGER, -- BIGINT in PostgreSQL
content TEXT,
created_at DATETIME, -- TIMESTAMP in PostgreSQL
expires_at DATETIME NOT NULL, -- TIMESTAMP in PostgreSQL
view_count INTEGER DEFAULT 0,
deleted_at DATETIME -- TIMESTAMP in PostgreSQL, for soft deletes
);
-- Performance indexes
CREATE INDEX idx_content_expires_at ON content(expires_at);
CREATE INDEX idx_content_deleted_at ON content(deleted_at);
CREATE INDEX idx_content_type ON content(type);
CREATE INDEX idx_content_created_at ON content(created_at DESC);Automatic Migrations: The application automatically creates tables and indexes on startup. Database migrations run in backend/internal/repository/db.go.
Soft Deletes: Content is marked as deleted (not permanently removed) for data retention and audit trails.
- Create free Neon account at neon.tech
- Create a new project (Postgres 17 recommended)
- Copy the connection string
- Set as environment variable:
export DATABASE_URL="postgresql://user:pass@host.neon.tech/dbname?sslmode=require"
- Run your backend - it will automatically use PostgreSQL
Benefits of Neon:
- Free tier with 0.5GB storage
- Auto-scaling and serverless
- Better performance for concurrent requests
- Automatic backups
- Database branching for development
- No vendor lock-in (migrate to any hosting platform)
For local development, simply run without DATABASE_URL:
cd backend
go run .The backend will automatically create and use konbi.db locally.
Delete expired content manually:
SQLite (local):
sqlite3 konbi.db "DELETE FROM content WHERE expires_at < datetime('now')"PostgreSQL (via psql):
psql $DATABASE_URL -c "DELETE FROM content WHERE expires_at < now()"Via Admin API:
# First, view all content
curl -H "X-Admin-Secret: your-secret" \
https://your-backend.onrender.com/api/admin/listSQLite:
sqlite3 konbi.db ".backup konbi_backup.db"PostgreSQL (Neon): Neon provides automatic backups with point-in-time recovery. You can also export manually:
pg_dump $DATABASE_URL > konbi_backup.sqlSQLite:
sqlite3 konbi.db "SELECT id, type, filename, title, created_at, expires_at FROM content"PostgreSQL:
psql $DATABASE_URL -c "SELECT id, type, filename, title, created_at, expires_at FROM content"Backend:
cd backend
go test ./...Frontend:
cd frontend
npm testBackend:
cd backend
CGO_ENABLED=1 go build -o konbiFrontend:
cd frontend
npm run buildIf you encounter CORS errors, update the allowed origins in backend/main.go:
config.AllowOrigins = []string{"https://your-frontend-domain.com"}If SQLite database is locked:
rm konbi.db-shm konbi.db-walChange the port:
PORT=3001 go run . # Backend
PORT=3002 npm start # FrontendThe frontend dependencies are kept up-to-date with security patches. If you see warnings:
cd frontend
npm auditThe project uses npm overrides to patch vulnerable dependencies in react-scripts.
Since the database is on Neon (separate from hosting), migration is simple:
- Deploy backend to Render (see Backend deployment section)
- Set the same
DATABASE_URLenvironment variable - Update frontend's
REACT_APP_API_URLto new backend URL in Vercel - Done! No data migration needed.
If you're currently using SQLite and want to migrate to Neon:
-
Export SQLite data:
sqlite3 konbi.db .dump > export.sql -
Create Neon database and set
DATABASE_URL -
The backend will automatically create tables on startup
-
Import data if needed (manual process for schema differences)
Note: Since content expires after 7 days, starting fresh is often acceptable.
- Admin Endpoints: Protected by
X-Admin-Secretheader authentication - Rate Limiting: 10 requests per second per IP
- File Validation: Whitelisted file extensions only
- Size Limits: 50MB max file size
- CORS: Configured for specific origins in production
- Dependencies: Regularly updated, security vulnerabilities patched
- HTTPS: Enforced in production via Vercel and Render
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use this project for any purpose.
For issues and questions, please open an issue on GitHub.
Built with Go and React
