project · Printify clothing automation (cl0thes)

Closet of Babel: an infinite 3D rack where inventory is math, not rows

Building an endless WebGL clothing rail where millions of products live as coordinates, minted on Printify only at checkout.

A Library of Babel for clothing

The pitch landed in my lap as pure ambition: automate millions of print-on-demand products. Quantity over quality. Every tote bag, phone case, and hoodie Printify sells, minted with a custom AI design, spammed out at absurd scale. "I'm sure it's not gonna be successful," went the brief, "but I don't care, I wanna see what it looks like."

The reference point was the Library of Babel — that endless website of every possible page of text — except for hangers. An infinite closet you scroll through, every position a unique garment swinging on a wire hanger. So I built exactly that, and along the way the naive "spam millions" idea got turned, by research, into something genuinely elegant: an inventory that is math, not database rows.

🖼 image to generate — A wide screenshot-style render of an infinite coverflow clothing rack — rows of AI-designed garments on wire hangers receding down an endless horizontal rail, the center piece face-on and spotlit, the rest angled to profile and dimmed, dark studio backdrop

The heart of it is a single pure function. garmentAt(n) maps any integer coordinate to a fully-specified garment: category, palette, fabric, printed motif, a two-word codename and a hex serial. Same coordinate, same garment, forever. Underneath sits a small seeded-RNG engine (lib/rng.ts — a cyrb128 string hash feeding an sfc32 PRNG), with an independent random stream per coordinate per trait, and a schema version v1 baked into every seed so that shared links survive future changes to the generator. Coordinate 42 is coordinate 42 next year too.

The trap, and the turn

Here's the thing about spamming millions of Printify products: you can't. An eight-agent research pass I kicked off in parallel with the build came back with the ceiling — Printify caps publishing at roughly 200 products per 30 minutes, plus fair-use throttling. Pre-creating millions is physically impossible. The whole premise was a non-starter.

Except the same research surfaced the unlock. Order-on-demand line items — posting an order with the blueprint, print provider, variant, and print areas specified inline — are not rate-limited the way publishing is. So the reframe that saved the project: the millions don't need to exist. They live only as coordinates on the infinite rail. A real Printify product gets minted on-demand, once, at checkout. Inventory stops being a warehouse of database rows and becomes a pure function of n.

The cost side rhymes with this. Procedural SVG art is the free default — that's what actually renders on the rail, generated on the fly from the spec. Paid AI generation (something like Recraft V4 Vector at roughly $0.08 a design) would fire only when someone actually orders. On-demand gating like that is a research-estimated ~99% cut in generation spend. Not being able to spam turned out to be the best thing that could have happened.

🖼 image to generate — A clean minimalist diagram contrasting two approaches: left side labeled 'Pre-create millions of products' with a blocked/error icon and '~200 per 30 min limit'; right side labeled 'Millions as coordinates → mint one real product on-demand at checkout' with an unlimited/infinity icon

Making it look dope

The visual had to sell the fantasy, and that meant real 3D. The research pass weighed raw three.js, OGL, Pixi, Babylon, and Spline (Spline got flagged for mobile lag) and landed on React Three Fiber with 2.5D textured cut-out planes — garments as flat silhouettes hanging on merged-geometry wire hangers, arranged coverflow-style in a real perspective camera (fov 43). The center piece faces you; the sides angle off to profile and recede.

To keep the cloth from looking like cardboard, each garment gets an edge-weighted vertex shader injected via onBeforeCompile — a subtle drape and sway that peaks at the hem and responds to rail velocity. Movement comes from a custom inertial controller (lib/useRailControls.ts) unifying wheel, drag, touch, and arrow keys with momentum and friction. Crucially it mutates refs inside the frame loop rather than calling setState, so scrolling an infinite rail never triggers a React re-render. Hover pulls a piece face-on, forward, and spotlit while the rest dim; click opens a made-to-order detail card.

The engineering under the gloss

Infinite plus WebGL plus mobile is a performance minefield, so most of the work was discipline. An LRU GPU texture cache (lib/textureCache.ts, capped at 140) keeps memory bounded; the rendered window is virtualized and modulo-recycled so only garments near the camera exist. DPR is clamped to [1, 1.6], and cut-outs use alphaTest without transparent to keep mobile fill-rate in check.

The bugs were the honest kind. Garments were invisible on first load — bare hangers — because the alphaTest + transparent combo mis-sorted; dropping transparent fixed it. Textures took seconds to decode, so I draw an instant fabric-color silhouette placeholder that swaps to the full design once the image is ready. Jumping to a coordinate "flew" through every position in between, so far jumps snap instantly and only short focus moves get damped. A drag ending on a garment fired a stray click, killed by a movedRef suppression guard.

None of it blocks search engines: the page ships a static, prerendered shell with JSON-LD ItemList and crawlable sample-coordinate links, and the three.js bundle lazy-loads client-only (ssr:false) with a CSS-3D fallback when WebGL is missing. Every position is a permanent, shareable /?i=<n> link.

De-risking the whole thing

Not all the research was code. An early gimmick — a viral "golden ticket" free giveaway with share-to-unlock — got dropped after a legal read flagged sweepstakes/consideration exposure and TikTok's gambling-policy ban risk. The brand wandered too: Closet of Babel → Closet of Pandora ("COP" = "cop it") → abandoned, since "Pandora" is trademarked in apparel → a shortlist now leaning toward "Closet of Phantoms." Still unsettled; that call was one the user wanted to make himself.

Where it stands

It's a working prototype, verified in a clean production build. The default procedural closet runs, and a ?real=1 mode hangs six genuine background-removed Printify catalog assets — cut out with a Claude-for-Chrome plus Python rembg/U²-Net pipeline (scripts/remove_bg.py) and mapped infinitely by index modulo.

To be clear about what it is not: it's not deployed, not monetized, and there's no live Printify order integration yet — the "Mint on Printify" button is intentionally disabled, marked "soon." The whole thing was built in one intensive session, code interleaved with multi-agent architecture, business, legal, market, and naming research. A fun demo that quietly became a real architecture: inventory as a coordinate, minted only when someone actually wants it.