Python SDK for local and cloud background removal (pip install withoutbg)
See the code
Remove backgrounds in Python. Free locally. One line to switch to the Cloud API.
Same API for both paths: run open weights on your machine (private, offline, unlimited) or call the Cloud API (sharper edges on hair and fur, no local GPU). Built for scripts, notebooks, backends, and batch jobs.

Open Weights results → · Cloud API results → · Compare →
from withoutbg import WithoutBG
model = WithoutBG.open_weights()
model.remove_background("photo.jpg").save("result.png")
Returns a PIL Image in RGBA. Prefer PNG or WebP; JPEG drops transparency silently.
uv add withoutbg
Don't have uv yet? It's a fast Python package manager from Astral. Install it once, then the command above.
Local (Open Weights: free, private, offline):
from withoutbg import WithoutBG
model = WithoutBG.open_weights()
result = model.remove_background("input.jpg")
result.save("output.png")
First local run downloads ~1.5 GB of weights from Hugging Face (once; the BiRefNet branch is fetched the first time an image needs it). After that, everything stays on your machine.
Cloud (withoutBG API: best quality):
from withoutbg import WithoutBG
# Pass api_key here, or set WITHOUTBG_API_KEY in the environment
model = WithoutBG.api(api_key="sk_your_key")
result = model.remove_background("input.jpg")
result.save("output.png")
Batch (load once, process many):
from withoutbg import WithoutBG
model = WithoutBG.open_weights() # keep this object alive
images = ["photo1.jpg", "photo2.jpg", "photo3.jpg"]
results = model.remove_background_batch(images, output_dir="results/")
Recreating the model for every image reloads the weights each time. Don't do that in a loop.
Progress callback:
def on_progress(value: float) -> None:
print(f"{value * 100:.0f}%")
result = model.remove_background("photo.jpg", progress_callback=on_progress)
Runnable scripts live in examples/.
Local (open_weights()) | Cloud (api()) | |
|---|---|---|
| Cost | Free forever | Pay per image |
| Quality | Good | Better (esp. hair, fur) |
| Privacy | Stays on your machine | Image sent to API |
| GPU required | No (CPU ONNX) | No |
| First-run setup | ~1.5 GB download, once | API key only |
| Best for | Offline, private, batch jobs | Products, occasional use |
Need offline or private processing? → Local
Processing a large batch? → Local (pay setup once, amortize across images)
Building a product? → Cloud (better quality, zero infra)
Occasional use, no setup tolerance? → Cloud
# Single image (local model)
withoutbg photo.jpg
withoutbg photo.jpg --output result.png
# Cloud API
export WITHOUTBG_API_KEY=sk_your_key
withoutbg photo.jpg --use-api
# JPEG with white background fill
withoutbg portrait.jpg --format jpg --quality 95
withoutbg --help
All methods return a PIL Image in RGBA mode:
result = model.remove_background("photo.jpg")
result.save("output.png") # keeps transparency
result.save("output.webp") # keeps transparency
result.save("output.jpg") # transparency dropped silently
Compositing example:
from PIL import Image
from withoutbg import WithoutBG
model = WithoutBG.open_weights()
fg = model.remove_background("subject.jpg")
bg = Image.open("background.jpg")
bg.paste(fg, (0, 0), fg) # alpha used as mask
bg.save("composite.png")
| Environment variable | Effect |
|---|---|
WITHOUTBG_API_KEY | API key for Cloud mode (alternative to api_key=) |
WITHOUTBG_MODEL_PATH | Path to a local .onnx file (skips Hugging Face download) |
When using WITHOUTBG_MODEL_PATH, keep the sidecar metadata file (withoutbg-open-weights.onnx.json) next to the ONNX file.
from withoutbg import WithoutBG, APIError, WithoutBGError
try:
model = WithoutBG.api()
result = model.remove_background("photo.jpg")
result.save("output.png")
except APIError as e:
print(f"API error: {e}")
except WithoutBGError as e:
print(f"Processing error: {e}")
Model download fails: Weights come from Hugging Face on first local run (~1.5 GB). Check your connection, or set WITHOUTBG_MODEL_PATH to a local copy.
Import error:
which python
uv pip list | grep withoutbg
uv add withoutbg
API key rejected: Get a key at withoutbg.com. Set export WITHOUTBG_API_KEY=sk_your_key.
Migrating from older names (WithoutBG.opensource(), ProAPI): see docs/MIGRATION.md.
This package is the in-process path: embed withoutBG in your Python code or CLI. Same open-weights technology powers the rest of the ecosystem; pick the surface that matches your workflow:
| Surface | Choose when |
|---|---|
| Docker / self-host | You want an HTTP API or browser UI on your own server (CPU or NVIDIA GPU) |
| Mac app | You want a native desktop cutout tool, with an optional Local API for plugins and scripts |
| GIMP plugin | You edit in GIMP 3 and want a private, mask-first workflow via Mac Local API or Docker |
| Hugging Face · Space | You want to try a demo or download the ONNX weights directly |
| Cloud API | You need maximum quality without running inference yourself |
# Self-host the open-weights web app (CPU)
docker run --rm -p 8080:8080 withoutbg/withoutbg-openweights-v3-app-cpu
The withoutBG Open Weights Model is an ONNX bundle hosted at withoutbg/withoutbg-openweights-onnx (version 10.8.0; the SDK pins the Hub revision). Built with DINOv3.
A trained router looks at each image and picks a branch:
Only the selected branch runs, and its alpha is upsampled to the image's native resolution (up to 4096 px per side). To run offline, download the whole bundle and set WITHOUTBG_MODEL_PATH to withoutbg-open-weights.onnx inside it; the other graphs are read from the same folder.
Licensed under the withoutBG Open Model License (Apache 2.0 for withoutBG portions; Meta DINOv3 License for DINOv3 backbone weights; MIT for BiRefNet). See the model's LICENSE.
uv sync --extra dev
make test-fast # fast unit tests
make quality # lint + format + type check
make test # full suite (downloads model on first run)
See CONTRIBUTING.md for the full guide.
This Python SDK is licensed under Apache License 2.0. See LICENSE.
The withoutBG Open Weights Model is a composite artifact with additional terms for embedded DINOv3 weights. See the withoutBG Open Model License, LICENSE-DINOv3, and NOTICE.
See THIRD_PARTY_LICENSES.md for complete attribution.
4,693 followers · starred Jun 2026
1,103 followers · starred Jan 2026
76 followers · starred Jan 2026
615 followers · starred Apr 2026
Python SDK for local and cloud background removal (pip install withoutbg)
See the code
Remove backgrounds in Python. Free locally. One line to switch to the Cloud API.
Same API for both paths: run open weights on your machine (private, offline, unlimited) or call the Cloud API (sharper edges on hair and fur, no local GPU). Built for scripts, notebooks, backends, and batch jobs.

