There is a 17 GB folder on my Mac that paints. Ask it for a watercolor of a tower by the sea and about ninety seconds later the file is sitting in your working directory, no cloud, no API key, no subscription, and not a single byte leaving the laptop. Painting a hundred more costs exactly nothing.
That folder is FLUX.2 Klein, quantized to 8-bit and running through mflux and Apple's MLX framework, and I spent an afternoon turning it into a Claude Code skill: a playbook that researches the subject, builds the prompt from templates, generates the image, and reports back. Claude Code itself did most of the typing while I made the decisions, which is how I build most things these days. The cover of this very post came out of that skill, and this article is the full setup, from the Hugging Face download to the prompt templates, with the real numbers and the things that went wrong along the way.
Why generate images locally on a Mac?
Local image generation is free per image, works offline, and keeps every prompt and every picture on your machine. Those three properties change how you use it: when a re-roll costs nothing, you stop rationing your attempts and start iterating the way you would with code.
With a hosted API there is always a meter running somewhere in your head. Locally, the only cost is a minute and a half of your Mac's time, so trying four seeds of the same idea is a normal move rather than a small expense. Privacy comes along for free as well, because a prompt that describes an unpublished blog post, or a family photo you want restyled, never leaves the laptop.
To be fair, if you want a point-and-click app, Draw Things and DiffusionBee already do local generation on a Mac very well. What I wanted was different: a generator my coding agent could drive, so that images become one more thing I can delegate in the same conversation that writes my tests and my prose.
What do you need to run FLUX.2 Klein locally?
You need an Apple Silicon Mac, Python, about 50 GB of free disk during setup, and the mflux package. FLUX.2 Klein is a distilled 9-billion-parameter model with open weights, and everything else in this guide is built on that one download.
The piece that makes this practical is mflux, a careful MLX port of the FLUX models. MLX is Apple's machine-learning framework, and it runs the model on the Mac's GPU through Metal with the weights sitting in unified memory, no separate graphics card involved. Installing it is one line:
pip install -U mfluxHow do you download FLUX.2 Klein from Hugging Face?
The weights live on Hugging Face as a gated repository, so the download has three steps: create a free Hugging Face account, accept the model license on the FLUX.2 Klein page, and authenticate your machine. This is the one part of the whole setup that needs a human, and it takes about two minutes.
Gated means the files exist publicly but Hugging Face will refuse the download until your account has clicked through the license. Once you have accepted it, log the machine in with hf auth login (or export an HF_TOKEN environment variable if you prefer tokens), and from then on the tools can pull the weights on your behalf:
hf auth login
# one time: download the weights and quantize them to 8-bit
mflux-save -m flux2-klein-9b -q 8 --path flux2-klein-9b-q8That second command does two jobs. It downloads the full-precision weights, which are around 32 GB, and then quantizes them locally to 8-bit, leaving a 17 GB folder on disk. The download is resumable if the connection drops, and the 32 GB cache can be deleted afterwards. My skill wraps all of this in a setup script that checks access up front, so a missing license acceptance stops the process immediately with instructions instead of failing an hour into a download.
One version note from experience: the quantized weights are coupled to the mflux version that produced them, so my skill pins mflux 0.17.5 and never re-quantizes at runtime. Quantizing on top of already-quantized weights only degrades them. From here, that quantized folder is what you generate with:
mflux-generate-flux2 \
--model flux2-klein-9b-q8 \
--base-model flux2-klein-9b \
--steps 8 --width 1024 --height 1024 \
--prompt "a red bicycle leaning against a blue wall, loose watercolor, soft morning light" \
--output ./red-bicycle.pngHow fast is FLUX.2 Klein on Apple Silicon?
On my machine it runs at roughly ten to eleven seconds per denoising step at 1024 by 1024, so the default eight steps finish in about a minute and a half. Four steps land in about 45 seconds and are enough for flat artwork like icons and stickers, while twelve steps help with stubborn compositions. Going beyond twelve is rarely worth the wait.
The reason such small step counts work at all is that Klein is a distilled model, built to reach a coherent image in a few steps where a full-size FLUX model wants twenty to fifty. That distillation is the whole trick that makes a laptop viable for this: clean faces, believable hands, and crisp detail in the time it takes to refill a coffee.
How I wired it into Claude Code as a skill
A working command line is nice, but the interesting part starts when your agent owns it. A Claude Code skill is essentially a playbook file plus a few helper scripts, and mine is about 80 KB of logic in a folder that also holds 27 GB of models. The trick is that the repository ships only the logic: one idempotent setup script rebuilds everything heavy, and every download lands in a temporary directory that is swapped into place atomically, so an interrupted download can never leave behind a half-written model that a later run would trust.
The part I care about most is what happens before any generation: the skill is required to ground its prompts in reality. If the request names a real person, building, city, or product, the agent researches what that thing actually looks like on the web before writing the prompt, because the instruction in the playbook is blunt:
Do not invent how something looks.
The enhanced prompt is shown to me for sign-off before a single step runs, which is the same review habit I use in my test-first workflow with Claude Code: the agent does the typing, and I approve the intent. After that, generation is fully offline.
How do the prompt templates work?
Every request is assembled from three parts: a content-kind scaffold that wraps the subject, a style that contributes its own cues, and defaults for size and step count that the kind carries with it. I wrote these into the skill as small tables during that same afternoon: eleven content kinds (illustration, photo, icon, infographic, logo, sticker, action figure, city diorama, pattern, storyboard, portrait), around forty-five styles grouped from painterly to cinematic, and fifteen ready-made photo-transform recipes for the viral requests like turning a portrait into a boxed action figure.
The scaffolds encode what each kind of image actually needs. An icon template asks for "bold minimal shapes, centered, generous margin, isolated on a plain solid white background", because that wording is what makes the later background removal and SVG trace come out clean. A flat sticker or logo runs at four steps because the extra refinement passes show nothing on flat shapes, while anything with faces gets the full eight. On top of the scaffold sits an enhancement checklist that fills in only the slots that apply: subject, action, setting, composition, lighting, color and mood, style, technical finish. And the whole thing is written as flowing prose, not the comma-separated tag soup we all learned from older tools, because FLUX.2's text encoder is a language model and reads sentences.
One subject, eight templates: the White Tower of Thessaloniki
The easiest way to show what the templates do is to hold the subject still and swap the template. So here is the White Tower, the round Ottoman-era tower on my city's waterfront, generated again and again by the same 17 GB folder, from one-line requests. Each prompt below is exactly what went to the model.
watercolor painting of the White Tower of Thessaloniki on the seafront promenade at golden hour, the round pale stone tower with its crenellated top rising over the bay, small figures strolling along the water, soft washes, visible paper texture, gentle color bleeds, hand-painted

