(... 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.

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:
- 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
- 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
- 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
.
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
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.