DEV Community

Neural_Ethos
Neural_Ethos

Posted on

How to Build a Serverless, Zero-Database Web App for 100k+ Users Using Client-Side Image Processing

As software engineers, our default setting is often to over-engineer. When tasked with building a web utility—such as an image sorter or a layout planner—our minds immediately jump to designing a complete backend ecosystem. We start sketching out PostgreSQL schemas, configuring AWS S3 bucket lifecycles for user uploads, setting up Redis caches, and writing authentication middleware.
While this architecture is robust, it introduces massive overhead:
Financial Cost: Database queries and S3 egress fees scale with your user base.
Maintenance Burden: Keeping server packages updated, managing API endpoints, and handling database backups.
Legal Compliance: Storing user-uploaded files means dealing with GDPR, CCPA, and data privacy regulations.
When I started building Rankly, an online Tier List Maker, I challenged myself to eliminate the backend entirely. I wanted to build a high-performance web tool capable of scale, with a server hosting bill of exactly $0/month, while giving users complete privacy.
Here is a technical deep dive into how we built a stateless, zero-database frontend architecture that processes complex image grids entirely client-side.
Traditional tier list tools follow a client-server-client round-trip pattern:
User uploads images -> Sent to server.
Server saves to S3 -> Returns public URLs.
User drags/drops -> State saved to database via JSON payload.
Export -> Server-side headless browser (like Puppeteer) renders the page and takes a screenshot -> Sent back to user.
This pattern is slow and highly resource-intensive. Rankly completely bypasses the server by implementing an entirely local-first rendering pipeline.

[Local File Upload/Drag] 
         │
         ▼ (FileReader API / Object URL)
[Local Memory State (React/State)] ───► [Interactive Grid UI (Tailwind)]
         │
         ▼ (HTML5 Canvas Synthesis)
[Local Client-Side Render] ───► [High-Res PNG Download]
Enter fullscreen mode Exit fullscreen mode

To let users use their own images without uploading them to a remote server, we utilize the HTML5 File API. When a user drags and drops a folder of images into the asset pool, we do not upload them. Instead, we generate a local reference link.
Using URL.createObjectURL(file) is highly performant because it creates a temporary, unique URL string representing the file in the browser's local memory.

// Handling local file dropping without backend storage
const handleImageDrop = (files) => {
  const newAssets = Array.from(files).map((file) => ({
    id: generateUniqueId(),
    src: URL.createObjectURL(file), // Generates a local, temporary browser URL
    name: file.name,
  }));

  // Update state to render previews instantly
  setAssetPool((prev) => [...prev, ...newAssets]);
};
Enter fullscreen mode Exit fullscreen mode

This approach provides instantaneous rendering. The user sees their images in the tool within milliseconds because there is zero network latency.
The core of a Tier List Maker is a multi-row matrix. Each row (S, A, B, C, etc.) is a drop zone, and there is a master asset pool.
We model this state as a key-value object where each key represents a row ID and the value is an array of item objects. To make the dragging experience smooth and accessible on both desktop and mobile, we implemented a custom pointer-event handler.

interface TierItem {
  id: string;
  src?: string; // For images
  text?: string; // For our custom "Text Mode"
}

interface TierBoardState {
  [rowId: string]: TierItem[];
}
Enter fullscreen mode Exit fullscreen mode

By supporting both text strings and image elements within the same state shape, we allowed users to build conceptual lists (ranking books, coding frameworks, or life goals) seamlessly using our integrated Text Mode without requiring heavy image assets.
The most technically challenging part of a backend-less approach is exporting the final grid as a high-quality, shareable image. Many applications rely on server-side APIs running headless Chromium to capture screenshots. This is incredibly expensive to scale.
To solve this, Rankly performs image synthesis directly in the browser using the Canvas API.
When the user clicks "Export," we calculate the absolute bounding box of the tier list element, initiate an off-screen HTML5 element, and draw the grid step-by-step:
Calculate Dimensions: Determine the total width and height based on the number of active rows and the width of the container.
Draw Backgrounds and Borders: Paint the structural layout of the board.
Render Labels: Draw the text labels (S, A, B, C...) using local system fonts.
Draw Images/Text Items: Loop through the state of each row. For images, we instantiate an Image() object, assign the local Object URL as the source, and draw it onto the corresponding coordinates using ctx.drawImage().
Convert to Downloadable Blob: Export the canvas to a data URL and trigger an automatic download.

// High-level conceptual flow for client-side export
const exportToPNG = async (boardState) => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');

  // Set dimensions based on board layout
  canvas.width = calculatedWidth;
  canvas.height = calculatedHeight;

  // Sequential canvas drawing logic...
  await drawGridStructure(ctx, boardState);

  // Trigger local browser download
  const imageURL = canvas.toDataURL('image/png');
  const downloadLink = document.createElement('a');
  downloadLink.href = imageURL;
  downloadLink.download = 'my-tier-list.png';
  downloadLink.click();
};
Enter fullscreen mode Exit fullscreen mode

By moving all computation to the client, we have created a highly scalable architecture:
Infinite Scale, Zero Cost: Since our hosting consists entirely of static HTML, CSS, and JS files, we can serve millions of users using free CDN platforms like Cloudflare or Vercel. Our hosting costs remain virtually zero.
Superior GDPR Compliance: Because we do not transmit, process, or store personal user assets, we are naturally compliant with global privacy laws.
Instantaneous Feedback: Zero network round-trips mean that actions like dragging, adding rows, changing colors, and exporting happen instantly.
If you are interested in exploring how a high-performance, client-side editor behaves under real conditions, check out the live implementation of our Tier List Maker.
Let me know in the comments how you manage local state and client-side rendering in your own serverless projects!

Top comments (1)

Collapse
 
bhavin-allinonetools profile image
Bhavin Sheth

Great approach. I've found that keeping image processing entirely in the browser not only cuts hosting costs but also makes users trust the tool more since their files never leave their device.