I remember my first 'impressive' project: a todo app with color themes and smug confidence. Ten years later I look back and realize those small wins don't prove you can build for real users. In this post I walk through how I took a useful idea — a web background remover — and turned it into a deployed, user-ready app. I’ll keep it practical: if you know basic HTML, CSS, and can write loops and functions in JavaScript or Python, you can follow along.
1) Why beginner projects plateau and what to do next
I started with todo apps and calculators. They build confidence, but they don’t prove you can ship production-ready apps that handle users, errors, and uptime. After 10+ years, including a SaaS that hit ~1,000 users, I learned ops fast.
Spruce Khalifa: "I learned more from production outages than from tutorials."
Employers want real-world projects that solve a real problem. That’s why this FastAPI Tutorial uses the Python FastAPI framework to build a background remover: small, useful, and deployable.
- Build → break → debug → repeat
- Ship user-facing features, not snippets
2) Why I picked a background remover (and why that choice matters)
I picked a background remover app because it’s a real, repeatable tool designers and creators use. As I like to say, immediate value beats cleverness.
Spruce Khalifa: "I chose a tool people actually use—immediate value beats cleverness."
This small project still proves production skills: file upload handling, image processing, and rembg integration (with rembg, pillow, and onnxruntime) without training a model.
- Proven idea = faster feedback and user testing
- Transferable skills + résumé-friendly output
- Live: https://iamspruce.github.io/background-remover/
- Open source: https://github.com/iamspruce/background-remover
Even here, I had to handle CORS, security, and resource tuning.
3) Prerequisites & tooling: what you actually need
Python FastAPI framework + basics
You don’t need perfect mastery. If you know basic HTML/CSS and JavaScript fetch, plus simple Python server ideas, you’re ready. Good engineering is often about effective integration, not reinvention.
- Tools: Python 3.9+, Git, VS Code, a browser, GitHub
- Packages:
pip install rembg pillow onnxruntime - Start small: one backend file, then grow
- Practice file upload handling end-to-end
Run a development server command with Uvicorn, and test the UI locally with VS Code Live Server to catch CORS-like issues early.
Sebastián Ramírez: “FastAPI lets you get a high-performance API running quickly with minimal boilerplate.”
4) Backend with FastAPI: start small, ship fast
I built a tiny REST API FastAPI backend with Uvicorn, starting in one file. I import FastAPI class, create FastAPI instance, then add a path operation decorator like @app.get("/health") to prove the server is alive.
“My rule: prove the backend works with simple endpoints before polishing anything else.” — Spruce Khalifa
Next, @app.post("/remove-bg") handles file upload handling, runs rembg in-memory with pillow and onnxruntime, and returns the PNG. FastAPI’s async support and auto docs help me iterate fast. I validate with curl multipart uploads.
5) Frontend without frameworks: HTML, CSS, JS that works
I built the UI with index.html, styles.css (a 600px max-width for readability), and app.js. I kept it accessible and simple—clarity beats fancy CSS. In app.js, I used JavaScript fetch with async function handlers to send the image as multipart/form-data, then render the returned blob inline and offer a download link. I also added loading text, file size checks, and basic feedback.
Local testing with Live Server reduced surprises, and I used the backend’s interactive API documentation to confirm requests. When I deployed, I only swapped the API URL and finished the CORS configuration setup.
“Solid UX often comes from constraints, not frameworks—keep it tight and functional.”
6) Deployment: Cloud Run backend, GitHub Pages frontend, and CORS
Cloud Run deployment + GitHub Pages hosting
I shipped the backend with Cloud Run deployment in the Google Cloud Console, then bumped limits to 2 GB memory and 4 CPUs so the rembg runtime could keep high performance APIs stable. For the UI, GitHub Pages hosting was perfect for static HTML/CSS/JS (Settings → Pages).
CORS configuration setup
Deployment exposed what local dev hid: CORS and integration gaps. As Spruce Khalifa said:
"I learned the hard way that CORS will stop you cold—set it right and only allow trusted sites."
I fixed it in backend/api/main.py with FastAPI CORSMiddleware, allowing Live Server first, then only my GitHub Pages origin. GitHub → Cloud Run automation kept updates smooth.
7) Post-launch improvements and learning roadmap
After shipping, I improved UX: loading states, clearer errors, and file size limits. Small iterative changes teach more than waiting to be perfect.
- Add progress UI, rate limits, and queued background task processing for spikes.
- Improve monitoring/logging so the Python FastAPI framework stays reliable under load.
- If turning this into a SaaS, add JWT token authentication and billing to protect paid routes.
Spruce Khalifa: "There's no need to wait—build, deploy, and learn from what breaks."
I keep it open-source for faster feedback: production-ready apps grow through community testing.
Live: https://iamspruce.github.io/background-remover/ • Code: https://github.com/iamspruce/background-remover • freeCodeCamp helped me and 40,000+ others.
8) Wild cards: quotes, hypotheticals, and imperfect asides
I keep a line from Sebastián Ramírez close:
“FastAPI is designed to make building APIs fast and enjoyable.”That’s the vibe of this FastAPI Crash Course: ship, learn, repeat.
Hypothetical: what if I built my own background model? Months of work, little extra user value. Machine learning integration is often “build vs reinvent,” and I’d rather build.
Shipping small feels like baking bread: master a simple loaf before croissants. I once deployed a beta with no CORS; users saw failures, and I learned fast. Share early—real-time applications get better when the Internet tells you what to fix. Tiny tangent: toggle max-width in CSS and watch readability change.
