Let me start with some context: I have a graveyard of unfinished side projects. Probably 15+ repos that never saw the light of day. This time I told myself — ship it, no matter how ugly the first version is.
The idea was dead simple. Upload a photo, remove the background, download a transparent PNG. That's it.
I ended up building imagesbackgroundremover.com — and the whole thing runs on Cloudflare's free tier. Zero dollars a month in hosting costs. I've also open-sourced the entire codebase so you can see exactly how it's put together:
turnturn
/
bg-remover-nextjs-cloudflare
Free AI Background Remover built with Next.js 16, Tailwind CSS 4, and Cloudflare Workers. Zero infrastructure cost.
🖼️ BG Remover — AI Background Remover
Remove image backgrounds instantly with AI. Free, fast, and no signup required.
✨ Features
- 🎯 AI Background Removal — Powered by advanced AI that detects subjects and removes backgrounds in seconds
- 📸 Drag & Drop Upload — Supports JPG, PNG, and WebP (up to 10 MB)
- 🔍 Before/After Comparison — Interactive slider to compare original and processed images
- ⬇️ One-Click Download — Download transparent PNG with a single click
- 📱 Fully Responsive — Works flawlessly on mobile, tablet, and desktop
- 🌍 Multi-language — English and Chinese (中文) support
- 🔒 Privacy First — Images are processed in real-time and never stored
- 🔍 SEO Optimized — JSON-LD, Open Graph, Twitter Cards, semantic HTML, blog
🚀 Live Demo
Try it now at imagesbackgroundremover.com
How It Works
- Upload your image (JPG, PNG, or WebP)
- AI processes and removes the background automatically
- Download the transparent PNG…
Here's the honest breakdown of how it went.
The architecture (kept it boring on purpose)
I'm a big believer in boring technology. The fewer moving parts, the fewer things that break at 2am.
The whole system is just a browser talking to Cloudflare Workers on the edge. No origin server, no Docker containers, no Kubernetes, no "microservice mesh." Workers handles routing, auth, and API calls. Data goes to D1 and KV. That's it.
Here's the stack in plain terms:
- Next.js 16 — App Router with Edge Runtime. The latest version, because why not live on the edge (pun intended).
-
TypeScript — I don't write JS without types anymore. Life's too short for
undefined is not a function. - Tailwind CSS 4 — Say what you will, but I can prototype a decent-looking UI in hours instead of days.
-
Cloudflare Workers — The compute layer. Deployed via
opennextjs-cloudflare(see the config). - D1 — Cloudflare's edge SQLite. Stores users, credits, transactions.
- KV — Key-value store for sessions. Think Redis, but free and managed.
- Google OAuth — Login. Hand-rolled, not NextAuth (more on this later).
- PayPal — Payments. Subscriptions and one-time credit packs.
Monthly infrastructure cost: $0. Not "$0 for the first 3 months." Just $0.
Why I left Vercel
I know, I know. "Next.js + Vercel" is like peanut butter and jelly. And honestly, the developer experience on Vercel is excellent.
But here's what happened. I needed a database for users and credits. I needed session storage. On Vercel's free tier, that means bolting on external services — a hosted Postgres, maybe Upstash for Redis. Suddenly my "free" project had $15-20/month in dependencies.
Cloudflare gave me all of that for free:
- D1 — A real SQL database at the edge. Not a toy. Actual SQLite with proper query support.
- KV — Session storage without managing Redis.
- No cold starts — Workers are always warm. Users in Tokyo and users in Berlin get the same fast response.
The catch? You need opennextjs-cloudflare to make Next.js work on Workers. It's an adapter, and it works — but don't expect the Vercel-level polish. Debugging runtime errors on Workers can feel like reading tea leaves sometimes.
For a solo project with zero budget, the math was obvious.
The deploy gotcha that cost me an afternoon
Let me save you some time: pushing to GitHub does NOT trigger a Cloudflare Workers build.
If you've used Cloudflare Pages, you're probably expecting Git-push deploys. Workers doesn't do that. You need two commands:
npx opennextjs-cloudflare build # ~45 seconds
npx wrangler deploy # ~45 seconds
I spent a genuinely embarrassing amount of time refreshing my production URL and wondering why nothing changed. Don't be me.
Also, in your wrangler.toml, do not forget this line:
compatibility_flags = ["nodejs_compat"]
Without it, Node.js APIs that Next.js depends on will fail silently at runtime. Not with a nice error message. Just weird, broken behavior that makes you question your life choices.
The UI: one rule
I gave myself one rule for the interface: if someone can't figure out what this tool does within 5 seconds, I failed.
So the design is deliberately simple. Upload area dead center. Three-step "how it works" below. FAQ at the bottom. No sidebar, no feature tour, no "watch our 2-minute intro video." Just the thing you came here to do.
The before/after slider
This is probably my favorite piece of UI in the whole project. It looks like it needs a fancy library, but it's actually embarrassingly simple:
Click to see the slider code (React + CSS clip-path)
<div className="relative overflow-hidden">
<img src={originalUrl} alt="Original" />
<img
src={processedUrl}
alt="Processed"
style={{ clipPath: `inset(0 ${100 - position}% 0 0)` }}
className="absolute inset-0"
/>
<input
type="range" min={0} max={100}
value={position}
onChange={(e) => setPosition(Number(e.target.value))}
/>
</div>
That's it. CSS clip-path and a native range input. No npm package needed.
i18n for two languages
The site supports English and Chinese. I considered next-intl and react-i18next, then decided they were massive overkill for two languages. Instead I wrote a simple i18n.ts:
export type Locale = "en" | "zh";
export const messages: Record<Locale, Messages> = {
en: {
hero: { title: "Make your images clean, cut-out, and ready to use." },
},
zh: {
hero: { title: "让图片更干净,更利落,更适合直接使用。" },
},
};
Language switching uses ?lang=zh URL params with localStorage persistence. An applySeo() function updates all meta tags dynamically.
Is this the "right" way to do internationalization? No. Does it work perfectly for my use case? Absolutely.
Auth: 200 lines vs. a framework
I hand-rolled Google OAuth instead of reaching for NextAuth. Here's why:
- I only need Google login. NextAuth is built for "sign in with 47 different providers." That's not my problem.
- Edge compatibility. Some NextAuth adapters don't play nice with Workers.
- It's three routes. That's it.
/api/auth/login → redirect to Google consent screen
/api/auth/callback/google → exchange code for tokens, create user in D1
/api/auth/me → look up session in KV, return user
Sessions live in KV with a 7-day TTL. The entire auth system is ~200 lines. Sometimes the best abstraction is no abstraction.
Making money (the honest version)
I went with a credits model because it's the simplest thing that could work:
| Plan | Price | What you get |
|---|---|---|
| Free | $0 | 3 credits on signup |
| Starter | $3.49/mo | 10 credits/month |
| Pro | $8.69/mo | 25 credits/month |
| Credit Pack (5) | $1.73 | Never expire |
| Credit Pack (10) | $3.46 | Never expire |
PayPal handles subscriptions and one-time purchases. The integration was fine until I hit webhook signature verification. PayPal's documentation for verifying webhooks on edge runtimes reads like it was written by someone who has never actually tried to verify a webhook on an edge runtime. I got it working eventually, but it was not fun.
SEO for a domain that Google has never heard of
A brand-new domain has zero authority. Zero. Google doesn't know you exist, and it doesn't care that your code is clean.
Here's what I did:
The basics (one afternoon of work):
- Proper
robots.txtandsitemap.xml - JSON-LD structured data (WebApplication schema)
- Open Graph + Twitter Card tags
- Canonical URLs and
hreflangfor both languages - Title < 70 chars, description < 155 chars
The real work (ongoing):
- Built a
/blogwith three articles targeting long-tail keywords:- "How to Remove Image Background for Free in 2026"
- "Best Background Remover Tools Compared"
- "Transparent PNG for Ecommerce Product Photos"
- Each post has its own SEO metadata, JSON-LD Article schema, canonical URL, and a CTA back to the main tool
Technical SEO is table stakes. Everyone has it. Content and backlinks are what actually move the needle — and that's a game measured in months, not days.
Five things I'd tell past-me
1. Ship the smallest version first. My v1 had no login, no payments, no blog. Just: upload → remove → download. One page, one button. I added everything else after confirming people actually used it.
2. Cloudflare's free tier is a cheat code. D1 + KV + Workers replaces $20-30/month of managed services. For indie devs and side projects, this changes the economics completely.
3. Don't fight the deployment. I wasted time trying to get Git-push deploys working with Workers. Just accept the two-command flow and move on.
4. Resist every feature idea. I almost added batch upload, color backgrounds, AI enhancement filters. Glad I didn't. The product is better because it does one thing well.
5. SEO is a slow burn. The technical foundation matters, but don't expect Google to notice you for weeks. Write content, build links, be patient.
Try it
If you need to remove a background from an image — give it a spin. Free, instant, no signup required, works on mobile.
Try the Background Remover for Free
The full source code is open:
turnturn
/
bg-remover-nextjs-cloudflare
Free AI Background Remover built with Next.js 16, Tailwind CSS 4, and Cloudflare Workers. Zero infrastructure cost.
🖼️ BG Remover — AI Background Remover
Remove image backgrounds instantly with AI. Free, fast, and no signup required.
✨ Features
- 🎯 AI Background Removal — Powered by advanced AI that detects subjects and removes backgrounds in seconds
- 📸 Drag & Drop Upload — Supports JPG, PNG, and WebP (up to 10 MB)
- 🔍 Before/After Comparison — Interactive slider to compare original and processed images
- ⬇️ One-Click Download — Download transparent PNG with a single click
- 📱 Fully Responsive — Works flawlessly on mobile, tablet, and desktop
- 🌍 Multi-language — English and Chinese (中文) support
- 🔒 Privacy First — Images are processed in real-time and never stored
- 🔍 SEO Optimized — JSON-LD, Open Graph, Twitter Cards, semantic HTML, blog
🚀 Live Demo
Try it now at imagesbackgroundremover.com
How It Works
- Upload your image (JPG, PNG, or WebP)
- AI processes and removes the background automatically
- Download the transparent PNG…
Got questions about the edge deployment, the OAuth flow, or anything else? Happy to go deeper in the comments.



