OuincheWinch/DiffusionBear

A free, local AI image generation studio for Apple Silicon Macs. Run FLUX.2, Krea 2, Z-Image-Turbo, Qwen-Image-2.1-Turbo and SDXL offline on your Mac .

Python

9

2 commits

updated Oct 17, 2026

See the code

See what people are saying

SourceMessageScoreDate

Running FLUX.2 [Klein], Krea 2 Turbo , Z-Image-Turbo, Qwen-Image-2.1-Turbo and SDXL on a 16GB Mac without frying it: Beta testers wanted for DiffusionBear (MLX-powered) (r/StableDiffusion)

Hi everyone, If you're on an Apple Silicon Mac, you probably know the struggle of trying to run the latest models locally. You either run out of RAM, or the generation times are painfully slow unless you have an M3 Max with 64GB. I been developing DiffusionBear (originally called MLX-Diffusion) to…

0

Oct 11, 2026

README

DiffusionBear

DiffusionBear

Beta — v0.3.8  ·  a local-first image generation studio for Apple Silicon

https://www.diffusionbear.com --- https://www.diffusionbear.com/discord


DiffusionBear runs open-weight diffusion models on your own Mac. Generation, prompt enhancement, LoRA management and the gallery all happen on the machine in front of you: the API listens on 127.0.0.1 (8001, stepping up by 1024 if something else already owns it), model weights are fetched once into a local store, and nothing is uploaded anywhere. No account, no cloud, no per-image billing.

It is built on Apple's MLX framework, so it is Apple Silicon only. There is no CUDA or CPU path, and there is not going to be one — MLX is macOS/Metal exclusive.

Formerly called MLX-Diffusion; renamed in October 2026. The old repository URL still redirects, and old search traffic still lands here.

Beta, honestly. This is the public beta of a one-person project. The core path — FLUX.2-klein and the SDXL engines — is the most used and the most tested. Engines marked experimental in the app (Qwen-Image 2.1) are unsupported previews: they can be slow, and Qwen needs roughly 5 GB of free memory before it starts, so it fails on a busy 16 GB machine. Bug reports and issues are welcome.

Made by Ouinche — heavily coded by AI (Gemini, 0xAlpha, Big Pickle) — released under the MIT licence.


Get the app

The compiled macOS app is the main thing this project produces. DiffusionBear.app is self-contained: it bundles the FastAPI backend, two relocatable Python runtimes and the compiled single-page UI, and serves both the API and the interface from 127.0.0.1. There is nothing to install — no Python, no Node, no virtual environments on your side.

DiffusionBear

Detail
RequiresAn Apple Silicon Mac, macOS 26.2 or later, 16 GB unified memory recommended. The floor is derived from the minos of the Mach-O binaries in the bundle (libmlx.dylib, core.cpython-310-darwin.so) rather than hardcoded, so the plist can no longer understate it.
First launchThe app is ad-hoc signed, not notarised with an Apple Developer ID. macOS will therefore block a plain double-click the first time — right-click the app → Open to get past Gatekeeper.
Your filesSettings, gallery, LoRA registry and model store live in ~/Library/Application Support/DiffusionBear, never inside the app bundle. To put the store on another volume, write an absolute path into ~/Library/Application Support/DiffusionBear/store_path; a store path can be shared by several installs.
Model weightsNot bundled. They are downloaded on first use from Hugging Face or Civitai into that store — a few GB for the first model. After that the app works fully offline.
Download DiffusionBear 0.3.8 for macOS (Apple Silicon)

⬇ Download DiffusionBear 0.3.8 for macOS (Apple Silicon) — 482 MB, from the v0.3.8 release.

  1. Unzip it and move DiffusionBear.app into /Applications.
  2. First launch only: the app is ad-hoc signed, not notarised with an Apple Developer ID, so macOS refuses a plain double-click with "Apple cannot check it for malicious software". Right-click the app → Open → Open. It is not malware; it is simply unsigned, and the warning does not return on later launches.
  3. To check the download: shasum -a 256 DiffusionBear-0.3.8-arm64.zip, compared against the ALL_SHA256SUMS published beside it.

Prefer to build it yourself? Build it from packaging/ — it is three scripts and no decisions to make.


Screenshots

Captured from v0.3.8 on a MacBook Pro (Apple M1, 16 GB), running against a live backend — not mock-ups.

GenerateBrowser
The generation pageThe browser
ModelsParameters
The models tabThe parameters tab
Prompt enhancerLicences
Prompt enhancerLicences tab

What it does

Models — find them, get them, make them runnable

  • Browse and download from inside the app. The Models tab searches Hugging Face and Civitai side by side, classifies results into the SDXL / FLUX.2 / Krea 2 / Z-Image buckets, and downloads with live progress, speed and cancel. A direct URL works too.
  • Convert single-file Civitai SDXL checkpoints into runnable diffusers directories. The conversion runs out of process so a slow one cannot stall the API, and it repairs the two things diffusers otherwise chokes on: CLIP text_model.* key naming and the slow tokenizer's missing vocab.json / merges.txt.
  • Register a model you already have. Point the app at a diffusers folder on disk or at a repo in your Hugging Face cache and it loads it in place — nothing is re-downloaded or copied.
  • Honest states. A model that is present but not runnable (missing model_index, a stale .incomplete download) is reported as not runnable rather than as ready.

