Export

Embed and export

For a single mood the studio is quicker — you are already looking at the mood there. The integration guide covers everything below in full, including versioning and the update policy.

Embed the bundle

Two files go into the app: the runtime and the spec. The app renders immediately from the embedded copy and picks up a newer spec later — not on every launch.

The reason for the split: app stores allow data to be downloaded but not executable code. A new mood can therefore ship without a store release.

Packages and sources

The package is not on the public npm registry, so it is served here as a tarball that npm i <url> installs directly. SwiftUI and the vendorable React Native drop are the repo's own sources.

Ship the runtime and spec inside the app and update the spec over the air. This is the shape you want in production.

ts
// 1. Ship these two files inside your app.
//    1.9.0 runtime + spec, no network needed on first launch.
//      kluuu-mascot-1.9.0.js     (ESM, zero imports)
//      kluuu-spec-1.9.0.json     (moods + geometry)

import {
  createMascot,
  createSpecClient,
  installSpec,
  applySpec,
  confirmSpecHealthy,
} from './kluuu-mascot-1.9.0.js'
import embedded from './kluuu-spec-1.9.0.json'

// 2. Install the embedded copy before the first frame. Every mascot built
//    after this renders from it, and nothing has touched the network yet.
installSpec(embedded)

const client = createSpecClient({
  baseUrl: 'https://kluuuapi.glade.studio',
  embedded,
  storage: localStorage,          // AsyncStorage / UserDefaults on native
  // Off by default: reaching out from someone else's app on their users'
  // data plan is not a decision a library gets to make for them.
  policy: { enabled: true },
  // Optional, and strongly recommended. Without it an unsigned or forged
  // index is accepted on its own say-so.
  publicKeys: { k1: '<32-byte base64 — node tools/keygen.mjs k1>' },
})

const mascot = createMascot(document.querySelector('#slot')!, { mood: 'idle' })

// 3. Tell the client this build renders. Until you do, a stored spec is
//    discarded after two launches — that counter is what stops a bad spec
//    bricking the app on every start.
confirmSpecHealthy()

// 4. Check occasionally. Not on every launch: once per 24 h, jittered per
//    install, skipped on metered connections. applySpec installs the new
//    tables and retargets this instance, springing across rather than cutting.
client.checkForUpdate().then((r) => {
  if (r.updated) applySpec(mascot, client.current())
  else console.log('no update:', r.reason)
})

The logo

The rig at every default: no lean, no squash, no droop, brand mint, both eyes open, nothing moving. The mark itself, not a still lifted out of an animation — and always transparent, whatever the controls further down are set to.

Frame
Fitted fills the square, which is what the icon sizes are for. Artboard is the registered master untouched — the mark sits in the middle band, because that canvas is sized for poses.

SVG

Identical geometry in every file. The size is only the intrinsic width and height a consumer falls back to when nothing tells it otherwise — a print layout, an <img> with no CSS, an editor's import dialog — so none of these is lossier than another.

PNG

Rasterised from that same vector, transparent, and supersampled below 256 px — a direct 16 px render drops the thin fold strokes entirely, and the folds are the whole reason the silhouette reads as a brain.

Export many moods

One file per selected mood — a still at frame zero of its idle animation, or a looping GIF of the idle itself. Files arrive one after another, not as an archive.

Size1024 px

Edge length of the square output.

Format
SVG ignores the size. PNG is one still; GIF is the idle animation, looped.
Colour
Mood tint uses each mood's own colour; brand green keeps the logo mint.
Background
Painted into the file behind the mascot.

Positive

Calm

Cognitive

Low

Agitated

Special

Product

Onboarding

Referral

Creatures

Tiers

1 of 90 selected