Top comments (11)
Great post, thank you. As a side comment, I couldn't agree more with your doubts about PayPal's professionalism. I've been a big fan of this company from day 1, when I first discovered the joys of a PayPal account. But it's been a downhill experience ever since. What is **wrong **with this company's management????
As evidence, I give you the company's number 1 product - the payment window. This is a breeze if you have a Paypal a/c. If not, it requires the IQ of an Einstein. Reason? Some bright marketing type has decided to use the situation as an opportunity to push people towards **creating **a Paypal account. Result? Total confusion. I've had to deal with customers literally in tears over this ghastly apology for a payment interface. And it's been like this for years? The worst of it is I'm a Paypal shareholder. I still believe in them, but can you hear the sound of my teeth grinding?
Man, the guest checkout rant hit home. I've had users email me completely lost trying to pay without creating an account. Years of this and they still won't fix it. As a fellow PayPal integrator... I feel your pain 😅 Thanks for reading!
"I needed a database for users and credits. I needed session storage. On Vercel's free tier, that means bolting on external services — a hosted Postgres, maybe Upstash for Redis. Suddenly my "free" project had $15-20/month in dependencies." -> Vercel + Supabase
Yeah that's exactly the trap. Supabase is solid on its own, but once you're stitching together Vercel + Supabase + maybe Upstash for KV, you're managing three dashboards and three billing pages for a "free" stack. Cloudflare having D1 and KV built in just cuts all that out.
Really cool write-up! I'm hearing lots of good things about Cloudflare as an application platform these days - eager to look at how you did this and to try something myself!
Thanks! Definitely give it a shot. The repo's public if you want to poke around: github.com/turnturn/bg-remover-nextjs-cloudflare.
Yeah I definitely want to check it out - interesting also that you did not target Vercel (the 'standard' choice), but Cloudflare, via OpenNext ...
Hi. Thanks for sharing. What about the dedicated domain name? Is it also free?
Not if you mean a custom domain — you still have to pay for that yourself. But Cloudflare does give you a free *.workers.dev subdomain, so you can get a project online without buying a domain first.
👍️
🙏