Open Weights results → · Cloud API results → · Compare →
from withoutbg import WithoutBG
model = WithoutBG.open_weights()
model.remove_background("photo.jpg").save("result.png")
Returns a PIL Image in RGBA. Prefer PNG or WebP; JPEG drops transparency silently.
uv add withoutbg
Don't have uv yet? It's a fast Python package manager from Astral. Install it once, then the command above.
Local (Open Weights: free, private, offline):
from withoutbg import WithoutBG
model = WithoutBG.open_weights()
result = model.remove_background("input.jpg")
result.save("output.png")
First local run downloads ~1.5 GB of weights from Hugging Face (once; the BiRefNet branch is fetched the first time an image needs it). After that, everything stays on your machine.
Cloud (withoutBG API: best quality):
from withoutbg import WithoutBG
# Pass api_key here, or set WITHOUTBG_API_KEY in the environment
model = WithoutBG.api(api_key="sk_your_key")
result = model.remove_background("input.jpg")
result.save("output.png")
Batch (load once, process many):
from withoutbg import WithoutBG
model = WithoutBG.open_weights() # keep this object alive
images = ["photo1.jpg", "photo2.jpg", "photo3.jpg"]
results = model.remove_background_batch(images, output_dir="results/")
Recreating the model for every image reloads the weights each time. Don't do that in a loop.
Progress callback:
def on_progress(value: float) -> None:
print(f"{value * 100:.0f}%")
result = model.remove_background("photo.jpg", progress_callback=on_progress)
Runnable scripts live in examples/.
Local (open_weights()) | Cloud (api()) | |
|---|---|---|
| Cost | Free forever | Pay per image |
| Quality | Good | Better (esp. hair, fur) |
| Privacy | Stays on your machine | Image sent to API |
| GPU required | No (CPU ONNX) | No |
| First-run setup | ~1.5 GB download, once | API key only |
| Best for | Offline, private, batch jobs | Products, occasional use |
Need offline or private processing? → Local
Processing a large batch? → Local (pay setup once, amortize across images)
Building a product? → Cloud (better quality, zero infra)
Occasional use, no setup tolerance? → Cloud
# Single image (local model)
withoutbg photo.jpg
withoutbg photo.jpg --output result.png
# Cloud API
export WITHOUTBG_API_KEY=sk_your_key
withoutbg photo.jpg --use-api
# JPEG with white background fill
withoutbg portrait.jpg --format jpg --quality 95
withoutbg --help
All methods return a PIL Image in RGBA mode:
result = model.remove_background("photo.jpg")
result.save("output.png") # keeps transparency
result.save("output.webp") # keeps transparency
result.save("output.jpg") # transparency dropped silently
Compositing example:
from PIL import Image
from withoutbg import WithoutBG
model = WithoutBG.open_weights()
fg = model.remove_background("subject.jpg")
bg = Image.open("background.jpg")
bg.paste(fg, (0, 0), fg) # alpha used as mask
bg.save("composite.png")
| Environment variable | Effect |
|---|---|
WITHOUTBG_API_KEY | API key for Cloud mode (alternative to api_key=) |
WITHOUTBG_MODEL_PATH | Path to a local .onnx file (skips Hugging Face download) |
When using WITHOUTBG_MODEL_PATH, keep the sidecar metadata file (withoutbg-open-weights.onnx.json) next to the ONNX file.
from withoutbg import WithoutBG, APIError, WithoutBGError
try:
model = WithoutBG.api()
result = model.remove_background("photo.jpg")
result.save("output.png")
except APIError as e:
print(f"API error: {e}")
except WithoutBGError as e:
print(f"Processing error: {e}")
Model download fails: Weights come from Hugging Face on first local run (~1.5 GB). Check your connection, or set WITHOUTBG_MODEL_PATH to a local copy.
Import error:
which python
uv pip list | grep withoutbg
uv add withoutbg
API key rejected: Get a key at withoutbg.com. Set export WITHOUTBG_API_KEY=sk_your_key.
Migrating from older names (WithoutBG.opensource(), ProAPI): see docs/MIGRATION.md.
This package is the in-process path: embed withoutBG in your Python code or CLI. Same open-weights technology powers the rest of the ecosystem; pick the surface that matches your workflow:
| Surface | Choose when |
|---|---|
| Docker / self-host | You want an HTTP API or browser UI on your own server (CPU or NVIDIA GPU) |
| Mac app | You want a native desktop cutout tool, with an optional Local API for plugins and scripts |
| GIMP plugin | You edit in GIMP 3 and want a private, mask-first workflow via Mac Local API or Docker |
| Hugging Face · Space | You want to try a demo or download the ONNX weights directly |
| Cloud API | You need maximum quality without running inference yourself |
# Self-host the open-weights web app (CPU)
docker run --rm -p 8080:8080 withoutbg/withoutbg-openweights-v3-app-cpu
The withoutBG Open Weights Model is an ONNX bundle hosted at withoutbg/withoutbg-openweights-onnx (version 10.8.0; the SDK pins the Hub revision). Built with DINOv3.
A trained router looks at each image and picks a branch:
Only the selected branch runs, and its alpha is upsampled to the image's native resolution (up to 4096 px per side). To run offline, download the whole bundle and set WITHOUTBG_MODEL_PATH to withoutbg-open-weights.onnx inside it; the other graphs are read from the same folder.
Licensed under the withoutBG Open Model License (Apache 2.0 for withoutBG portions; Meta DINOv3 License for DINOv3 backbone weights; MIT for BiRefNet). See the model's LICENSE.
uv sync --extra dev
make test-fast # fast unit tests
make quality # lint + format + type check
make test # full suite (downloads model on first run)
See CONTRIBUTING.md for the full guide.
This Python SDK is licensed under Apache License 2.0. See LICENSE.
The withoutBG Open Weights Model is a composite artifact with additional terms for embedded DINOv3 weights. See the withoutBG Open Model License, LICENSE-DINOv3, and NOTICE.
See THIRD_PARTY_LICENSES.md for complete attribution.
4,693 followers · starred Jun 2026
1,103 followers · starred Jan 2026
76 followers · starred Jan 2026
615 followers · starred Apr 2026