a single White Tower of Thessaloniki icon, simple flat pictogram of the round crenellated tower, bold minimal shapes, centered, generous margin, isolated on a plain solid white background

a die-cut sticker of the White Tower of Thessaloniki, the round crenellated tower with a small blue sea wave at its base, bold flat colors, thick clean outline, slight drop shadow, isolated on a plain solid background

isometric 3D miniature diorama of the White Tower of Thessaloniki on a floating square tile, the round crenellated tower beside a tiny waterfront promenade with small trees, a bench and little people, soft claylike 3D render, pastel palette, soft studio lighting, plain pale background

Those four cover the everyday kinds. The style table is where the fun lives, so here are four more rows over the same subject, the ones that make people ask how a laptop did this. Each is still a single line: the style row's cues wrapped around the same tower.
hand-painted anime film still of the White Tower of Thessaloniki on the seafront promenade, a summer afternoon with strolling figures and gulls over the bay, soft Studio-Ghibli-esque watercolor backgrounds, gentle warm lighting, lush painterly detail, nostalgic

ukiyo-e Japanese woodblock print of the White Tower of Thessaloniki rising over a stylized bay, flat areas of color, bold outlines, stylized waves and clouds, visible woodgrain, Edo-period

pop art print of the White Tower of Thessaloniki, Warhol/Lichtenstein style, bold flat primary colors, Ben-Day halftone dots, thick black outlines, high contrast

LEGO brick version of the White Tower of Thessaloniki, built from white plastic interlocking bricks with a crenellated top, tiny minifigures on a waterfront baseplate, visible studs, glossy plastic

Eight images, one subject, and the only thing that changed between them is which template wrapped it. That is the entire idea: the templates carry the craft, so a request can stay one line long.
How do you get legible text in AI images?
Mostly, you don't get it from a small distilled model: FLUX.2 Klein paints lettering as texture and cannot spell reliably. The skill solves text in three tiers, and the honest way to show them is to ask for the same picture three ways: a vintage travel poster of a tower by the sea, with a large title reading "THESSALONIKI".
First, Klein itself, on its best behavior: one short word, a flat high-contrast poster style, twelve steps. It landed the title on the first seed here, which genuinely surprised me. This is the lucky tier, not the reliable one: it only works for a word or two in a flat layout, the skill still tells you to expect re-rolls, and the moment lettering gets longer or smaller it degrades into the decorative nonsense you saw on the ukiyo-e cartouches above.

