SmokeByte is a backend platform that lets users securely upload files, convert them to different formats through an asynchronous background queue, track conversion status in real-time, and download the results from cloud storage β all via a clean REST API.
It's built to handle image, document, audio, and video conversions reliably, even under load.
| Feature | Details |
|---|---|
| JWT Auth | Access + Refresh token architecture |
| Password Hashing | bcrypt |
| Route Protection | Middleware-guarded endpoints |
| User Isolation | Each user sees only their own resources |
| Hardening | Helmet, CORS, Rate Limiting |
| From | To |
|---|---|
| JPG | PNG, WEBP |
| PNG | JPG, WEBP |
| WEBP | JPG, PNG |
| From | To |
|---|---|
| DOCX, TXT | |
| DOCX | PDF, TXT |
| TXT | PDF, DOCX |
| PPT / PPTX |
Supports cross-format conversion across: MP4, AVI, MOV, WEBM, MP3, WAV, AAC, FLAC, OGG, M4A, WMA
- BullMQ powered job queue backed by Redis
- Background worker processes jobs asynchronously
- Each conversion tracked by a BullMQ Job ID
- Workers are decoupled from the API β scale independently
- Converted files stored in Supabase Object Storage
- Temporary local files auto-cleaned post-upload
- Secure, user-scoped download URLs
- Conversion history per user
- Real-time job status polling
- Secure file download
- Full resource isolation between users
Frontend / API Client
β
βΌ
Express REST API
βββββββ΄βββββββββββββββββββββββ
β Auth β Upload β Jobs β
βββββββ¬βββββββββββββββββββββββ
β
βΌ
BullMQ Queue βββ Redis
β
βΌ
Worker Process
ββββββ¬βββββ¬βββββ
β β β β
βΌ βΌ βΌ βΌ
Sharp FFmpeg LibreOffice
β β β
ββββββ΄βββββ
β
βΌ
Supabase Object Storage
β
βΌ
PostgreSQL
flowchart TD
A[User Uploads File] --> B[Upload Validation]
B --> C[Store Original in Supabase]
C --> D[Create BullMQ Job]
D --> E[Worker Picks Up Job]
E --> F{File Type?}
F -->|Image| G[Sharp]
F -->|Document| H[LibreOffice]
F -->|Audio/Video| I[FFmpeg]
G --> J[Upload Converted File]
H --> J
I --> J
J --> K[Save File Record]
K --> L[Save Conversion Log]
L --> M[Job ID Returned to Client]
M --> N[Client Polls /status/:jobId]
N --> O[Client Downloads Converted File]
src/
βββ config/
β βββ db.js # PostgreSQL connection
β βββ supabase.js # Supabase client
β
βββ controllers/
β βββ authController.js
β βββ conversionController.js
β βββ statusController.js
β βββ historyController.js
β βββ userController.js
β
βββ jobs/
β βββ queue.js # BullMQ queue definition
β βββ worker.js # Background job processor
β
βββ middlewares/
β βββ authMiddleware.js # JWT verification
β βββ uploadMiddleware.js # Multer file handling
β βββ rateLimiter.js
β βββ errorHandler.js
β
βββ models/
β βββ userModel.js
β βββ fileModel.js
β βββ conversionLogs.js
β βββ refreshTokenModel.js
β
βββ routes/
β βββ authRoutes.js
β βββ conversionRoutes.js
β βββ statusRoutes.js
β βββ historyRoutes.js
β βββ userRoutes.js
β
βββ services/
β βββ imageService.js # Sharp logic
β βββ documentService.js # LibreOffice logic
β βββ audiovideoService.js # FFmpeg logic
β βββ storageService.js # Supabase upload/download
β
βββ utils/
β βββ jwtUtils.js
β βββ fileUtils.js
β βββ logger.js
β
βββ app.js
βββ server.js
POST /auth/register # Create new account
POST /auth/login # Login, receive access + refresh tokens
POST /auth/refresh-token # Get new access token using refresh token
POST /auth/logout # Invalidate sessionGET /user/me # Get authenticated user profile
GET /user/history # Get user's conversion historyPOST /convert/image # Convert image files
POST /convert/document # Convert document files
POST /convert/media # Convert audio/video filesAll
/convert/*endpoints return ajobIdfor polling.
GET /status/:jobId # Poll conversion job status
GET /download # Download converted filegit clone <repository-url>
cd SmokeByte
npm installCreate a .env file at the project root:
PORT=3000
DATABASE_URL=
JWT_SECRET=
JWT_REFRESH_SECRET=
REDIS_URL=
SUPABASE_URL=
SUPABASE_KEY=
SUPABASE_SERVICE_ROLE_KEY=
SUPABASE_BUCKET=convert-files
NODE_ENV=production# Start API server
npm run dev
# Start worker (separate terminal)
node src/jobs/worker.jsThe API server and the worker are separate processes. Both need to be running for end-to-end conversions to work.
# Build image
docker build -t smokebyte .
# Run container
docker run -p 3000:3000 smokebyte| Layer | Technology |
|---|---|
| Runtime | Node.js |
| Framework | Express.js |
| Database | PostgreSQL + Sequelize ORM |
| Auth | JWT, Refresh Tokens, bcrypt |
| Queue | BullMQ + Redis (Upstash) |
| Storage | Supabase Object Storage |
| Image Processing | Sharp |
| Media Processing | FFmpeg |
| Document Processing | LibreOffice |
| Infrastructure | Docker, PM2, Cloudflare Tunnel |
- Email verification on signup
- Password reset via email
- Refresh token rotation
- Admin dashboard
- Conversion analytics
- WebSocket-based real-time status updates
- Multi-file batch conversion
Pushpak Pathe
Backend Developer β Node.js Β· Express.js Β· PostgreSQL Β· Redis Β· Docker
Built with β and way too many conversion edge cases.