Inspiration
I've loved TinyPNG's UX since using it at the web agency I worked at years ago. Drop files, watch them compress, done. Simple.
For some reason I always wanted to build a file converter with that same feel but bulk by default. Most online converters treat batch processing as a premium feature, limiting free users to 5-10 files at a time.
When .FAST gTLD dropped in October I secured Convert.FAST to finally build this project. End result after 3 months is a bulk file converter that handles up to 1,000 files per batch across 140 converters.
What it does
Drop files. Watch real-time progress on each one. Download everything as a single ZIP.
- Images: HEIC, JPG, PNG, WebP, AVIF, GIF, BMP, TIFF, PDF, SVG
- RAW Camera: CR2, CR3, NEF, ARW, DNG, RAF, ORF, RW2
- Documents: PDF, PDF/A, Word, PowerPoint, Excel, EPUB
- Audio: MP3, WAV, FLAC, AAC, OGG, M4A, OPUS
- Video: Extract audio from MP4, MOV, AVI, MKV, WebM
50 free conversions daily, no signup required.
How I built it
I'm usually a React developer, but this project called for either PHP or Razor Pages (my day job has a lot of enterprise C# experience). I went with .NET 10 + Razor Pages for server-side rendering, PostgreSQL for persistence, and libvips for high-performance image processing.
The interesting discovery came when I needed interactive UI without rewriting everything in a SPA framework.
Vue Islands with Zero-Repaint Hydration
I experimented and found that Vue can mount on existing server-rendered HTML as a no-op—the virtual DOM diff calculates to zero changes, so there's no content repaint. The user has no idea Vue just hydrated in 10-40ms.
The pattern:
- Server renders the exact same HTML that Vue would render
- Vue mounts against that container
- Diff = zero changes = no repaint
- Data hydrates via a
data-stateattribute (JSON blob, Zod-validated)
This gives you the benefits of your SSR framework (Razor Pages, PHP, whatever) without writing vanilla JS. You get TypeScript, your favorite libraries, reactive state—all mounting invisibly on top of existing HTML.
I've got a minimal example here: github.com/stewartcelani/razor-pages-with-vue-islands
This isn't tied to Razor Pages—it works anywhere you can render HTML server-side.
Zero-Downtime Deployment
The production architecture runs on dedicated Hetzner server with:
- YARP reverse proxy load balancing to multiple instances (behind NGINIX)
- Blue-green zero-downtime deployments (stop instance 1, deploy, start, then repeat for instance 2) (using Redis and RabbitMQ so user wont even know something went wrong if I deployed an update in the middle of their 1000 file batch)
- Health checks that gate traffic during deploys
Challenges
- Fair scheduling: When multiple users submit large batches simultaneously, the job queue needs weighted round-robin to prevent one user from monopolizing resources
- Real-time progress: SSE (Server-Sent Events) streaming job status to the browser for each file in a batch
- Credit system: Handling both paid users (via API) and anonymous users (local PostgreSQL ledger) with advisory locks for concurrency
What I learned
Learned a lot about message queues and how to do zero-downtime deployments by putting any shared state in Redis, RabbitMQ and Postgres.
Really enjoyed working with pure SSR html in Razor Pages (reminds me of PHP agency days 10 years ago) while still getting to mount a vue app on each page to handle the dynamic real-time converter queue.
What's next
- More converter formats
- API access for developers
- Polish C# SDK (using it internally for tests) and release with API, then do Typescript + PHP + curl for docs. C# SDK already nicely handles parallelism which I learnt from my https://github.com/stewartcelani/autodesk-construction-cloud-backup project
Log in or sign up for Devpost to join the conversation.