The dependable tier is a second model. Z-Image Turbo is a 6-billion-parameter Apache-2.0 model that renders short text correctly as a matter of course, and the skill fetches it lazily the first time a request needs baked-in text, so nobody pays its 10 GB of disk without asking for it. The same poster request comes back with the title spelled right on the first seed, and its habits show at the edges: the big title is flawless, while the tiny mock-print it invented along the bottom border is illegible up close, which is exactly the pattern, text quality scales with text size.

And the guaranteed tier involves no model spelling at all: ask Klein for the poster with a deliberately blank banner where the title should go, then place real type on it with a small Pillow script. A slight blur and a touch of transparency let the lettering sit inside the picture instead of floating on top of it, and because it is an actual font, it is pixel-perfect every single time, which is what I use when the words are brand-exact or long.

What went wrong along the way
The most instructive bug was a shell quirk. I had batch runs where every generation died instantly with unrecognized arguments while the loop marched on looking perfectly healthy, because zsh does not word-split an unquoted variable, so a $FLAGS variable holding several flags was being passed as one bogus argument. The fix that stuck was writing the flags out explicitly, printing a progress marker per run, and verifying that the first output file actually appears before trusting the rest.
Unified memory taught me a scheduling rule: batches run sequentially, never in parallel, because two model processes fight over the same memory and everything slows to a crawl. Background removal had a subtle trap as well. Cutting out a subject that was generated on a white background can make white areas inside the subject transparent too, so the skill generates cutout candidates on a solid magenta or chroma green instead.
The last lesson was about review. An image that looks fine at full-frame scale can hide melted hands or garbled edges, so the skill crops the risky regions and inspects them at three times the size before calling an image done. That judgment pass matters more than any parameter, and it is the same discernment habit I described in AI fluency and the 4D framework: the agent produces, and you stay the editor.
Beyond generation: editing, vectors, and cutouts
The same setup covers most of what I used to need an online tool for. There is an edit mode that takes one or more reference images plus an instruction, which handles restyling a photo, combining references, and the whole family of playful transforms like turning a portrait into a boxed action figure or a plushie. A vectorizer turns flat generated artwork into SVG, which is amazing for icons and logos, though photographs come out as a mess of slivers, so I keep it for flat shapes. And the background remover produces transparent PNGs offline, with its models baked into the setup so nothing is downloaded at runtime.
Frequently asked questions
Is local AI image generation on a Mac really free?
Yes, after the one-time downloads the only costs are disk space and electricity. There is no API key, no quota, and no subscription. FLUX.2 Klein has open weights behind a free license acceptance on Hugging Face, and Z-Image Turbo is Apache-2.0.
How much disk space does FLUX.2 Klein need?
The 8-bit quantized model takes 17 GB on disk. Plan for about 50 GB free during setup, because the full-precision weights are downloaded first and quantized locally, and the download cache can be deleted afterwards.
How long does one image take?
On my Apple Silicon machine, about a minute and a half at the default eight steps and 1024 by 1024, or about 45 seconds at four steps for flat artwork. A first run after boot adds a few seconds of model loading.
Do you need a separate GPU to run FLUX.2 on a Mac?
No. MLX runs the model on the Apple Silicon GPU through Metal, and the weights live in the Mac's unified memory, which is exactly why this works on a laptop with no discrete graphics card.
Can you run Nano Banana locally?
No. Nano Banana is Google's closed-source image model and it only runs on Google's cloud, so every "run it locally" setup is really a local client calling the Gemini API. What you can run fully offline on a Mac is FLUX.2 Klein and Z-Image Turbo, and the skill's edit mode covers the viral Nano-Banana-style photo transforms, like the desk figurine and the boxed action figure, with no internet and no quota.
Can Claude Code generate images?
Not by itself, but it can drive any tool you wrap in a skill. Packaging a local generator as a Claude Code skill means the agent handles research, prompting, generation, and cleanup inside the same conversation as the rest of your work.
The takeaway
If you have an Apple Silicon Mac and 50 GB to spare, you can have free, private, offline image generation running this week, and the setup above is the whole recipe. The deeper shift for me is what happens when that capability belongs to the agent rather than to an app: images stop being a separate errand and become one more thing I can ask for, review, and approve without leaving my terminal.
I have been building things my whole life, from hundreds of small apps in my early developer years to the workflows I write about here, and the pattern keeps repeating: the tools get more capable, and the valuable part of my day moves further toward deciding and reviewing. The White Tower now sits on my disk in four styles, each with its seed and prompt recorded next to it. My Mac painted them all, and it can paint the next one before my coffee gets cold.