We Built Ditherly: An All-In-One Dithering Studio

October 27, 2025

(... because the internet asked for it).

A few weeks ago, “the dithering effect” exploded across Twitter/X. Gorgeous, moody, lo-fi visuals everywhere, but surprisingly, no single tool let you:

  • Upload images or short videos
  • Apply multiple dithering styles with real-time controls
  • Generate new images or videos with AI
  • And export cleanly.

So we built Ditherly: A fast, browser-first dithering studio with an AI pipeline behind it.

Image uploaded by robert

An artist using a monitor as a canvas

Why Ditherly?

  • Momentum: The trend was hot; creators wanted to experiment fast.
  • Coverage gap: Existing tools did one piece (e.g., only images, only one dithering algorithm, or no batch/video support).
  • Performance: Client-side rendering for previews and exports is just snappier, with no upload wait loop.
  • Ownership: We wanted a system that could scale from solo creators to teams, with a clear credit model and modern dev-ops.

High-Level Architecture

Ditherly is split into three clear lanes:

  1. Frontend (Angular app)
    • Real-time dithering in the browser (WebCanvas/WebGL)
    • Supports images/videos
    • Supports three dithering modes with live controls [Ordered (Bayer), ASCII, and Halftone/Dots]
    • Exports as either a PNG or WebM video
    • Auth UI and Credit UX allow for AI image generation
  2. Optional API (C#/.NET 9 on Cloud Run)
    • Publishes a job to Google Pub/Sub for async processing
    • Enforces atomic credit spend (with safe, automatic refunds on failure)
    • Simple job-polling endpoint for client-side updates
  3. Optional Image Worker (Python FastAPI on Cloud Run)
    • Subscribes to Pub/Sub (push)
    • Calls the image model(s) (right now, just Gemini Flash Image/nano-banana)
    • Uploads output to Google Cloud Storage and returns a public URL
    • Issues idempotent refunds if anything fails

Image uploaded by robert.

An AI head with cords coming out of it

Data & Auth

We used Supabase for Auth + PostgREST + SQL. A simple profiles table tracks each user's credit balance and an even simpler jobs table tracks users' queued or processed jobs.

Hosting

Everything runs serverlessly on Google Cloud Run:

  • The (static) frontend is hosted in a bucket
  • The backend and worker are hosted as Cloud Run instances
  • Pub/Sub is used for the job queue
  • GCS stores generated media

The Core Features that Matter

Real-time dithering

We chose to apply the dither effect on the client:

  • Speed: No round-trip for tuning sliders
  • Privacy: Your assets don't leave the browser
  • Quality: We can tweak shaders/kernels tightly and preview instantly

Image uploaded by robert

An AI head with cords coming out of it

Modes

  • Ordered (Bayer): Stable, crisp matrices—great for logos, icons, product silhouettes
  • ASCII: Character-based rendering with adjustable charsets, sizes, and background opacity
  • Halftone/Dots: Classic print-style vibe; grid size + pixel radius give tons of texture control

Controls:

  • Grid/scale: threshold, pixel size, primary/secondary colors, ASCII charset + char size, background opacity
  • Color picker: allows the user to select a palette of up-to 4 colors

Try it out!

This architecture is intentionally boring in the best way:

  • Angular for speed on the front
  • .NET for a tiny, reliable API
  • Python for model calls and image plumbing
  • Supabase for auth + SQL
  • GCP for serverless scale

Check it out at https://ditherly.app and let us know what you think!

We built this in just two days. Have a project with a tight timeline? Contact us - We'd love to help.