Generating

  • Engine presets, batch counts, seed lock / random / +1 / +1024, guidance, negative prompts where the architecture supports them, and a sampler picker where it matters.
  • Reference images. FLUX.2-klein takes up to 10 references referenced in the prompt as Image 1, Image 2, … ; Z-Image, Krea 2 and Qwen take one.
  • Generative fill. Paint a mask on a gallery image and regenerate just that region (FLUX.2-klein only — it is the one engine with spatial conditioning).
  • One generation at a time, behind a worker thread and a FIFO queue. This is deliberate; see CONTRIBUTING.md.

Prompt enhancement

  • A local Qwen2.5-0.5B-Instruct 4-bit model rewrites your prompt for the selected engine, in prose or in JSON, with editable per-engine system prompts.
  • Active LoRA trigger words are preserved verbatim, with a deterministic re-insertion guarantee.

LoRAs

  • Drag a .safetensors in, or import from Civitai with progress and cancel. FLUX.2 and SDXL formats are both supported, and SDXL adapters stack by rank-concat. Trigger words become clickable chips in the prompt box.

Your library

  • A local gallery with tags, text search, and one-click Use as Reference.
  • 2× / 4× Lanczos upscaling with unsharp masking.
  • Civitai-compliant metadata: every PNG embeds prompt, seed, steps, sampler, CFG, model and LoRA names/hashes as tEXt + EXIF, so the exact checkpoint and LoRAs are recognised automatically if you upload the image. A stealth mode omits all of it.
  • Interface in English, French, German, Italian, Spanish, Simplified Chinese, Japanese, Portuguese and Korean.
  • A ⚖ Licences tab listing the licence of every bundled package and every supported model.

Supported models

Nine checkpoints across five families, all quantised to 4-bit and memory-tuned for 16 GB of unified memory. Switching engine swaps weights on demand rather than keeping everything resident.

ModelFamilyDefault stepsNotes
FLUX.2-klein 4BFLUX.24Up to 10 reference images, LoRA, guidance. No negative prompt (guidance-distilled).
FLUX.2-klein 9BFLUX.24Same capabilities, roughly twice the cost per image.
Z-Image Turbo 6BZ-Image6One reference image, LoRA. No guidance or negative prompt.
Krea 2 Turbo 13BKrea 28One reference image, LoRA. At 4 steps the app auto-loads the Krea distilled 4-step LoRA, so 4 and 8 steps are two different pipelines, not one model at two budgets.
Qwen-Image 2.1Qwen-Image25Experimental. One reference image, negative prompts supported, no LoRA. Needs ~5 GB free memory; its bf16 VAE decode can exhaust Metal on a busy 16 GB machine.
Juggernaut XL LightningSDXL4Distilled 4-step + TAESD decode — the fastest combo here. Sampler picker, negative prompts, DeepCache.
RealVisXL V5.0 LightningSDXL6As above, distilled 6-step.
RealVisXL V5.0 (Hyper-SD)SDXL25Base checkpoint with an 8-step Hyper-SD draft preset.
Juggernaut XI v11 (Hyper-SD)SDXL25Base checkpoint with an 8-step Hyper-SD draft preset.

Local by design

Every part of the pipeline runs from your Mac's own memory:

  • Generation runs on the Metal GPU through MLX (mflux for the flow-matching models, a native MLX SDXL daemon for the SDXL checkpoints). Weights are 4-bit so a 4–13 B parameter model fits the 16 GB unified memory of an M1 MacBook Pro.
  • The prompt enhancer is a local LLM too, so rewriting a prompt never leaves the machine either.
  • No telemetry, no analytics, no network calls at generation time. Once the weights are cached the app works fully offline.
  • No data leaves your computer while generating. The only moment anything is transmitted is when you explicitly download weights, or export an image somewhere. Tokens are stored on your disk and sent only to the service they belong to.

Unified memory is why this works at all on a 16 GB machine: the CPU and GPU share one pool, so a quantised model stays resident with no CPU↔GPU copying — which is exactly what MLX is built to exploit.

Optional tokens

No account is needed to generate. Two optional tokens make downloads smoother:

TokenWhy it helpsWhere
Civitai API keyResumable LoRA and checkpoint downloads; some model versions are auth-gatedSettings → Tokens, or env CIVITAI_API_KEY
Hugging Face tokenUnlocks gated and private models, and avoids first-download rate limitsSettings → Tokens, or env HF_TOKEN (or huggingface-cli login)

Benchmarks

Measured on a 2021 MacBook Pro M1 (16 GB) — the reference machine this project is tuned for. This table is a September 2026 snapshot (293 timed studio generations plus an 18-run repeatability suite). Defaults have moved since — Z-Image Turbo in particular now starts at 6 steps instead of 8 — so read it as a record of that build, not as a promise about the current one.

Methodology — removing load spikes: within each model × resolution bucket the 5% fastest and 5% slowest times are excluded before computing mean and median (other Metal work on the machine routinely inflates outliers). Aborted records (<2 s) are dropped; single-sample buckets are kept as indicative only.

