







I built SubZI to bring the main steps of subtitle creation into one workflow: upload a video, generate subtitles, edit.
SubZI is a web-based video subtitling tool that turns spoken audio into editable subtitles and exports videos with captions embedded directly into the footage.
I built SubZI to bring the main steps of subtitle creation into one workflow: upload a video, generate subtitles, edit the transcript, review timing, customize the appearance, and export the final result.
A typical video passes through the following stages:
| Component | Technologies | Purpose |
|---|---|---|
| Frontend | React, TypeScript, Vite, React Router | Browser UI and build tooling |
| Styling and UI | Tailwind CSS, Radix UI | Responsive styling and reusable controls |
| Client state | Zustand | Shared in-browser editor and upload state |
| Backend | Node.js, Express, TypeScript | REST API and job orchestration |
| Database | MongoDB, Mongoose (optional) | Persistent job and glossary records |
| Background jobs | BullMQ, Redis (optional) | Queued subtitle-generation jobs |
| Transcription | Google Gemini, Groq Whisper, local OpenAI Whisper | Speech recognition and provider fallback |
| Media processing | FFmpeg | Audio extraction and MP4 subtitle rendering |
| Translation | Provider-specific translation plus deep-translator for local Whisper |
Translation support where configured |
| Deployment | Vercel, Render, Docker | Frontend hosting and backend container deployment |
The application lives inside vid-sub-engine/, with separate frontend and backend directories.
SubZI/
├── README.md
├── render.yaml
└── vid-sub-engine/
├── frontend/
│ ├── client/
│ │ ├── components/
│ │ ├── pages/
│ │ └── lib/
│ ├── shared/
│ ├── .env.example
│ └── package.json
│
└── backend/
├── src/
│ ├── app.ts
│ ├── config/
│ ├── controllers/
│ ├── routes/
│ ├── services/
│ ├── workers/
│ ├── queue/
│ └── utils/
├── tests/
├── Dockerfile
├── requirements.txt
└── package.json
Note: This is a high-level view of the main directories, not an exhaustive listing of every file.
app.ts: Initializes Express, configures middleware and routes, connects services, and starts the server.routes/: Defines API endpoints.controllers/: Handles HTTP requests, validates inputs, and coordinates application logic.services/: Contains transcription and media-processing logic.workers/ and queue/: Manage background job execution and queue integration.utils/: Handles job persistence, subtitle formatting, configuration, and supporting utilities. The Mongoose job schema is in utils/subtitleJobModel.ts.tests/: Contains automated tests for selected backend behavior.Install Node.js, Python, and FFmpeg. Docker is useful for running local services. Configure MongoDB and Redis, or use the application's supported fallback modes where appropriate.
git clone https://github.com/ashh106/SubZI.git
cd SubZI
cd vid-sub-engine/backend
npm install
Create a local environment file using .env.example as a reference. Configure the database connection, Redis connection, API keys, and other required settings. Never commit real credentials.
Install the Python dependencies required by the selected local transcription pipeline and ensure FFmpeg is available in the environment.
Build and run the backend:
npm run build
npm start
Use npm run dev if you want to run the development server.
In a separate terminal:
cd vid-sub-engine/frontend
npm install
Set VITE_API_URL in the frontend's local environment file to your backend URL. For local development, this is typically http://localhost:5000.
Start the frontend:
npm run dev
Open the local URL printed by Vite in your terminal.
From the backend directory:
npm test
Build the backend before deployment:
npm run build
SubZI uses separate deployments for the frontend and backend.
VITE_API_URL to the deployed backend URL before building the production frontend./health, which reports application status and which transcription providers are configured.Configure secrets in the hosting provider's environment settings rather than committing them to Git.
| Variable | Purpose |
|---|---|
MONGO_URI |
MongoDB connection string |
REDIS_URL |
Optional Redis connection URL for BullMQ |
GEMINI_API_KEY |
Optional Gemini API authentication |
GROQ_API_KEY |
Optional Groq API authentication |
VITE_API_URL |
Backend URL used by the frontend build |
CORS_ORIGIN |
Backend CORS configuration |
MAX_FILE_SIZE_MB |
Upload size limit |
UPLOADS_DIR |
Directory used for uploaded and generated files |
Refer to the environment examples and backend configuration for the complete list of supported settings.
The backend includes automated tests for selected request-validation behavior. Additional integration and end-to-end tests would improve coverage of the complete video-processing pipeline.
Useful manual checks include:
/health before testing the frontend.GET /api/upload/:fileId/status.POST /api/upload/:fileId/burn and retrieve the result through GET /api/upload/:fileId/burned.Aashutosh Bharti
GitHub: @ashh106
SubZI is a personal full-stack project focused on AI-assisted transcription, asynchronous processing, and browser-based video editing.
No updates yet.
Building a dev tool or hiring developers? Get seen here. Become our Sponsor
Building a dev tool or hiring developers? Get seen here. Become our Sponsor