v0.1.0 · MIT · zero dependencies

Procedurally generate
SVG clouds.

A single seeded call returns a clean, standalone <svg> string built from minimal, smooth bezier geometry — deterministic per seed, dependency-free, and usable in both Node and the browser.

npm install cloudswg
Try the playground

Turn the knobs

Every control below maps to a real option. The cloud regenerates on each change — there is no debounce, because generating one takes well under a millisecond.

Type

Default viewBox 300×180

42

The same seed and options always produce the same bytes.

0.70

Turret count. At 0 the cloud grows none at all.

Size
Style
1.00
0.0px

Not a library option. cloudswg emits no filters, so you soften it yourself.

693 B 1 path
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 180" width="300" height="180">
  <path d="M 32.3,171 L 267.7,171 C 285.196,171 299.378,156.817 299.378,139.322 C 299.378,128.364 293.716,118.185 284.406,112.406 C 283.817,98.653 273.762,87.15 260.21,84.728 C 258.19,69.874 246.756,58.054 231.977,55.541 C 217.198,53.029 202.501,60.407 195.685,73.759 C 193.386,75.313 191.289,77.148 189.443,79.221 C 185.012,79.186 180.63,80.141 176.617,82.017 C 159.204,68.465 134.238,70.874 119.738,87.505 C 106.005,84.412 91.626,88.218 81.222,97.701 C 63.558,88.428 41.735,94.243 31.027,111.076 C 14.981,111.758 2.324,124.964 2.324,141.024 C 2.324,157.579 15.745,171 32.3,171 Z" fill="#ffffff"/>
</svg>

Why it stays out of your way

Deterministic by seed

The same seed and options return the same string, byte for byte. Snapshot it, cache it, or regenerate it on another machine and get the identical cloud.

Zero dependencies

Nothing in the dependency tree, nothing to audit. Ships ESM and CJS with hand-written .d.ts types, and marks itself side-effect free so unused generators tree-shake away.

Small enough to inline

The whole library minifies to roughly 8 kB, and a generated cumulus is about 1 kB of markup — small enough to paste straight into a template.

Node and browser

Take the svg string anywhere — write it to a file, render it server-side, or call element() in the browser for a live SVGSVGElement.

Nothing baked in

No embedded stylesheet, no defs, no filters, no generated ids. Just paths in a viewBox, so it composes with your CSS instead of fighting it.

Three real morphologies

Cumulus turrets on a flat base, stratus ribbons around a Fourier spine, and hooked cirrus uncinus wisps — each with its own response to puffiness.

Usage

Install it, call it, and you have a string. There is no fourth step.

Install

shell
npm install cloudswg

Generate

js
import { generateCloud } from 'cloudswg'

const { svg } = generateCloud({ type: 'cumulus', seed: 42, puffiness: 0.7 })
// → '<svg xmlns="..." viewBox="0 0 300 180" ...>...</svg>'

Seeded or random

Omit seed for a new cloud on every call.

js
generateCloud({ type: 'cumulus' })            // random every call
generateCloud({ type: 'cumulus', seed: 42 })  // byte-identical, every time

A DOM node instead

element() uses DOMParser, so it is browser-only and throws in Node. Use svg to write files or render server-side.

js
const cloud = generateCloud({ type: 'stratus', seed: 7 })
document.body.appendChild(cloud.element())    // SVGSVGElement

Per-type generators

js
import { generateCumulus, generateStratus, generateCirrus } from 'cloudswg'

// Same options minus `type`, and tree-shakeable — import one, ship one.
const { svg } = generateCumulus({ seed: 42, puffiness: 0.7 })

TypeScript

ts
import type {
  CloudOptions,     // everything you can pass to generateCloud
  CloudTypeOptions, // Omit<CloudOptions, 'type'> — for the named generators
  CloudResult,      // { svg: string; element(): SVGSVGElement }
  CloudType,        // 'cumulus' | 'stratus' | 'cirrus'
  CloudStyle,       // { fill?, stroke?, strokeWidth?, opacity? }
} from 'cloudswg'

Options

OptionTypeDefaultNotes
type'cumulus' | 'stratus' | 'cirrus''cumulus'Cloud morphology.
seednumberrandomSame seed ⇒ identical output.
puffinessnumberfrom seedClamp to 0–1. Meaning is per-type: turret count, band thickness, or hook strength. Omit it and the seed picks a value.
width / heightnumberper typeSets the viewBox and the width/height attributes. cumulus 300×180, stratus 1200×120, cirrus 400×200.
styleCloudStyle{ fill: "white" }fill, stroke, strokeWidth, opacity — any CSS color. Blur belongs in your stylesheet.