ModelResolutionStepsn (trim)MeanMedianTrimmed range
FLUX.2-klein 4B512×51245/745 s48 s38 – 51 s
FLUX.2-klein 4B512×76842/255 s55 s54 – 56 s
FLUX.2-klein 4B768×76842/21:16 min1:16 min1:14 – 1:19 min
FLUX.2-klein 4B768×115242/45:02 min5:02 min4:53 – 5:11 min
FLUX.2-klein 4B1024×102441/12:03 min2:03 min—
FLUX.2-klein 9B512×76841/11:51 min1:51 min—
FLUX.2-klein 9B768×115244/67:14 min6:46 min4:17 – 11:04 min
Juggernaut XL Lightning (SDXL)512×51242/422 s22 s10 – 33 s
Juggernaut XL Lightning (SDXL)512×768425/279 s9 s9 – 11 s
Juggernaut XL Lightning (SDXL)832×1216414/162:08 min1:57 min1:21 – 3:13 min
Juggernaut XL Lightning (SDXL)1024×102441/11:06 min1:06 min—
Juggernaut XI v11 (SDXL)512×768810/1250 s49 s42 s – 1:11 min
Krea 2 Turbo 13B512×51287/92:44 min2:44 min1:38 – 3:36 min
Krea 2 Turbo 13B512×7684*41/453:41 min2:51 min1:22 – 6:40 min
RealVisXL V5.0 (SDXL)512×768810/121:00 min55 s46 s – 1:21 min
RealVisXL V5.0 Lightning (SDXL)512×512623/2523 s22 s20 – 27 s
RealVisXL V5.0 Lightning (SDXL)512×768627/2933 s31 s30 – 51 s
RealVisXL V5.0 Lightning (SDXL)768×76862/42:48 min2:48 min2:44 – 2:53 min
RealVisXL V5.0 Lightning (SDXL)832×121662/43:31 min3:31 min3:17 – 3:45 min
RealVisXL V5.0 Lightning (SDXL)1024×102462/21:55 min1:55 min1:53 – 1:57 min
Z-Image Turbo 6B512×512846/521:42 min1:43 min1:15 – 2:13 min
Z-Image Turbo 6B512×768816/182:22 min2:22 min1:57 – 2:43 min
Z-Image Turbo 6B768×76883/53:49 min3:44 min3:44 – 3:59 min
Qwen-Image 2.1512×7682010/107:38 min7:36 min7:10 – 8:05 min

n (trim) = samples kept after removing the fastest/slowest 5% out of the raw count. * 4-step Krea runs use the Krea 2 distilled 4-step LoRA. — = single-sample bucket.

Repeatability suite (Sep 20, run under elevated system load up to ~9):

ModelResolutionnMeanMedian
FLUX.2-klein 4B768×76811 (9)1:15 min1:14 min
FLUX.2-klein 4B1024×102422:02 min2:02 min
Z-Image Turbo 6B768×76822:54 min2:54 min
Juggernaut XL Lightning (SDXL)1024×102411:07 min1:07 min
Krea 2 Turbo 13B1024×1024212:16 min12:16 min

How to read it: Juggernaut XL Lightning at 512×768 is by far the fastest combo (median 9 s — distilled 4 steps plus a TAESD decode); Z-Image Turbo costs more than an order of magnitude as much at the same size (2:22 median), and FLUX.2-klein sits in between with the most resolution flexibility. The wide trimmed ranges on the 512×768 buckets (Krea, Z-Image, Juggernaut at 832×1216) are exactly the load spikes this methodology filters — treat medians, not means, as the stable number. The Qwen-Image 2.1 row comes from a separate controlled sweep (10 scenes, seeds 1001–1010, 20-step linear, guidance 1.0) which also confirmed its 64-channel RGBA VAE handles 512×768 on a 16 GB M1 without running out of memory.


Model vs model — visual arena

Head-to-head repeatability comparisons on original, royalty-free scenes — a sourdough loaf, a cliff villa, a snow leopard, no copyrighted characters. Each duel plays right here in the README as a muted auto-wiping divider video; for the draggable version, open ouinche.com/mlx-diffusion-yet-another-open-source-image-generator-on-apple-silicon in a browser. GitHub strips JavaScript from READMEs, so a slider cannot render on the repo page — the moving divider is the closest thing that does.

FLUX.2-klein 4B vs Z-Image Turbo 6B — "Rustic Sourdough" (512×768)

FLUX.2-klein 4BZ-Image Turbo 6B
FLUX.2-klein 4B, Rustic SourdoughZ-Image Turbo 6B, Rustic Sourdough

FLUX.2-klein 4B vs Juggernaut XL Lightning — "Modern Glass Villa" (512×768)

FLUX.2-klein 4BJuggernaut XL Lightning
FLUX.2-klein 4B, Modern Glass VillaJuggernaut XL Lightning, Modern Glass Villa

FLUX.2-klein 4B vs Krea 2 Turbo 13B — "Snow Leopard" (512×768)

FLUX.2-klein 4BKrea 2 Turbo 13B
FLUX.2-klein 4B, Snow LeopardKrea 2 Turbo 13B, Snow Leopard

Build the app yourself

The bundle is assembled by three scripts, in this order:

packaging/build_runtime_venv.sh   # main runtime: Python 3.10 + mflux
packaging/build_sdxl_venv.sh      # SDXL engine runtime: Python 3.14 + mlx_diffuser
packaging/build_app.sh            # assembles and ad-hoc signs DiffusionBear.app

They write to packaging/dist/DiffusionBear.app. Install it with a copy, not ditto (see the note at the end of build_app.sh):

rm -rf /Applications/DiffusionBear.app
cp -R packaging/dist/DiffusionBear.app /Applications/

Two things worth knowing before you touch these scripts. The runtimes are python-build-standalone interpreters, not a copy of venv/ — a repo venv points at a Homebrew install and is not relocatable, which is precisely what breaks inside a bundle. And build_app.sh audits the result and fails the build if it finds model weights, credential-shaped files, or unexpected large files outside the runtimes; if it complains, do not ship the bundle.


Build from source

If you would rather run it from a checkout than install the app — for development, or to read it — the source is the whole thing and there are two ways to launch it.

Requirements: an Apple Silicon Mac (16 GB+ recommended), Python 3.10 and Python 3.14, Node.js 18+.

