npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kids-games/core

v1.0.0

Published

Shared framework for Kids Corner games — voice personas, audio playback, celebrations, UI components, and design tokens

Readme

@kids-games/core

Shared framework for Kids Corner educational games (ages 2-6). Provides voice personas with pre-generated TTS audio, sound effects, celebration animations, reusable React components, and design tokens.

Installation

npm install @kids-games/core

Peer dependencies (install if not already present):

npm install react@^19 react-dom@^19

Modules

The package is split into five independently importable modules:

| Module | Import | Description | |--------|--------|-------------| | Voice | @kids-games/core/voice | Persona system, audio playback, React provider & hooks | | SFX | @kids-games/core/sfx | Synthesized sound effects via Web Audio API | | Celebrations | @kids-games/core/celebrations | Confetti particle system with physics | | Components | @kids-games/core/components | Ready-to-use React UI components | | Tokens | @kids-games/core/tokens | Design tokens (colors, spacing, touch targets) |


Voice

Five kid-friendly personas, each mapped to an OpenAI TTS voice with a Web Speech API fallback:

| Persona | Voice | Character | |---------|-------|-----------| | Sunny | shimmer | Warm, encouraging guide | | Bloop | fable | Silly, playful buddy | | Maple | nova | Calm, nurturing mentor | | Fizz | echo | Energetic, excited hype | | Pip | alloy | Gentle, curious explorer |

Provider setup

Wrap your app (or game layout) with KidsAudioProvider:

import { KidsAudioProvider } from "@kids-games/core/voice";

export default function Layout({ children }) {
  return (
    <KidsAudioProvider storagePrefix="color-mixer" audioBasePath="/audio">
      {children}
    </KidsAudioProvider>
  );
}

Hooks

import { useVoice, usePersona, useSoundEffects, useCelebrate } from "@kids-games/core/voice";

function GameScreen() {
  const { playPhrase, muted, toggleMute } = useVoice();
  const persona = usePersona("sunny");
  const { playCorrect, playIncorrect } = useSoundEffects();
  const celebrate = useCelebrate("sunny");

  const handleAnswer = (correct: boolean) => {
    if (correct) {
      playCorrect();
      celebrate("big");
      playPhrase("well-done", "sunny");
    } else {
      playIncorrect();
      playPhrase("try-again", "sunny");
    }
  };

  return <button onClick={() => handleAnswer(true)}>Answer</button>;
}

Persona data

import { PERSONAS, getPersona, getRandomPhrase } from "@kids-games/core/voice";

const sunny = getPersona("sunny");
// { name: "Sunny", openaiVoice: "shimmer", ... }

const phrase = getRandomPhrase("sunny", "celebration");
// Random celebration phrase from Sunny's pool

SFX

Synthesized sound effects using the Web Audio API. No audio files needed.

import { playTap, playPop, playCorrect, playIncorrect, playWhoosh, playCelebrationChime } from "@kids-games/core/sfx";

// All functions take an AudioContext
const ctx = new AudioContext();
playTap(ctx);
playPop(ctx);
playCorrect(ctx);
playIncorrect(ctx);
playWhoosh(ctx);
playCelebrationChime(ctx);

When using with the voice module, get the context from the provider:

const { getContext } = useVoice();
playTap(getContext());

Celebrations

Confetti particle system with three intensity levels.

import { createConfettiBurst, tickConfetti } from "@kids-games/core/celebrations";
import { CELEBRATION_CONFIGS } from "@kids-games/core/celebrations";
import type { CelebrationLevel } from "@kids-games/core/components";

// Create particles
const config = CELEBRATION_CONFIGS["big"]; // small | medium | big
let particles = createConfettiBurst(config.particleCount);

// Animation loop
function animate() {
  particles = tickConfetti(particles);
  // render particles...
  if (particles.length > 0) requestAnimationFrame(animate);
}
animate();

Or use the ready-made component (see Components below).


Components

CelebrationOverlay

Full-screen confetti overlay with auto-dismiss.

import { CelebrationOverlay } from "@kids-games/core/components";

<CelebrationOverlay
  level="big"        // "small" | "medium" | "big" | null
  text="Great job!"  // optional overlay text
  onComplete={() => setLevel(null)}
/>

MuteButton

Floating mute/unmute toggle. Requires KidsAudioProvider as an ancestor.

import { MuteButton } from "@kids-games/core/components";

<MuteButton size={48} className="custom-class" />

PersonaPicker

Tappable persona cards with localStorage persistence.

import { PersonaPicker } from "@kids-games/core/components";

<PersonaPicker
  availablePersonas={["sunny", "bloop", "maple"]}
  onSelect={(id) => setActivePersona(id)}
  storageKey="my-game-persona"
/>

Tokens

Design tokens optimized for children ages 2-6.

Colors

import { COLORS } from "@kids-games/core/tokens";

COLORS.primary.red      // "#FF6B6B"
COLORS.background.warm  // "#FFF8E7"
COLORS.feedback.success // "#4CAF50"
COLORS.persona.sunny    // "#FFD93D"

Spacing

import { SPACING } from "@kids-games/core/tokens";

SPACING.touchTarget.min          // 48 (WCAG minimum)
SPACING.touchTarget.recommended  // 56 (toddler-friendly)
SPACING.touchTarget.large        // 64 (primary actions)
SPACING.padding.md               // 16
SPACING.gap.comfortable          // 16
SPACING.radius.lg                // 16
SPACING.fontSize.lg              // 24

Generating Voice Audio

Each game defines its dialogue in a voice-script.json file. The generation script converts these to MP3 files using the OpenAI TTS API.

1. Create a voice script

{
  "lines": [
    { "id": "welcome", "text": "Welcome to Color Mixer!", "persona": "sunny" },
    { "id": "try-again", "text": "Oops, let's try that again!", "persona": "bloop" },
    { "id": "well-done", "text": "Amazing job, you did it!", "persona": "sunny" }
  ]
}

Save this as voice-script.json in your game's root directory.

2. Generate audio files

OPENAI_API_KEY=sk-... npx tsx node_modules/@kids-games/core/scripts/generate-audio.ts ./

Or from the monorepo root:

OPENAI_API_KEY=sk-... npx tsx _core/scripts/generate-audio.ts ./my-game/

This creates public/audio/<persona>/<id>.mp3 files. Use --force to regenerate existing files.

3. Reference in your provider

<KidsAudioProvider storagePrefix="my-game" audioBasePath="/audio">

The player resolves audio as {audioBasePath}/{persona}/{phraseId}.mp3.


TypeScript

All exports are fully typed. Key types:

import type {
  PersonaId,       // "sunny" | "bloop" | "maple" | "fizz" | "pip"
  Persona,         // Full persona config object
  CelebrationLevel // "small" | "medium" | "big"
} from "@kids-games/core/voice";

License

MIT