@bitrise/spaceship-avatar
v0.1.1
Published
Procedurally generated, brand-aligned spaceship avatars for Bitrise workspaces and users
Readme
@bitrise/spaceship-avatar
Procedurally generated, brand-aligned spaceship avatars for Bitrise workspaces and users.
Give it a name and it draws a spaceship that is always the same for that name and almost always different from everyone else's — a friendlier placeholder than two initials on a coloured square.
- Storybook: https://storybook.services.bitrise.dev/projects/spaceship-avatar/production/
- Interactive demo: https://storybook.services.bitrise.dev/projects/spaceship-avatar/production/demo/index.html
Install
npm install @bitrise/spaceship-avatarReact 18 or newer is the only peer dependency. There is no theme provider to set up: the SVG uses literal brand colours, so it looks the same inside Bitkit, in a plain React tree, or exported to Figma.
Usage
import { SpaceshipAvatar } from '@bitrise/spaceship-avatar';
<SpaceshipAvatar name={workspace.name} size={40} />;As the fallback of a Bitkit avatar — it renders whenever the workspace has no uploaded image:
import { BitkitAvatar } from '@bitrise/bitkit-v2';
import { SpaceshipAvatar } from '@bitrise/spaceship-avatar';
<BitkitAvatar
variant="image"
size="40"
name={workspace.name}
src={workspace.avatarUrl ?? ''}
fallback={<SpaceshipAvatar name={workspace.name} size="100%" />}
/>;API
<SpaceshipAvatar name size? …svgProps />
| Prop | Type | Default | Description |
| ------ | ------------------ | ------- | --------------------------------------------------------------------------- |
| name | string | — | The seed. Surrounding whitespace is ignored. Also used as the aria-label. |
| size | number \| string | 48 | Width and height. Use "100%" to fill a sized container. |
Any other SVG attribute (className, style, aria-*, …) is passed to the root <svg>.
generateSpaceship(name): Spaceship
The pure, deterministic part: turns a name into a plain description of the ship (archetype, traits, colours, particles). Useful for tests, analytics, or rendering the same ship somewhere else.
<SpaceshipGraphic ship label size? …svgProps />
Renders a Spaceship description directly — for curated or hand-tweaked ships that should not come from a name.
How a ship is built
The trimmed name is hashed (cyrb53-style) into a seeded mulberry32 generator. The generator picks, in order:
- Shared traits — hull tint (lavender-led), accent, glass, brand gradient backdrop, engine count (1–3), exhaust glow (ice-led), tilt, pixel particles and an optional (ringed) planet.
- An archetype, each equally likely, and that archetype's own traits:
| Archetype | Traits | | --------- | -------------------------------------------------------------------------------------------- | | rocket | nose, proportions, wing (6 kinds), wing stripe, cockpit (5 kinds), fins, hull decal | | saucer | disc thickness, dome (glass bubble, low, tower), rim lights or band, landing legs, tractor beam | | pod | rounded-square / gumdrop / bubble body, window, side nacelles / bottom thrusters / orbital ring, legs or fins, antenna, stripe | | lander | faceted or round cabin, 3 or 4 legs, gold foil, dish antenna | | ring | one or two rotating rings, sphere or drum core, ring lights |
The rocket is a port of the brand-aligned reference artwork; the other archetypes follow the same style rules — pale tinted hulls with soft shading, dark glass with a coloured glint, ribbed black engine blocks, glowing exhaust, brand gradient backdrops with spatial squares.
Changing the generator changes existing avatars. Any change to the order or ranges of random picks gives
every name a new ship, so treat such changes as breaking (feat!:) and release them as a major version.
Development
npm install
npm run storybook # Storybook on http://localhost:6007
npm run dev # interactive demo on http://localhost:5173
npm test # Vitest
npm run lint # ESLint (@bitrise/eslint-plugin), also formats with --fix
npm run type-check # tsc --noEmit
npm run build # library build into dist/ (ESM + .d.ts)
npm run build:site # Storybook + demo into storybook-static/Node.js version: see .tool-versions.
Releasing
Releases are automated and follow semantic versioning driven by Conventional Commits:
| Commit | Release |
| ---------------------------------------- | ------- |
| fix: … | patch |
| feat: … | minor |
| feat!: … or a BREAKING CHANGE: footer | major |
Every push to main runs the Bitrise release workflow, which uses release-it
to pick the version from the commits since the last tag, update CHANGELOG.md, tag vX.Y.Z, publish to npm,
create a GitHub release, and deploy the production Storybook and demo. Pull requests run the ci workflow and
get their own Storybook and demo, linked in a PR comment.
Bitrise setup
The bitrise.yml in this repository is the source of truth. The Bitrise app needs these secrets:
| Secret | Used for | Expose to PRs |
| ----------------------------- | -------------------------------------------------------------- | ------------- |
| NPM_PUBLISH_TOKEN | publishing @bitrise/spaceship-avatar (shared workspace secret) | no |
| GH_TOKEN | GitHub release, commit status, Storybook link comment on PRs | yes |
| STORYBOOK_GCP_DEPLOY_KEY | uploading Storybook and the demo to the shared Storybook bucket | yes |
The release workflow pushes the release commit and tag back to main, so the Bitrise SSH key needs write access
to the repository, and branch protection must allow it (the commit is marked [skip ci]).
License
MIT © Bitrise