git clone https://github.com/OuincheWinch/DiffusionBear.git
cd DiffusionBear

Both virtual environments are required: venv/ for the main engine, venv-sdxl/ for the isolated SDXL engine.

python3 -m venv venv
python3 -m venv venv-sdxl

./venv/bin/python -m pip install -r backend/requirements.txt
./venv-sdxl/bin/python -m pip install -r backend/requirements-sdxl.txt

cd frontend && npm install && cd ..

Then launch everything — backend, frontend and browser:

./run.sh

run.sh starts FastAPI on 8001, Vite on 5174, opens the UI, and keeps the Mac awake with caffeinate during long renders. CTRL+C stops everything. The first generation downloads the model weights once (a few GB into the Hugging Face cache); after that it runs offline.

Ports 8001 and 5174 are deliberate. 8000 and 5173 belong to other tools on the author's machine. Do not "fix" them.

Launch the backend with ./venv/bin/python -m uvicorn …, never ./venv/bin/uvicorn — the venv console-script shebangs can point at a stale interpreter after the project folder is renamed, and the app then silently boots with the wrong mflux. run.sh already resolves the right one.

Development mode (two terminals)

./dev-backend.sh                   # FastAPI, port 8001, hot reload
cd frontend && npm run dev         # Vite, port 5174, hot reload

Free a stuck service with lsof -ti :8001,5174 | xargs kill -9.

Other frontend tasks: npm run lint (oxlint) and npm run build (production bundle). The GitHub Actions workflow compiles the backend, runs its test suite, and runs frontend lint plus build on every push to main and on every pull request.

Your first prompt — FLUX.2-klein 4B at 4 steps is a good first run:

A mischievous baby otter wearing a tiny yellow developer helmet, sitting in front of a futuristic glowing computer setup. The glowing computer screen clearly displays the words "HELLO WORLD" in vibrant neon text. Warm studio lighting, shallow depth of field, 8k resolution, cinematic photorealism.

HELLOWORLD

Uninstall

Check the path twice, then:

cd /path/to/your/DiffusionBear
cd .. && rm -rf DiffusionBear

To leave nothing behind:

python3 -m pip cache purge     # downloaded wheels and packages
npm cache clean --force        # npm cache

Repository layout

PathWhat it is
backend/FastAPI service (main.py), generation engines (generator.py, sdxl_engine.py, qwen_engine.py), model registry and the Hugging Face / Civitai / SDXL-conversion clients
frontend/React 19 + Vite single-page UI
packaging/Scripts and Swift shell that build and sign DiffusionBear.app
docs/Assets used by this README, including the interactive benchmark arena
test/Benchmark, A/B and repeatability harnesses, and the runs they recorded

Longer guides: readme.txt (models, tuning rules, troubleshooting) and USER_GUIDE.md.


Documentation


Author and AI-assisted development

