Founder Story TypeScript File Upload

Why We Built Uploadista: A Founder's Story

Denis Laboureyras avatar
Denis Laboureyras
CTO & Tech Lead
8 min read
Share:
Abstract illustration of file processing pipelines flowing through cloud infrastructure

Every developer has that one problem they keep running into — the one that follows them from project to project, company to company. For me, it was file uploads.

Not the simple kind. Not “pick a file, POST it to a server, done.” I’m talking about the kind where users upload thousands of images that need resizing, videos that need transcoding, documents that need parsing — all while showing real-time progress on a mobile app with a flaky connection.

After spending the better part of a decade as a CTO building media-heavy applications, I can say with confidence: the state of file processing in the JavaScript ecosystem has been broken for a long time. Uploadista is my attempt to fix it.

The problem I kept solving (and re-solving)

At my first startup, we were building a marketplace where sellers uploaded product photos. Simple enough, right? We started with a basic Express endpoint and Multer. Within weeks, we needed image resizing. Then watermarking. Then format conversion for mobile. Then virus scanning because a user uploaded a malicious PDF.

Each requirement meant bolting on another library, another service, another failure point. Our upload pipeline became a tangled mess of callbacks and queue workers. When something failed halfway through processing, we had orphaned files scattered across S3, half-processed thumbnails, and no way to retry just the step that failed.

So we rewrote it. We always rewrote it.

At the next company, we adopted a popular image CDN. The API was good, the transformations were powerful. But once we scaled past a certain threshold, the bills became unpredictable. Our finance team couldn’t budget for it — bandwidth charges here, transformation credits there, storage fees on top. We were spending more time modeling costs in spreadsheets than building features.

At a third project — a mobile-first social platform — we needed native upload experiences on iOS and Android. Resumable uploads over unreliable connections. Background uploads that survived app switches. Progress tracking that was actually accurate. The existing JavaScript libraries? They were built for the browser. Mobile was an afterthought, if it was a thought at all.

What I tried (and why it wasn’t enough)

I’ve used them all — the popular open-source browser uploaders, the polished UI-first libraries, the newer TypeScript-first managed services, the full-pipeline processing platforms.

The best open-source browser uploaders are genuinely impressive: modular, well-designed, with rich plugin ecosystems for cloud storage integrations. But when I needed to chain processing steps together — resize, then watermark, then convert to WebP, then route to multiple cloud providers — I was back to writing custom orchestration code. Pipeline composition wasn’t what they were designed for.

The UI-focused libraries are a joy to drop in. You get a polished upload experience in minutes. But they stop at the browser boundary. The backend processing, the pipeline orchestration, the multi-cloud routing — that’s all on you.

The newer managed services made framework integration refreshingly simple, and I genuinely admire what the teams behind them have built for developer experience. But they tend to be coupled to their own hosting infrastructure. I needed to bring my own storage — because my clients had data residency requirements in the EU, and “your files live on our servers” wasn’t an option.

The more powerful pipeline processing platforms offer full orchestration and tons of integrations. But pricing models at scale can be hard to predict, and TypeScript support often feels like it was layered on after the fact — thin wrappers over REST APIs, no compile-time validation on pipeline definitions.

Each tool solved a piece of the puzzle, but none of them solved the whole thing.

The moment it clicked

The idea for Uploadista crystallized during a particularly painful sprint. We were building a content platform that needed to:

  1. Accept uploads from web, iOS, and Android
  2. Scan files for malware
  3. Extract metadata
  4. Generate multiple image sizes
  5. Convert videos to HLS for streaming
  6. Store originals in the customer’s S3 bucket (GDPR requirement)
  7. Store processed versions in our CDN
  8. Track the entire pipeline with real-time progress

We had seven different services stitched together with SQS queues and Lambda functions. When step 4 failed, we had to manually figure out which files were stuck, reprocess them, and hope the downstream steps would pick up where they left off. Debugging meant jumping between CloudWatch logs from six different functions.

I remember thinking: why isn’t there a framework where I can define this entire pipeline as a typed, composable flow? Where each step is a pure function that transforms input to output? Where retries, error handling, and progress tracking are built in? Where I can run it locally for development and deploy it to any cloud for production?

That night, I started sketching what would eventually become Uploadista’s flow-based architecture.

What we built (and why it’s different)

Uploadista is built around a core idea: file processing is a pipeline problem, not an upload problem.

The upload itself — getting bytes from a client to a server — is the easy part. The hard part is what happens next. And that “what happens next” should be expressed as a typed, composable, observable flow.

Here’s what that philosophy led to:

Flow-based processing. Instead of writing imperative code that calls service after service, you define a flow — a directed graph of processing steps. Each step has typed inputs and outputs. The framework handles orchestration, retries, and parallelism. If step 3 of 5 fails, only step 3 reruns when you retry. No orphaned files. No manual cleanup.

TypeScript-first, not TypeScript-compatible. The SDK is built with TypeScript from the ground up, using Effect-TS for robust error handling. Your pipeline definitions are fully typed. If you pass an image processor a video file, the compiler catches it. If a step produces a thumbnail and the next step expects a full-resolution image, you know at build time, not at 3 AM in production.

BYOS — Bring Your Own Storage. Your files, your buckets, your rules. Connect your S3, Google Cloud Storage, or Azure Blob Storage. We never store your data. For companies with data residency requirements, this isn’t a feature — it’s a prerequisite.

Native mobile SDKs. Not WebView wrappers. Native iOS, Android, Flutter, and React Native SDKs with resumable uploads, background transfer support, and accurate progress tracking that works over spotty cellular connections. Because in 2026, mobile isn’t a secondary platform — it’s the primary one.

Predictable pricing. One metric: flow executions. No per-node pricing, no bandwidth surprises, no transformation credits. You run a flow, you pay for a flow. Your finance team can actually build a budget.

What’s ahead

Uploadista is available today — you can sign up and deploy your first pipeline right now. The early feedback from our first users has been sharp and invaluable, actively shaping everything from the API surface to the error messages.

The visual flow builder is coming along. It will let you design processing pipelines by dragging and dropping steps on a canvas, with the TypeScript code generated automatically. Think of it as the best of both worlds: visual for prototyping and understanding, code for version control and CI/CD.

We’re also investing heavily in documentation and developer experience. Every error message should tell you what went wrong and how to fix it. Every API should have examples that actually work. TypeScript autocompletion should guide you through the entire SDK without ever opening a docs page.

A note on being open source

The core Uploadista SDK is MIT-licensed and will always be. I believe infrastructure tools should be transparent. You should be able to read the code that handles your files, audit the security model, and contribute improvements. The cloud platform (Uploadista Cloud) is where we build our business — managed infrastructure, the visual builder, team collaboration, monitoring. But the engine underneath is open.

This isn’t altruism. It’s pragmatism. The best developer tools earn trust through transparency. And trust is what makes a developer choose your framework for their next production system.

Try it yourself

If any of this resonates — if you’ve felt the same frustration building file processing at scale — I’d love for you to take Uploadista for a spin. Check out the documentation, browse the SDK on GitHub, or sign up for Uploadista Cloud — no credit card required.

And if you have questions, opinions, or war stories about file uploads, I want to hear them. The best products are built in conversation with the people who use them.

Denis is the founder and CEO of Uploadista. He previously served as CTO at multiple startups building media-heavy applications. You can find him on Twitter/X or GitHub.