beantology
v0.1.0
Published
Seeded, expressive React avatar components and motion primitives.
Maintainers
Readme
Beantology
Beantology is a typed React motion SDK for building seeded, expressive bean avatars. Each Bean combines a deterministic identity with a research-oriented motion vocabulary: thinking, searching, reading, comparing, calculating, insight, uncertainty, recall, and more.
Install
npm install beantologyReact 18 or newer is required. Import the package stylesheet once in your application:
import 'beantology/styles.css';Basic usage
Bean is self-contained. Every instance owns an independent motion and interaction controller by default.
import { Bean, createBeanAppearance } from 'beantology';
import 'beantology/styles.css';
const appearance = createBeanAppearance('portfolio-42');
export function ResearchAvatar({ state = 'thinking' }) {
return (
<Bean
{...appearance}
state={state}
seed="portfolio-42"
meta={{ confidence: 58, urgency: 38, depth: 68, activity: 46 }}
pointer={{ radius: 100 }}
size={96}
/>
);
}Clicking or pressing Enter/Space bonks only that Bean. Pointer gaze is opt-in; its influence fades across the configured radius. Nearby Beans can both respond when their proximity fields geometrically overlap, but their controllers remain independent.
Set interactive={false} for a display-only avatar. It will use image semantics and leave the tab order.
Deterministic identities
createBeanAppearance(seed) deterministically selects the palette, body, visor, proportions, eye spacing, asymmetry, and emergence side. The same seed and package version produce the same identity.
const appearance = createBeanAppearance('analyst-7');
<Bean {...appearance} state="reading" seed="analyst-7" />;The renderer also accepts custom palette, body, and visor objects:
<Bean
palette={{ background: '#6f8a72', body: '#49352f', face: '#f3e5c7' }}
shape={{ radius: [50, 46, 58, 42], vertical: [44, 52, 48, 56] }}
visor={{ radius: '50%', rotate: -4, width: 72, height: 44 }}
/>Explicit synchronization
Independent controllers are the default. Wrap Beans in BeanMotionProvider only when a product intentionally needs synchronized motion and interaction.
import { Bean, BeanMotionProvider } from 'beantology';
<BeanMotionProvider state="searching" seed="shared-search">
<Bean size={240} />
<Bean size={64} />
</BeanMotionProvider>;Controlled composition
Use useBeanMotion when another application context needs to own the motion value.
const { motion, interactionProps, pointerTargetRef, triggerImpact } = useBeanMotion({
state,
seed,
meta,
pointer: { radius: 100 },
});
<Bean
ref={pointerTargetRef}
motion={motion}
interactive
{...interactionProps}
/>;triggerImpact(clientX, clientY, element) supports non-pointer input systems.
States
The built-in vocabulary is exported as BEAN_STATES with human-readable BEAN_STATE_LABELS:
idle, thinking, searching, reading, insight, comparing, calculating, uncertain, contradiction, rereading, skimming, deepReading, findingNumber, backtracking, waiting, streaming, recall, and conviction.
Unknown JavaScript state values safely fall back to idle; TypeScript rejects them at compile time.
Public API
BeanBeanMotionProvideruseBeanMotionanduseBeanMotionContextcreateBeanAppearanceBEAN_PALETTES,BEAN_SHAPES, andBEAN_VISORSBEAN_STATES,BEAN_STATE_LABELS, andBEAN_NARRATIVE_CHAINSDEFAULT_BEAN_META,DEFAULT_BEAN_MOTION, andDEFAULT_BEAN_SEED
The package ships ESM, CommonJS, TypeScript declarations, SSR-safe initial rendering, keyboard interaction, and reduced-motion CSS.
Repository
Source, issues, and the live studio are maintained at ayshptk/beantology.
License
MIT