DiffusionBear is written and maintained by Ouinche (https://github.com/OuincheWinch), and is heavily coded by AI — Gemini, 0xAlpha and Big Pickle do a large share of the writing. That is a deliberate choice, not an accident, and it is why the contribution rules ask for a human review and a measurement alongside every change.

Security

Please do not open a public issue for a security problem. Use GitHub's private vulnerability report, or email the author with the subject [DiffusionBear security]. Acknowledgement within 3 working days; treat proof-of-concepts as embargoed until the issue is fixed or declined. Scope and the privacy posture are in SECURITY.md.

Fonts and licensing

The app embeds no fonts. There is no @font-face anywhere in the frontend and no web font in the bundle, so there is no font for anyone to redistribute and nothing to license.

What the interface does is name fonts, which is what a native Mac app does:

KindExamplesWhy it is fine
CSS keywordsystem-ui, ui-monospace, sans-serif, monospaceResolved by the browser. No font is named or shipped.
macOS system font-apple-system, Menlo, SFMono-RegularmacOS provides these. The app ships no copy — naming one is not redistribution.
Open fontDejaVu Sans Mono, Liberation MonoFree and open (Bitstream Vera / SIL OFL 1.1), named only as fallbacks.

38 TTF files do appear inside venv/ — DejaVu, STIX and Computer Modern, all arriving with matplotlib, which is a transitive dependency and is not imported by any backend module. All three are free (DejaVu: Bitstream Vera plus public-domain changes; STIX: SIL OFL 1.1; Computer Modern: Knuth, public-domain lineage) and LICENSE_DEJAVU and LICENSE_STIX ship beside them so the claim is checkable rather than asserted.

This is enforced by a test rather than by good intentions. backend/test_font_licensing.py fails on any font-family name that is not a CSS keyword, a macOS system font, or a known open font — it is default-deny, so a font nobody has classified yet stops the build rather than passing unnoticed. It found Consolas in the stylesheet: a Microsoft font, and one that could only ever resolve on a Mac that already had Office installed. It was removed.

License

MIT — Copyright © 2026 Ouinche. This covers the project's source code only. Model weights carry their own terms (FLUX.2 is Black Forest Labs non-commercial; the Juggernaut and RealVisXL checkpoints are non-commercial too), and none of them are redistributed here — they are downloaded from Hugging Face or Civitai on first use. The app shows the full per-package and per-model licences in its ⚖ Licences tab.

apple
apple-silicon
flux
flux2
generative-ai
image-generation
image-generation-ai
image-generation-api
krea-2
krea2
local-ai
mac
macos
mlx
mlx-lm
qwen-image
sdxl
stable-diffusion
stable-diffusion-xl
z-image-turbo

OuincheWinch/DiffusionBear

A free, local AI image generation studio for Apple Silicon Macs. Run FLUX.2, Krea 2, Z-Image-Turbo, Qwen-Image-2.1-Turbo and SDXL offline on your Mac .

Python

9

2 commits

updated Oct 17, 2026

See the code

See what people are saying

SourceMessageScoreDate

Running FLUX.2 [Klein], Krea 2 Turbo , Z-Image-Turbo, Qwen-Image-2.1-Turbo and SDXL on a 16GB Mac without frying it: Beta testers wanted for DiffusionBear (MLX-powered) (r/StableDiffusion)

Hi everyone, If you're on an Apple Silicon Mac, you probably know the struggle of trying to run the latest models locally. You either run out of RAM, or the generation times are painfully slow unless you have an M3 Max with 64GB. I been developing DiffusionBear (originally called MLX-Diffusion) to…

0

Oct 11, 2026

README

DiffusionBear

DiffusionBear

Beta — v0.3.8  ·  a local-first image generation studio for Apple Silicon

https://www.diffusionbear.com --- https://www.diffusionbear.com/discord


DiffusionBear runs open-weight diffusion models on your own Mac. Generation, prompt enhancement, LoRA management and the gallery all happen on the machine in front of you: the API listens on 127.0.0.1 (8001, stepping up by 1024 if something else already owns it), model weights are fetched once into a local store, and nothing is uploaded anywhere. No account, no cloud, no per-image billing.

It is built on Apple's MLX framework, so it is Apple Silicon only. There is no CUDA or CPU path, and there is not going to be one — MLX is macOS/Metal exclusive.

Formerly called MLX-Diffusion; renamed in October 2026. The old repository URL still redirects, and old search traffic still lands here.

Beta, honestly. This is the public beta of a one-person project. The core path — FLUX.2-klein and the SDXL engines — is the most used and the most tested. Engines marked experimental in the app (Qwen-Image 2.1) are unsupported previews: they can be slow, and Qwen needs roughly 5 GB of free memory before it starts, so it fails on a busy 16 GB machine. Bug reports and issues are welcome.

Made by Ouinche — heavily coded by AI (Gemini, 0xAlpha, Big Pickle) — released under the MIT licence.


Get the app

The compiled macOS app is the main thing this project produces. DiffusionBear.app is self-contained: it bundles the FastAPI backend, two relocatable Python runtimes and the compiled single-page UI, and serves both the API and the interface from 127.0.0.1. There is nothing to install — no Python, no Node, no virtual environments on your side.

DiffusionBear

Detail
RequiresAn Apple Silicon Mac, macOS 26.2 or later, 16 GB unified memory recommended. The floor is derived from the minos of the Mach-O binaries in the bundle (libmlx.dylib, core.cpython-310-darwin.so) rather than hardcoded, so the plist can no longer understate it.
First launchThe app is ad-hoc signed, not notarised with an Apple Developer ID. macOS will therefore block a plain double-click the first time — right-click the app → Open to get past Gatekeeper.
Your filesSettings, gallery, LoRA registry and model store live in ~/Library/Application Support/DiffusionBear, never inside the app bundle. To put the store on another volume, write an absolute path into ~/Library/Application Support/DiffusionBear/store_path; a store path can be shared by several installs.
Model weightsNot bundled. They are downloaded on first use from Hugging Face or Civitai into that store — a few GB for the first model. After that the app works fully offline.
Download DiffusionBear 0.3.8 for macOS (Apple Silicon)

⬇ Download DiffusionBear 0.3.8 for macOS (Apple Silicon) — 482 MB, from the v0.3.8 release.

  1. Unzip it and move DiffusionBear.app into /Applications.
  2. First launch only: the app is ad-hoc signed, not notarised with an Apple Developer ID, so macOS refuses a plain double-click with "Apple cannot check it for malicious software". Right-click the app → Open → Open. It is not malware; it is simply unsigned, and the warning does not return on later launches.
  3. To check the download: shasum -a 256 DiffusionBear-0.3.8-arm64.zip, compared against the ALL_SHA256SUMS published beside it.

Prefer to build it yourself? Build it from packaging/ — it is three scripts and no decisions to make.


Screenshots

Captured from v0.3.8 on a MacBook Pro (Apple M1, 16 GB), running against a live backend — not mock-ups.

GenerateBrowser
The generation pageThe browser
ModelsParameters
The models tabThe parameters tab
Prompt enhancerLicences
Prompt enhancerLicences tab

What it does

Models — find them, get them, make them runnable

  • Browse and download from inside the app. The Models tab searches Hugging Face and Civitai side by side, classifies results into the SDXL / FLUX.2 / Krea 2 / Z-Image buckets, and downloads with live progress, speed and cancel. A direct URL works too.
  • Convert single-file Civitai SDXL checkpoints into runnable diffusers directories. The conversion runs out of process so a slow one cannot stall the API, and it repairs the two things diffusers otherwise chokes on: CLIP text_model.* key naming and the slow tokenizer's missing vocab.json / merges.txt.
  • Register a model you already have. Point the app at a diffusers folder on disk or at a repo in your Hugging Face cache and it loads it in place — nothing is re-downloaded or copied.
  • Honest states. A model that is present but not runnable (missing model_index, a stale .incomplete download) is reported as not runnable rather than as ready.

Generating

  • Engine presets, batch counts, seed lock / random / +1 / +1024, guidance, negative prompts where the architecture supports them, and a sampler picker where it matters.
  • Reference images. FLUX.2-klein takes up to 10 references referenced in the prompt as Image 1, Image 2, … ; Z-Image, Krea 2 and Qwen take one.
  • Generative fill. Paint a mask on a gallery image and regenerate just that region (FLUX.2-klein only — it is the one engine with spatial conditioning).
  • One generation at a time, behind a worker thread and a FIFO queue. This is deliberate; see CONTRIBUTING.md.

Prompt enhancement

  • A local Qwen2.5-0.5B-Instruct 4-bit model rewrites your prompt for the selected engine, in prose or in JSON, with editable per-engine system prompts.
  • Active LoRA trigger words are preserved verbatim, with a deterministic re-insertion guarantee.

LoRAs

  • Drag a .safetensors in, or import from Civitai with progress and cancel. FLUX.2 and SDXL formats are both supported, and SDXL adapters stack by rank-concat. Trigger words become clickable chips in the prompt box.

Your library

  • A local gallery with tags, text search, and one-click Use as Reference.
  • 2× / 4× Lanczos upscaling with unsharp masking.
  • Civitai-compliant metadata: every PNG embeds prompt, seed, steps, sampler, CFG, model and LoRA names/hashes as tEXt + EXIF, so the exact checkpoint and LoRAs are recognised automatically if you upload the image. A stealth mode omits all of it.
  • Interface in English, French, German, Italian, Spanish, Simplified Chinese, Japanese, Portuguese and Korean.
  • A ⚖ Licences tab listing the licence of every bundled package and every supported model.

Supported models

Nine checkpoints across five families, all quantised to 4-bit and memory-tuned for 16 GB of unified memory. Switching engine swaps weights on demand rather than keeping everything resident.

ModelFamilyDefault stepsNotes
FLUX.2-klein 4BFLUX.24Up to 10 reference images, LoRA, guidance. No negative prompt (guidance-distilled).
FLUX.2-klein 9BFLUX.24Same capabilities, roughly twice the cost per image.
Z-Image Turbo 6BZ-Image6One reference image, LoRA. No guidance or negative prompt.
Krea 2 Turbo 13BKrea 28One reference image, LoRA. At 4 steps the app auto-loads the Krea distilled 4-step LoRA, so 4 and 8 steps are two different pipelines, not one model at two budgets.
Qwen-Image 2.1Qwen-Image25Experimental. One reference image, negative prompts supported, no LoRA. Needs ~5 GB free memory; its bf16 VAE decode can exhaust Metal on a busy 16 GB machine.
Juggernaut XL LightningSDXL4Distilled 4-step + TAESD decode — the fastest combo here. Sampler picker, negative prompts, DeepCache.
RealVisXL V5.0 LightningSDXL6As above, distilled 6-step.
RealVisXL V5.0 (Hyper-SD)SDXL25Base checkpoint with an 8-step Hyper-SD draft preset.
Juggernaut XI v11 (Hyper-SD)SDXL25Base checkpoint with an 8-step Hyper-SD draft preset.

Local by design

Every part of the pipeline runs from your Mac's own memory:

  • Generation runs on the Metal GPU through MLX (mflux for the flow-matching models, a native MLX SDXL daemon for the SDXL checkpoints). Weights are 4-bit so a 4–13 B parameter model fits the 16 GB unified memory of an M1 MacBook Pro.
  • The prompt enhancer is a local LLM too, so rewriting a prompt never leaves the machine either.
  • No telemetry, no analytics, no network calls at generation time. Once the weights are cached the app works fully offline.
  • No data leaves your computer while generating. The only moment anything is transmitted is when you explicitly download weights, or export an image somewhere. Tokens are stored on your disk and sent only to the service they belong to.

Unified memory is why this works at all on a 16 GB machine: the CPU and GPU share one pool, so a quantised model stays resident with no CPU↔GPU copying — which is exactly what MLX is built to exploit.

Optional tokens

No account is needed to generate. Two optional tokens make downloads smoother:

TokenWhy it helpsWhere
Civitai API keyResumable LoRA and checkpoint downloads; some model versions are auth-gatedSettings → Tokens, or env CIVITAI_API_KEY
Hugging Face tokenUnlocks gated and private models, and avoids first-download rate limitsSettings → Tokens, or env HF_TOKEN (or huggingface-cli login)

Benchmarks

Measured on a 2021 MacBook Pro M1 (16 GB) — the reference machine this project is tuned for. This table is a September 2026 snapshot (293 timed studio generations plus an 18-run repeatability suite). Defaults have moved since — Z-Image Turbo in particular now starts at 6 steps instead of 8 — so read it as a record of that build, not as a promise about the current one.

Methodology — removing load spikes: within each model × resolution bucket the 5% fastest and 5% slowest times are excluded before computing mean and median (other Metal work on the machine routinely inflates outliers). Aborted records (<2 s) are dropped; single-sample buckets are kept as indicative only.

ModelResolutionStepsn (trim)MeanMedianTrimmed range
FLUX.2-klein 4B512×51245/745 s48 s38 – 51 s
FLUX.2-klein 4B512×76842/255 s55 s54 – 56 s
FLUX.2-klein 4B768×76842/21:16 min1:16 min1:14 – 1:19 min
FLUX.2-klein 4B768×115242/45:02 min5:02 min4:53 – 5:11 min
FLUX.2-klein 4B1024×102441/12:03 min2:03 min—
FLUX.2-klein 9B512×76841/11:51 min1:51 min—
FLUX.2-klein 9B768×115244/67:14 min6:46 min4:17 – 11:04 min
Juggernaut XL Lightning (SDXL)512×51242/422 s22 s10 – 33 s
Juggernaut XL Lightning (SDXL)512×768425/279 s9 s9 – 11 s
Juggernaut XL Lightning (SDXL)832×1216414/162:08 min1:57 min1:21 – 3:13 min
Juggernaut XL Lightning (SDXL)1024×102441/11:06 min1:06 min—
Juggernaut XI v11 (SDXL)512×768810/1250 s49 s42 s – 1:11 min
Krea 2 Turbo 13B512×51287/92:44 min2:44 min1:38 – 3:36 min
Krea 2 Turbo 13B512×7684*41/453:41 min2:51 min1:22 – 6:40 min
RealVisXL V5.0 (SDXL)512×768810/121:00 min55 s46 s – 1:21 min
RealVisXL V5.0 Lightning (SDXL)512×512623/2523 s22 s20 – 27 s
RealVisXL V5.0 Lightning (SDXL)512×768627/2933 s31 s30 – 51 s
RealVisXL V5.0 Lightning (SDXL)768×76862/42:48 min2:48 min2:44 – 2:53 min
RealVisXL V5.0 Lightning (SDXL)832×121662/43:31 min3:31 min3:17 – 3:45 min
RealVisXL V5.0 Lightning (SDXL)1024×102462/21:55 min1:55 min1:53 – 1:57 min
Z-Image Turbo 6B512×512846/521:42 min1:43 min1:15 – 2:13 min
Z-Image Turbo 6B512×768816/182:22 min2:22 min1:57 – 2:43 min
Z-Image Turbo 6B768×76883/53:49 min3:44 min3:44 – 3:59 min
Qwen-Image 2.1512×7682010/107:38 min7:36 min7:10 – 8:05 min

n (trim) = samples kept after removing the fastest/slowest 5% out of the raw count. * 4-step Krea runs use the Krea 2 distilled 4-step LoRA. — = single-sample bucket.

Repeatability suite (Sep 20, run under elevated system load up to ~9):

ModelResolutionnMeanMedian
FLUX.2-klein 4B768×76811 (9)1:15 min1:14 min
FLUX.2-klein 4B1024×102422:02 min2:02 min
Z-Image Turbo 6B768×76822:54 min2:54 min
Juggernaut XL Lightning (SDXL)1024×102411:07 min1:07 min
Krea 2 Turbo 13B1024×1024212:16 min12:16 min

How to read it: Juggernaut XL Lightning at 512×768 is by far the fastest combo (median 9 s — distilled 4 steps plus a TAESD decode); Z-Image Turbo costs more than an order of magnitude as much at the same size (2:22 median), and FLUX.2-klein sits in between with the most resolution flexibility. The wide trimmed ranges on the 512×768 buckets (Krea, Z-Image, Juggernaut at 832×1216) are exactly the load spikes this methodology filters — treat medians, not means, as the stable number. The Qwen-Image 2.1 row comes from a separate controlled sweep (10 scenes, seeds 1001–1010, 20-step linear, guidance 1.0) which also confirmed its 64-channel RGBA VAE handles 512×768 on a 16 GB M1 without running out of memory.


Model vs model — visual arena

Head-to-head repeatability comparisons on original, royalty-free scenes — a sourdough loaf, a cliff villa, a snow leopard, no copyrighted characters. Each duel plays right here in the README as a muted auto-wiping divider video; for the draggable version, open ouinche.com/mlx-diffusion-yet-another-open-source-image-generator-on-apple-silicon in a browser. GitHub strips JavaScript from READMEs, so a slider cannot render on the repo page — the moving divider is the closest thing that does.

FLUX.2-klein 4B vs Z-Image Turbo 6B — "Rustic Sourdough" (512×768)

FLUX.2-klein 4BZ-Image Turbo 6B
FLUX.2-klein 4B, Rustic SourdoughZ-Image Turbo 6B, Rustic Sourdough

FLUX.2-klein 4B vs Juggernaut XL Lightning — "Modern Glass Villa" (512×768)

FLUX.2-klein 4BJuggernaut XL Lightning
FLUX.2-klein 4B, Modern Glass VillaJuggernaut XL Lightning, Modern Glass Villa

FLUX.2-klein 4B vs Krea 2 Turbo 13B — "Snow Leopard" (512×768)

FLUX.2-klein 4BKrea 2 Turbo 13B
FLUX.2-klein 4B, Snow LeopardKrea 2 Turbo 13B, Snow Leopard

Build the app yourself

The bundle is assembled by three scripts, in this order:

packaging/build_runtime_venv.sh   # main runtime: Python 3.10 + mflux
packaging/build_sdxl_venv.sh      # SDXL engine runtime: Python 3.14 + mlx_diffuser
packaging/build_app.sh            # assembles and ad-hoc signs DiffusionBear.app

They write to packaging/dist/DiffusionBear.app. Install it with a copy, not ditto (see the note at the end of build_app.sh):

rm -rf /Applications/DiffusionBear.app
cp -R packaging/dist/DiffusionBear.app /Applications/

Two things worth knowing before you touch these scripts. The runtimes are python-build-standalone interpreters, not a copy of venv/ — a repo venv points at a Homebrew install and is not relocatable, which is precisely what breaks inside a bundle. And build_app.sh audits the result and fails the build if it finds model weights, credential-shaped files, or unexpected large files outside the runtimes; if it complains, do not ship the bundle.


Build from source

If you would rather run it from a checkout than install the app — for development, or to read it — the source is the whole thing and there are two ways to launch it.

Requirements: an Apple Silicon Mac (16 GB+ recommended), Python 3.10 and Python 3.14, Node.js 18+.

git clone https://github.com/OuincheWinch/DiffusionBear.git
cd DiffusionBear

Both virtual environments are required: venv/ for the main engine, venv-sdxl/ for the isolated SDXL engine.

python3 -m venv venv
python3 -m venv venv-sdxl

./venv/bin/python -m pip install -r backend/requirements.txt
./venv-sdxl/bin/python -m pip install -r backend/requirements-sdxl.txt

cd frontend && npm install && cd ..

Then launch everything — backend, frontend and browser:

./run.sh

run.sh starts FastAPI on 8001, Vite on 5174, opens the UI, and keeps the Mac awake with caffeinate during long renders. CTRL+C stops everything. The first generation downloads the model weights once (a few GB into the Hugging Face cache); after that it runs offline.

Ports 8001 and 5174 are deliberate. 8000 and 5173 belong to other tools on the author's machine. Do not "fix" them.

Launch the backend with ./venv/bin/python -m uvicorn …, never ./venv/bin/uvicorn — the venv console-script shebangs can point at a stale interpreter after the project folder is renamed, and the app then silently boots with the wrong mflux. run.sh already resolves the right one.

Development mode (two terminals)

./dev-backend.sh                   # FastAPI, port 8001, hot reload
cd frontend && npm run dev         # Vite, port 5174, hot reload

Free a stuck service with lsof -ti :8001,5174 | xargs kill -9.

Other frontend tasks: npm run lint (oxlint) and npm run build (production bundle). The GitHub Actions workflow compiles the backend, runs its test suite, and runs frontend lint plus build on every push to main and on every pull request.

Your first prompt — FLUX.2-klein 4B at 4 steps is a good first run:

A mischievous baby otter wearing a tiny yellow developer helmet, sitting in front of a futuristic glowing computer setup. The glowing computer screen clearly displays the words "HELLO WORLD" in vibrant neon text. Warm studio lighting, shallow depth of field, 8k resolution, cinematic photorealism.

HELLOWORLD

Uninstall

Check the path twice, then:

cd /path/to/your/DiffusionBear
cd .. && rm -rf DiffusionBear

To leave nothing behind:

python3 -m pip cache purge     # downloaded wheels and packages
npm cache clean --force        # npm cache

Repository layout

PathWhat it is
backend/FastAPI service (main.py), generation engines (generator.py, sdxl_engine.py, qwen_engine.py), model registry and the Hugging Face / Civitai / SDXL-conversion clients
frontend/React 19 + Vite single-page UI
packaging/Scripts and Swift shell that build and sign DiffusionBear.app
docs/Assets used by this README, including the interactive benchmark arena
test/Benchmark, A/B and repeatability harnesses, and the runs they recorded

Longer guides: readme.txt (models, tuning rules, troubleshooting) and USER_GUIDE.md.


Documentation


Author and AI-assisted development

DiffusionBear is written and maintained by Ouinche (https://github.com/OuincheWinch), and is heavily coded by AI — Gemini, 0xAlpha and Big Pickle do a large share of the writing. That is a deliberate choice, not an accident, and it is why the contribution rules ask for a human review and a measurement alongside every change.

Security

Please do not open a public issue for a security problem. Use GitHub's private vulnerability report, or email the author with the subject [DiffusionBear security]. Acknowledgement within 3 working days; treat proof-of-concepts as embargoed until the issue is fixed or declined. Scope and the privacy posture are in SECURITY.md.

Fonts and licensing

The app embeds no fonts. There is no @font-face anywhere in the frontend and no web font in the bundle, so there is no font for anyone to redistribute and nothing to license.

What the interface does is name fonts, which is what a native Mac app does:

KindExamplesWhy it is fine
CSS keywordsystem-ui, ui-monospace, sans-serif, monospaceResolved by the browser. No font is named or shipped.
macOS system font-apple-system, Menlo, SFMono-RegularmacOS provides these. The app ships no copy — naming one is not redistribution.
Open fontDejaVu Sans Mono, Liberation MonoFree and open (Bitstream Vera / SIL OFL 1.1), named only as fallbacks.

38 TTF files do appear inside venv/ — DejaVu, STIX and Computer Modern, all arriving with matplotlib, which is a transitive dependency and is not imported by any backend module. All three are free (DejaVu: Bitstream Vera plus public-domain changes; STIX: SIL OFL 1.1; Computer Modern: Knuth, public-domain lineage) and LICENSE_DEJAVU and LICENSE_STIX ship beside them so the claim is checkable rather than asserted.

This is enforced by a test rather than by good intentions. backend/test_font_licensing.py fails on any font-family name that is not a CSS keyword, a macOS system font, or a known open font — it is default-deny, so a font nobody has classified yet stops the build rather than passing unnoticed. It found Consolas in the stylesheet: a Microsoft font, and one that could only ever resolve on a Mac that already had Office installed. It was removed.

License

MIT — Copyright © 2026 Ouinche. This covers the project's source code only. Model weights carry their own terms (FLUX.2 is Black Forest Labs non-commercial; the Juggernaut and RealVisXL checkpoints are non-commercial too), and none of them are redistributed here — they are downloaded from Hugging Face or Civitai on first use. The app shows the full per-package and per-model licences in its ⚖ Licences tab.

apple
apple-silicon
flux
flux2
generative-ai
image-generation
image-generation-ai
image-generation-api
krea-2
krea2
local-ai
mac
macos
mlx
mlx-lm
qwen-image
sdxl
stable-diffusion
stable-diffusion-xl
z-image-turbo