A full-stack web application that transforms spreadsheet data into professional, print-ready barcode labels in seconds. Built for inventory management, warehousing, and any business that needs to generate barcode labels at scale.
Label Genius automates the tedious process of creating barcode labels from inventory data. Upload a CSV or Excel file containing your product information, and the system generates professionally formatted Code 128 barcode labels arranged on standard label sheets, ready for printing.
- β‘ Lightning Fast Processing - Generate thousands of labels in seconds with multi-threaded barcode generation
- π Flexible Input - Supports CSV, Excel (.xlsx, .xls) files up to 50MB
- π¨ Professional Output - Code 128 barcodes formatted for 4x5 label sheets (20 labels per sheet)
- βοΈ Cloud Storage - Generated labels stored securely in Supabase with persistent access
- π Resumable Uploads - TUS protocol implementation for reliable large file uploads with automatic retry
- π¦ ZIP Download - All label sheets packaged and ready for batch printing
- π Secure Authentication - Session-based auth with Supabase integration
- π± Responsive Design - Works seamlessly on desktop, tablet, and mobile
- β±οΈ Real-time Progress - Visual feedback during processing and uploads
src/
βββ components/
β βββ LandingPage.tsx # Marketing landing page with features
β βββ login.tsx # User authentication
β βββ signup.tsx # New user registration
β βββ dashboard.tsx # Main app interface
β βββ labelUploader.tsx # File upload & sheet management
β βββ ProtectedRoute.tsx # Route authentication guard
β βββ header.tsx # Navigation component
βββ config/
βββ config.ts # Supabase client configuration
Tech Stack:
- React 18 with TypeScript
- Vite for build tooling
- Tailwind CSS for styling
- Axios for HTTP requests
- React Router for navigation
backend/
βββ auth/
β βββ auth.py # Login/logout endpoints
β βββ decorators.py # Session auth middleware
βββ routes/
β βββ uploads.py # File upload handling
β βββ sheets.py # Sheet download/management
β βββ api.py # Database operations
βββ services/
β βββ label_service.py # Core label processing logic
β βββ sheet_service.py # Sheet retrieval & ZIP creation
β βββ storage_service.py # Supabase storage integration
βββ utils/
β βββ BarcodeGenerator.py # Barcode image generation
β βββ LabelSheetGenerator.py # Sheet layout & composition
β βββ file_utils.py # File validation utilities
β βββ security.py # Security & rate limiting
βββ models/
βββ database.py # Supabase client setup
βββ settings.py # Configuration management
Tech Stack:
- Flask 3.0
- Supabase (PostgreSQL + Storage)
- PIL/Pillow for image processing
- python-barcode for Code 128 generation
- pandas for data parsing
- tuspy (TUS client) for resumable uploads
- concurrent.futures for parallel processing
- Node.js 18+ and npm
- Python 3.10+
- Supabase account
- Git
- Clone the repository
git clone https://github.com/yourusername/label-genius.git
cd label-genius- Backend Setup
cd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Create .env file
cat > .env << EOF
SUPABASE_URL=your_supabase_project_url
SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_KEY=your_supabase_service_key
FLASK_SECRET_KEY=your_secure_secret_key
FLASK_ENV=development
EOF
# Create required folders
mkdir -p uploads images sheets
# Run the Flask server
python app.py- Frontend Setup
cd frontend
# Install dependencies
npm install
# Create .env file
echo "VITE_API_URL=http://localhost:5000" > .env
# Run development server
npm run dev- Database Setup
Create the following tables in your Supabase project:
-- Users table (handled by Supabase Auth)
-- User sheets metadata
CREATE TABLE user_sheets (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
original_filename TEXT NOT NULL,
label_count INTEGER NOT NULL,
sheet_count INTEGER NOT NULL,
total_size_bytes BIGINT DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Individual sheet files
CREATE TABLE sheet_files (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_sheet_id UUID NOT NULL REFERENCES user_sheets(id) ON DELETE CASCADE,
filename TEXT NOT NULL,
storage_path TEXT NOT NULL,
file_size_bytes BIGINT NOT NULL,
sheet_number INTEGER NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create indexes
CREATE INDEX idx_user_sheets_user_id ON user_sheets(user_id);
CREATE INDEX idx_sheet_files_user_sheet_id ON sheet_files(user_sheet_id);Create a storage bucket in Supabase:
- Bucket name:
label-sheets - Public: No (private)
- Access the application
- Frontend: http://localhost:5173
- Backend: http://localhost:5000
-
Sign Up / Login
- Create an account or log in with existing credentials
- Session-based authentication keeps you logged in
-
Prepare Your Data
Your CSV/Excel file should have this format:
Location,Part Number,Description,Unit A-01-01,SKU12345,Widget Assembly,EA A-01-02,SKU12346,Gadget Component,PCS B-02-01,SKU12347,Tool Kit,SET
- Column 1 (Location): Warehouse location or identifier
- Column 2 (Part Number): Product SKU (becomes barcode)
- Column 3 (Description): Product description (optional)
- Column 4 (Unit): Unit of measure (displayed on label)
-
Upload & Generate
- Drag and drop or browse to select your file
- Click "Generate Label Sheets"
- Watch real-time progress as labels are created
- Processing time: ~2-5 seconds per 100 labels
-
Download & Print
- Download the ZIP file containing all label sheets
- Extract and print on 4x5 label paper
- Each sheet contains 20 labels (4 columns Γ 5 rows)
- Session Management: Previously generated sheets are saved and accessible from your dashboard
- Download Tracking: Visual indicators show which sheets you've already downloaded
- Bulk Delete: Remove old label sheets when no longer needed
- Progress Indicators: Real-time feedback during file processing
Backend (.env)
# Supabase Configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJhb...
SUPABASE_SERVICE_KEY=eyJhb...
# Flask Configuration
FLASK_SECRET_KEY=your-256-bit-secret-key
FLASK_ENV=development # or 'production'
# Optional: Redis for rate limiting
REDIS_URL=redis://localhost:6379Frontend (.env)
VITE_API_URL=http://localhost:5000 # Backend URLDefault label dimensions (configurable in label_service.py):
- Label size: 2.5" Γ 2.0" (width Γ height)
- Sheet layout: 4 columns Γ 5 rows
- DPI: 600 (high quality)
- Barcode type: Code 128
- Output format: PNG images
To customize, modify these constants in BarcodeGenerator.py and LabelSheetGenerator.py:
# BarcodeGenerator.py
width_inches = 2.5
height_inches = 2.0
dpi = 600
# LabelSheetGenerator.py
label_width = 220
label_height = 180
x_gap = 35
y_gap = 85
rows = 5
columns = 4- File Validation: Magic byte checking, MIME type validation, extension verification
- Rate Limiting: 5 uploads per hour, 15 per day per user
- Session Security: HTTP-only cookies, CSRF protection, secure session tokens
- Input Sanitization: SQL injection prevention, XSS protection
- File Size Limits: 50MB max (25MB in production)
- Authentication: Protected routes, token-based session management
- Multi-threaded Processing: Concurrent barcode generation (6 workers by default)
- Thread-safe Operations: File locking for shared resources
- Parallel Uploads: Concurrent Supabase storage uploads
- Optimized ZIP Creation: Single ZIP file instead of individual files
- Async Cleanup: Background image deletion
One of the standout features is the implementation of the TUS protocol for resumable uploads to Supabase storage. This provides several critical advantages:
Why TUS?
- Fault Tolerance: Uploads automatically resume from where they left off if interrupted
- Network Resilience: Handles unstable connections gracefully without data loss
- Large File Support: Reliable handling of multi-megabyte ZIP files
- Chunked Transfer: 6MB chunks for optimal upload performance
- No Re-uploads: Users never have to restart failed uploads from scratch
Implementation Details:
# storage_service.py
def upload_zip_to_storage(user_id, user_sheet_id, zip_buffer, original_filename):
tus_client = create_tus_client()
# TUS uploader with chunking
uploader = tus_client.uploader(
file_stream=zip_buffer,
chunk_size=6*1024*1024, # 6MB chunks
metadata={
'bucketName': 'label-sheets',
'objectName': storage_path,
'contentType': 'application/zip'
}
)
uploader.upload() # Automatically resumes on failureThis is particularly valuable for:
- Users with slower internet connections
- Large label sheet batches (1000+ labels)
- Mobile users with intermittent connectivity
- Production environments where reliability is critical
- Lazy Loading: Code splitting with React.lazy()
- State Persistence: LocalStorage for download tracking
- Optimistic UI: Immediate feedback before backend confirmation
- Efficient Re-renders: React.memo and useCallback optimizations
- 100 labels: ~3-5 seconds
- 500 labels: ~10-15 seconds
- 1,000 labels: ~20-30 seconds
- 5,000 labels: ~2-3 minutes
# Backend tests
cd backend
python -m pytest tests/
# Frontend tests
cd frontend
npm run test- Set environment variables in your hosting platform
- Configure production CORS origins in
settings.py - Update
SESSION_COOKIE_SECURE = Truefor HTTPS - Use production Supabase credentials
- Deploy with Dockerfile or buildpack
Example Railway deployment:
railway login
railway init
railway up- Build the production bundle:
npm run build- Set environment variable:
VITE_API_URL=https://your-backend-url.com
- Deploy:
# Vercel
vercel --prod
# Netlify
netlify deploy --prod| Layer | Technology |
|---|---|
| Frontend Framework | React 18 + TypeScript |
| Build Tool | Vite 5 |
| Styling | Tailwind CSS 3 |
| HTTP Client | Axios |
| Backend Framework | Flask 3.0 |
| Database | PostgreSQL (Supabase) |
| Storage | Supabase Storage |
| Upload Protocol | TUS (tuspy client) |
| Image Processing | Pillow 10.0 |
| Barcode Generation | python-barcode 0.15 |
| Data Processing | pandas 2.0 |
| Authentication | Supabase Auth + Sessions |
βββββββββββββββββββ
β auth.users β (Supabase managed)
ββββββββββ¬βββββββββ
β
β user_id (FK)
βΌ
βββββββββββββββββββ
β user_sheets β
βββββββββββββββββββ€
β id (PK) β
β user_id β
β original_filenameβ
β label_count β
β sheet_count β
β total_size_bytesβ
β created_at β
ββββββββββ¬βββββββββ
β
β user_sheet_id (FK)
βΌ
βββββββββββββββββββ
β sheet_files β
βββββββββββββββββββ€
β id (PK) β
β user_sheet_id β
β filename β
β storage_path β
β file_size_bytes β
β sheet_number β
β created_at β
βββββββββββββββββββ
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- python-barcode for Code 128 generation
- tuspy for TUS resumable upload protocol
- Supabase for backend infrastructure
- Tailwind CSS for styling utilities
- Vite for blazing fast development
For issues, questions, or suggestions:
- Open an issue on GitHub
- Contact via your preferred method
Made with β€οΈ for businesses that need efficient label generation