How to batch svg blob generation for design system integration
- Step 1Fetch the schema — Call
GET /api/v1/tools/svg-blob-generatorwith your API key. The response lists the three options (blobPoints,blobColor,blobSmoothing) with their ranges and notes that the tool is generative and runner-backed. Build your payloads against that shape. - Step 2Pair the runner — Install and start
@jadapps/runner(see the runner docs). It listens on127.0.0.1:9789. The hosted/runendpoint deliberately returns 400 with pairing instructions — generation actually happens on your machine via the runner, so nothing leaves your network. - Step 3Define the blob family — Decide the constants for your system: a fixed
blobPoints(e.g. 7), a fixedblobSmoothing(e.g. 0.45), and a colour list drawn from your design tokens. These constants are what make the blobs look related; only colour (and the inherent random jitter) varies. - Step 4Loop and POST — For each colour, POST
{ "blobPoints": 7, "blobColor": token, "blobSmoothing": 0.45 }tohttp://127.0.0.1:9789/v1/tools/svg-blob-generator/run. Each response is one SVG with a single<path>. Because there is no seed, every call yields a fresh shape even with identical params — that is the source of variety here. - Step 5Save and commit the SVG files — Write each response to a versioned asset (e.g.
blobs/blob-01.svg). The committed file IS your reproducibility: you can always re-render the exact shape from the file, but never from the parameters. Re-running the loop produces a different set. - Step 6Wrap as components — Build a
BlobBackground/BlobMaskcomponent that imports a blob by index. To recolour later without changing shape, post-process the committed SVG with svg-hex-swapper instead of regenerating (which would change the shape).
Runner payload — the three options
These are the only fields the runner accepts for this tool. Ranges from the schema; web-UI availability noted because batch is the only way to reach two of them fully.
| Field | Type / range | Default | Web UI? |
|---|---|---|---|
blobPoints | integer 3–12 | 6 | Slider 3–10 only |
blobColor | CSS colour string | #6366f1 | Picker (hex) |
blobSmoothing | number 0.1–1 (step 0.05) | 0.4 | Not exposed (fixed 0.4) |
Building a consistent blob family
Fix the structural options, vary the colour. The random ±20% radius jitter supplies shape variety automatically.
| Goal | Hold constant | Vary | Result |
|---|---|---|---|
| Card accents | blobPoints: 6, blobSmoothing: 0.4 | blobColor per brand token | Six recognisably-sibling card shapes |
| Avatar masks | blobPoints: 8, blobSmoothing: 0.5 | nothing (re-run for variety) | Wavier shapes, same character, used as clip-paths |
| Morphable loader pair | blobPoints: 7, blobSmoothing: 0.45, blobColor | nothing — generate twice | Two same-count paths that morph cleanly |
Cookbook
Runner-driven recipes. JAD's API is upload-free, so every call goes to your local runner at 127.0.0.1:9789 — the SVG is produced on your machine. Inputs and outputs never touch JAD servers.
Fetch the schema first
Confirm the option shape before you loop. The response marks the tool generative and runner-backed.
curl -s https://jadapps.example/api/v1/tools/svg-blob-generator \
-H 'Authorization: Bearer $JAD_API_KEY'
# → { ..., "input": { "isGenerative": true,
# "options": [
# {"name":"blobPoints","min":3,"max":12,"default":6},
# {"name":"blobColor","type":"color","default":"#6366f1"},
# {"name":"blobSmoothing","min":0.1,"max":1,"default":0.4}
# ] } }Generate one blob via the runner
POST the payload to the paired local runner. The body is the generated SVG with a single path.
curl -s http://127.0.0.1:9789/v1/tools/svg-blob-generator/run \
-H 'Content-Type: application/json' \
-d '{"blobPoints":7,"blobColor":"#8b5cf6","blobSmoothing":0.45}'
# → <svg viewBox="0 0 400 400" width="400" height="400">
# <path d="M…C…Z" fill="#8b5cf6"/>
# </svg>Loop your colour tokens into a library
Fix Points and smoothing; iterate the palette. Each file is committed and becomes the source of truth — re-running would give different shapes.
for color in 6366f1 8b5cf6 ec4899 14b8a6 f59e0b; do
curl -s http://127.0.0.1:9789/v1/tools/svg-blob-generator/run \
-H 'Content-Type: application/json' \
-d "{\"blobPoints\":6,\"blobColor\":\"#$color\",\"blobSmoothing\":0.4}" \
> "src/assets/blobs/blob-$color.svg"
done
git add src/assets/blobs && git commit -m 'Add blob library'Generate a morphable pair for a loader
Two runs at the same Points value produce same-command-count paths that morph cleanly with the CSS d property — perfect for a breathing skeleton.
curl -s …/svg-blob-generator/run -d '{"blobPoints":7,"blobColor":"#e5e7eb"}' > a.svg
curl -s …/svg-blob-generator/run -d '{"blobPoints":7,"blobColor":"#e5e7eb"}' > b.svg
# extract each <path d="…"> and drop into @keyframes:
# 0%,100% { d: path('<from a.svg>'); }
# 50% { d: path('<from b.svg>'); }Recolour without changing shape
Regenerating changes the shape (no seed). To restyle a committed blob, swap its colour with svg-hex-swapper instead of re-running the generator.
# keep the exact shape, change indigo → teal: # paste blob-6366f1.svg into /svg-tools/svg-hex-swapper # map #6366f1 → #14b8a6 # → identical path, new fill
Edge cases and what actually happens
Re-running the same payload to 'reproduce' a blob
failThere is no seed parameter. Two POSTs with the identical body return two different shapes because the radius jitter is Math.random(). The only reproducible artefact is the committed SVG file — store the file, not the parameters, when you need the exact shape again.
Expecting `blobSmoothing` to match the website
ExpectedThe web UI has no smoothing control and is fixed at 0.4. If you batch with a different blobSmoothing, your library's curve character will differ from anything art-directed in the browser. Pick one smoothing value and use it everywhere for consistency.
POSTing to the hosted /run endpoint
400The hosted https://…/api/v1/tools/svg-blob-generator/run intentionally returns 400 with pairing instructions — JAD never accepts uploads or runs jobs server-side. Generation happens on the paired runner at 127.0.0.1:9789. Point your loop at the runner endpoint, not the hosted one.
Missing or invalid API key on the schema fetch
401GET /api/v1/tools/svg-blob-generator validates the API key first and returns 401 if it is missing or invalid. The generation itself runs locally via the runner, but the schema endpoint (used to build payloads) is authenticated.
blobPoints above 12 or below 3
invalid optionThe schema constrains blobPoints to 3–12; values outside that are rejected by option validation. Keep batch values inside the range. Twelve is already very wavy — most design-system families sit at 6–8.
Rate limit hit during a large batch
429The schema endpoint and the hosted API enforce a per-key hourly rate limit and return 429 with a reset time when exceeded. The actual generation runs locally and is not metered by file content, but pace your schema fetches and any hosted calls; back off on 429.
Varying point count across the family
inconsistent setMixing blobPoints values across the library makes the shapes look unrelated and breaks cross-blob morphing (different command counts). Fix one Points value per family; vary colour and rely on the random jitter for shape variety.
Committing all 400×400 blobs as-is
PreservedEach output is a fixed 0 0 400 400 viewBox with one <path>. That is fine — they scale via the viewBox. If you want them trimmed or re-centred, post-process with svg-responsive-wrapper; to shave bytes, run svg-pro-minifier.
Wanting gradient-filled blobs in the batch
By designThe generator only emits solid fill. A batch of gradient blobs requires a post-process step: inject a <defs> gradient and rewrite fill to url(#id) in your script, or template the SVG. The runner will not produce gradients on its own.
Treating the runner output as multi-shape
ExpectedEach call returns exactly one blob (one <path>). To assemble many into a single asset (e.g. an icon-style sheet), collect the responses and combine them with svg-sprite-builder rather than expecting the generator to batch internally.
Frequently asked questions
Is there an API to generate blobs?
Yes, via the runner. GET /api/v1/tools/svg-blob-generator returns the option schema; you then POST payloads to http://127.0.0.1:9789/v1/tools/svg-blob-generator/run on your paired @jadapps/runner. JAD's hosted /run endpoint deliberately returns 400 — generation runs locally so nothing leaves your network.
Can I make blobs reproducible across runs?
Not from parameters — there is no seed, so identical payloads return different shapes. The reproducible artefact is the generated SVG file. Commit the files to version control; to 'reproduce' a blob, re-render the saved file, and to restyle it, edit the file (e.g. swap colours) rather than regenerating.
How do I keep a blob library looking consistent?
Fix the structural options — one blobPoints value (e.g. 7) and one blobSmoothing (e.g. 0.45) — for the whole family. Vary only blobColor, drawn from your design tokens. The built-in ±20% radius jitter then supplies shape variety while every blob still reads as a sibling.
Can I set smoothing in a batch even though the website can't?
Yes — that is one of the reasons to batch. blobSmoothing (0.1–1) is a real schema option that the web UI does not surface; the runner accepts it. Higher values give looser, rounder curves; lower values pull the curve tighter to the anchors. Pick one value and apply it across the family.
What is the maximum blobPoints I can pass?
12. The schema constrains blobPoints to 3–12 (the web slider only goes to 10). Values outside the range are rejected by option validation. For design systems, 6–8 is the usual sweet spot; 10–12 is very wavy and best reserved for bold accents.
How do I turn the library into React components?
Import each committed SVG (or its d value) and build a BlobBackground/BlobMask that takes an index prop. To generate JSX directly from a blob SVG, run it through svg-to-jsx. Keep recolouring out of regeneration — swap colours on the saved file with svg-hex-swapper.
Can I build a skeleton-loader animation from a batch?
Yes. Generate two blobs at the same Points value so their paths share a command count, then morph between them with the CSS d property for a subtle breathing skeleton — more interesting than a linear shimmer. See the animation guide for the keyframe pattern.
Does batching expose my data to JAD servers?
No. Blob generation needs no input file, and the runner executes locally on 127.0.0.1:9789. The only authenticated hosted call is the schema fetch, which carries no design data. The generated SVGs stay on your machine.
How do I combine many blobs into one file?
The generator returns one blob per call. Collect the responses and merge them with svg-sprite-builder to produce a single referenceable asset, or keep them as individual files for per-component import — whichever your build prefers.
Can I add gradients to a whole batch?
Only as a post-process. The runner emits solid-fill paths; to gradient-fill them, your script must inject a <defs> <linearGradient> and rewrite each path's fill to url(#id). Templating the output SVG is the cleanest way to apply one gradient across the family.
Will I hit a rate limit batching hundreds of blobs?
The local runner generation is not metered by content, but the hosted schema/API endpoints enforce a per-key hourly limit and return 429 when exceeded. Fetch the schema once, cache it, and loop against the local runner — that keeps you well clear of the hosted limit.
Do I need to regenerate to change a blob's colour later?
No — and you should not, because regenerating changes the shape (no seed). Edit the committed file instead: svg-hex-swapper maps the old fill to a new one and leaves the path untouched, so the shape is preserved exactly.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.