planet-avatar
v0.1.0
Published
Deterministic planet-style SVG avatars for vanilla JS, React, and Vue.
Readme
Planet Avatar turns any string or number seed into a stable, self-contained SVG planet. It is useful for user avatars, team members, account images, activity feeds, placeholders, and product UI where the same identity should always render the same visual.
Website: http://planet-avatar.vikingz.me/
Features
- Deterministic output from any
seed - Self-contained SVG strings with no canvas runtime or image assets
- Vanilla JavaScript core API
- Thin React and Vue adapters
- Built-in planet variants:
void,drift,mira,flux,luna,orbit,sol - Optional custom palettes, rings, backgrounds, sizes, and accessible titles
- ESM, CommonJS, and TypeScript declaration output
Install
npm install planet-avatarReact and Vue are optional peer dependencies. Install only the framework adapter you use.
Quick Start
import { createPlanetAvatar } from 'planet-avatar'
const svg = createPlanetAvatar({
seed: 'viking',
size: 128,
variant: 'orbit',
rings: true,
title: 'Viking avatar'
})
document.querySelector('#avatar')!.innerHTML = svgUse the DOM helper when you want Planet Avatar to mount directly into an element:
import { mountPlanetAvatar } from 'planet-avatar'
mountPlanetAvatar(document.querySelector('#avatar')!, {
seed: 'nova-42',
size: 96,
title: 'Nova avatar'
})Core API
import {
createPlanetAvatar,
createPlanetAvatarDataUri,
mountPlanetAvatar,
VARIANT_NAMES,
VARIANTS
} from 'planet-avatar'createPlanetAvatar(options)
Returns a complete SVG string.
const svg = createPlanetAvatar({
seed: 'atlas',
size: 160,
variant: 'luna'
})createPlanetAvatarDataUri(options)
Returns a data:image/svg+xml URI for image tags or CSS.
const src = createPlanetAvatarDataUri({
seed: 'atlas',
size: 160
})mountPlanetAvatar(target, options)
Renders the SVG into an existing element.
mountPlanetAvatar(element, {
seed: 'atlas',
size: 160
})Options
type PlanetAvatarOptions = {
seed: string | number
size?: number
variant?: 'auto' | 'void' | 'drift' | 'mira' | 'flux' | 'luna' | 'orbit' | 'sol'
palette?: 'auto' | string[]
rings?: boolean | 'auto'
background?: 'transparent' | string
title?: string
}| Option | Default | Description |
| --- | --- | --- |
| seed | required | Identity input. The same seed and options always produce the same SVG. |
| size | 128 | SVG width and height. |
| variant | auto | Named visual style or deterministic automatic selection. |
| palette | variant palette | Custom color array. Missing colors fall back to the active variant. |
| rings | variant setting | Force planet rings, disable them, or use auto. |
| background | transparent | SVG background fill. Use a CSS color string. |
| title | none | Accessible SVG title. When omitted, the SVG is aria-hidden. |
Variants
import { VARIANT_NAMES } from 'planet-avatar'
console.log(VARIANT_NAMES)
// ['void', 'drift', 'mira', 'flux', 'luna', 'orbit', 'sol']Use variant: 'auto' when you want the seed to choose a stable preset. Use a named variant when product art direction matters.
React
import { PlanetAvatar, usePlanetAvatar } from 'planet-avatar/react'
export function Profile() {
const svg = usePlanetAvatar({ seed: 'viking', size: 96 })
return (
<>
<PlanetAvatar seed="viking" size={96} variant="orbit" title="Viking avatar" />
<output>{svg.length}</output>
</>
)
}The React adapter exports:
PlanetAvatarusePlanetAvatarPlanetAvatarProps
Vue
<script setup lang="ts">
import { PlanetAvatar } from 'planet-avatar/vue'
</script>
<template>
<PlanetAvatar seed="viking" :size="96" variant="orbit" title="Viking avatar" />
</template>The Vue adapter exports:
PlanetAvatarusePlanetAvatar
Accessibility
Pass title when the avatar conveys identity or content. Planet Avatar will render a <title> and connect it with aria-labelledby.
When title is omitted, the generated SVG uses aria-hidden="true" so it behaves as decorative artwork.
Development
npm install
npm run checkCommon scripts:
| Script | Description |
| --- | --- |
| npm run build | Build ESM, CJS, sourcemaps, and declarations with tsup. |
| npm run typecheck | Run TypeScript without emitting files. |
| npm run test | Run Vitest tests. |
| npm run check | Run typecheck, tests, package build, and docs build. |
| npm run docs:dev | Start the Astro/Starlight docs site. |
| npm run docs:build | Check and build the docs site to docs/dist. |
| npm run docs:preview | Preview the built docs site. |
| npm run release:pack | Dry-run the npm tarball contents. |
| npm run release:dry | Dry-run npm publish. |
| npm run release:publish | Publish the package with public access. |
| npm run pages:preview | Build docs and run Cloudflare Pages locally with Wrangler. |
| npm run pages:deploy | Build docs and deploy docs/dist to Cloudflare Pages. |
Repository Layout
src/core Core SVG generator, palettes, random helpers, and types
src/react React component and hook
src/vue Vue component and composable
docs/src Astro/Starlight documentation site and landing page
docs/public Static docs assets, including logo.svg and favicon.svg
examples Vanilla, React, and Vue starter examples
tests Core and adapter testsPublishing
Before publishing:
npm run check
npm run release:pack
npm run release:dryThen publish:
npm run release:publishCloudflare Pages
Deploy the docs site with:
npm run pages:deployThe script builds the docs site first, then deploys docs/dist using Wrangler:
npx wrangler pages deploy docs/dist --project-name planet-avatarLicense
MIT
