DEV Community

CarsonJ
CarsonJ

Posted on

I built 109 tools that never touch a server - here is the architecture

I built 109 tools that never touch a server - here is the architecture

Most "tools" sites you have used do this:

  1. You upload a file
  2. It goes to a server
  3. The server processes it
  4. You download the result

Sometimes the server stores it. Sometimes it leaks. Sometimes it disappears with the company.

I wanted something different. Every tool on korelyy.com runs 100% in your browser. Zero backend. Zero upload. Zero tracking.

Here is the actual architecture, the real numbers after 90 days, and what I learned.

What "no server" actually means

For each of the 109 tools:

  • The entire app is a static HTML + CSS + JS file
  • It is served as-is from a CDN (Cloudflare Pages)
  • All file processing happens in your browser via FileReader, canvas, Web Crypto API, or OffscreenCanvas
  • Your file never leaves your device
  • Closing the tab = the data is gone (no cookies, no localStorage, no account)

This is not a marketing claim. It is verifiable:

  1. Open DevTools -> Network tab
  2. Use any tool that requires a file (image converter, JSON formatter, etc.)
  3. Reload. The only network request is for the static HTML/CSS/JS bundle.

No fetch() to a server. No XHR. No upload. The file is read, processed in-memory, and downloaded.

The 4 browser APIs that do 90% of the work

When you remove a backend, you are left with the browser. The browser is more capable than most people think.

1. FileReader and URL.createObjectURL

Read any file the user gives you:

const file = document.querySelector('input[type=file]').files[0];
const url = URL.createObjectURL(file);
const img = new Image();
img.onload = () => {
  // process image
  canvas.toBlob(blob => {
    const downloadUrl = URL.createObjectURL(blob);
    // trigger download
  });
};
img.src = url;
Enter fullscreen mode Exit fullscreen mode

Image conversion, PDF generation, audio trimming - all the same pattern. Read blob, process, create new blob, download.

2. crypto.subtle (Web Crypto API)

Hashing, encryption, signing - all client-side:

const hash = await crypto.subtle.digest('SHA-256', arrayBuffer);
const hex = Array.from(new Uint8Array(hash))
  .map(b => b.toString(16).padStart(2, '0'))
  .join('');
Enter fullscreen mode Exit fullscreen mode

No need for a Node backend. The browser has FIPS-validated crypto built in.

3. canvas and OffscreenCanvas

Image manipulation in 2D context:

  • resize, crop, rotate
  • draw shapes, text, gradients
  • extract pixel data
  • convert formats via canvas.toBlob()

OffscreenCanvas lets you do this in a Web Worker, so the UI does not freeze on large images.

4. Worker and SharedWorker

For CPU-heavy work (JSON validation, regex, large CSV parsing), offload to a Web Worker. The main thread stays responsive.

The hard parts

It is not all easy. Three categories of features are genuinely hard without a server:

1. Anything that needs a shared database

"No server" means no central state. You cannot have user accounts, leaderboards, comments, or shared documents without a backend.

My answer: I do not have those. The trade is intentional. korelyy is not a social product. It is a calculator. Calculators do not need user accounts.

If you want shared state, you need a backend. Be honest about it.

2. Anything that needs to call a third-party API that requires a key

Most LLM APIs, payment APIs, and OAuth flows need a server-held secret.

My answer: do not call them from the client. Either skip the feature or do it via a thin serverless function. (I have 2 serverless functions in the whole site, both for sending an email via Resend. They are 30 lines total.)

3. Anything that requires lots of CPU or RAM

A 4K video transcoded in the browser will lock up the UI for 30 seconds. There is no fix except "use a server."

My answer: korelyy does not do video. Image, audio, text, code, JSON, PDF, CSV - all fine. Video, 3D, ML inference - skip.

The SEO win no one talks about

A static-only site is insanely fast for Google.

  • Lighthouse 100/100/100/100 on every page
  • LCP under 500ms globally
  • TTFB under 100ms (Cloudflare edge)
  • Total page weight under 50KB

Google rewards this. My actual results after 90 days:

  • 165 pages indexed
  • 1,545 monthly impressions
  • 22 monthly clicks
  • 0 backlinks
  • 0 marketing spend

These are not impressive numbers. But the cost per impression is literally $0. And the trend is monotonically up.

The 6-language "trick"

Most indie sites ship English-only because i18n is painful. Mine has 6 (en, zh, es, fr, hi, ar).

The trick: translations live in JSON files, not in the code. A 2,000-line tool component never knows what language it is in. The useTranslations hook from next-intl handles it.

// English file
{ "compressImage": { "title": "Compress image" } }

// Chinese file
{ "compressImage": { "title": "压įžĐå›ūቇ" } }
Enter fullscreen mode Exit fullscreen mode

RTL (Arabic) is one CSS rule: html[dir=rtl] { ... } plus using logical properties (margin-inline-start instead of margin-left) throughout.

Cost: 1 week to set up. Saved: 6x market reach with zero ongoing effort.

What I would do differently

After 90 days, here is what I would change:

  1. Start with SEO from day 1, not day 30. I lost 30 days of indexing time. Set up sitemap, structured data, and submit to GSC before launch.
  2. Ship fewer, better tools. I shipped 109. 20 of them are great. 60 are decent. 29 are mediocre. I would rather have shipped 30 great ones.
  3. Do not add a backend for the sake of it. Every time I was tempted to add a server, I asked "do users actually need this?" 95% of the time, the answer was no.
  4. Write the marketing page before the tool. I built tools nobody searched for. Now I check Google Trends and "People Also Ask" before building anything.

When NOT to do this

The no-backend approach is wrong for:

  • Multiplayer or collaborative products
  • Anything requiring authentication
  • Products with ML inference
  • Products with heavy server-side processing
  • Anything where you need analytics

For me, the trade was right. For your product, it might be wrong. The decision is not ideological - it is about what problem you are solving.

Try it

If you want to see the architecture in action:

All 109 at korelyy.com/en.

The whole site is open source. The architecture is not magic. It is just a willingness to say "no" to features that need a backend.

Sometimes the simplest constraint is the best one.

Top comments (0)