Building File Tools That Can't See Your Files

Published on the 13th Jun 2026

Table of Contents

  1. Can't, Not Won't
  2. From Side Project to Platform
  3. An Architecture of Nuxt Layers
  4. Open Where It Counts
  5. A Crate and an npm Package per Layer
  6. Where It Goes from Here

Every file tool on the internet makes you the same offer: give me your file, and I'll give it back changed. Converting an image, compressing a PDF, stripping metadata - the operation takes milliseconds, but your file takes a round trip to somebody else's server first. For a vacation photo, that's a shrug. For a contract, a medical scan, or a photo with GPS coordinates still embedded, it's a real cost, paid for a task your own machine could have done.

re;file labs is my answer to that trade-off: privacy-first file tools that run entirely on your device.

Can't, Not Won't

Most services answer privacy concerns with a policy. "We delete uploads after one hour." "We never look at your data." Those are promises, and promises require trust in whoever operates the server, their logging setup, and every party in between.

re;file labs answers with architecture instead. All processing happens locally in your browser: the Rust code compiled to WebAssembly runs on your CPU, in your browser's sandbox, and the files it touches never leave your computer. There is no upload endpoint to trust, because there is no upload. No accounts either, since there is nothing a server would need to remember about you.

That's the distinction the whole project is built on: a service that won't look at your files still could. A static site with no backend can't. You can verify this the hard way - the network tab during a conversion is refreshingly boring.

WebAssembly is what makes this possible without sacrificing capability. The same image and PDF crates that power native Rust tools compile to wasm and run at near-native speed, so "local" no longer means "worse."

From Side Project to Platform

The idea started with the Wasm Image Converter, a single-purpose tool that converted images client-side with Rust and WebAssembly. It worked, people used it, and the pattern generalized in an obvious way: if conversion runs in the browser, so does resizing, compression, metadata editing, and most things done to PDFs.

Instead of bolting more features onto one page, I rebuilt the concept as a platform. Each file domain became its own module: an image layer, a document layer, with more to come. re;file labs is the roof over all of them.

An Architecture of Nuxt Layers

Technically, each tool domain is a Nuxt layer - a self-contained Nuxt project with its own components, composables, Web Workers, and a Rust crate compiled to WebAssembly. The main site is a thin shell that extends the layers and contributes routing, design, and content:

nuxt.config.ts
export default defineNuxtConfig({
  extends: ['github:refilelabs/image'],
})

That one line pulls the entire image toolset - UI, workers, wasm module - into any Nuxt app. Every layer ships a .playground/ directory, so it also develops and previews standalone, without the site around it.

The same property makes the layers self-hostable. Since a layer is a complete Nuxt project, you can deploy one on your own infrastructure and run the image tools without refilelabs.com being involved at all. For the truly cautious, that closes the last gap: you don't have to trust my hosting either.

The split keeps concerns clean: a layer knows how to convert an image; only the shell knows there's a navbar. It also enables a licensing decision that would otherwise be awkward.

Open Where It Counts

The image layer is open source under MIT, together with the base layer of shared components. The site shell, refilelabs.com itself, is closed source - at least for now.

That split is deliberate. The privacy claim rests entirely on the code that touches your files, and that is exactly the code you can read: the Rust sources, the wasm bindings, the workers that call them. Auditing the closed part would gain you knowledge of my landing page and SEO setup, which you were probably not going to review anyway. Keeping the shell closed mostly deters wholesale clones of the site while the actual engineering stays public - and if that calculus changes, opening it up later is a one-way door I'm happy to keep available.

A Crate and an npm Package per Layer

Each layer's Rust core is also published as standalone packages, so the tooling is usable outside re;file labs entirely. For the image layer that's refilelabs-image on crates.io and @refilelabs/image on npm, with the document layer's packages following the same pattern.

The npm package ships three wasm builds - bundler, node, and web - and picks the right one automatically through the exports field. In a bundler or Node.js there is no init() dance:

ts
import { convertImage } from '@refilelabs/image'

const output = convertImage(input, 'image/png', 'image/webp', onProgress)

The same code path that runs on refilelabs.com is what you get from the registry, which keeps the packages honest: they aren't a demo extracted from the product, they are the product.

Where It Goes from Here

The document layer is next in line for the same treatment - public repository and published packages - and further layers are on the roadmap. The direction stays fixed: the browser is the safest place to handle your files, and re;file labs intends to prove that one wasm module at a time.

← Deploying a Cloud-Based Text Extraction App with One Ansible CommandWasm Image Converter →