Pip's Spelling Stars ⭐
A bilingual, parent-editable spelling practice game for young readers
Pip's Spelling Stars is a self-contained single HTML file that turns the weekly classroom spelling list into a tile-dragging mini-game. A penguin mascot named Pip guides the child through each word: a target word appears, letter tiles fly across the screen, and the child taps or drags them into the correct order. Correct placement earns a star; finishing a word triggers a celebration with snow and a recap.
Parents (or teachers) edit the week's word list in an in-app editor — no code, no settings file, no server. The list is saved locally and persists between sessions. Language can be toggled between English and French; tile letters, voice pronunciation, and UI strings all switch together.
Delivery
1 HTML file
Dependencies
0 installed
Languages
EN + FR
Words per round
1–20
Voice
Native TTS
Storage
localStorage
This app has no camera or microphone requirements, so it runs from any source — including a file double-click.
Each round walks through a small word list. The game state machine cycles through three phases per word: preview (the word is spoken aloud and the child sees the target), build (letter tiles fly around the screen, the child drags them into ordered slots), and celebrate (the word lights up green, a star is awarded, and Pip cheers).
Word preview
The target word is displayed and read aloud using the browser's built-in text-to-speech in the chosen language. A "say it again" button replays at any time.
Flying tiles
Letter tiles drift around a designated flying zone with gentle physics — slow movement, wall-bouncing, slight drag. Each tile is grabbable on touch or mouse.
Slot placement
Slots appear under the word, one per letter. Tapping or dragging a tile into a slot locks it in. Tapping a filled slot returns the tile to the flying zone.
Stars + recap
Completing a word correctly awards a star. After all words are done, a recap screen lists every word with its star, and the snow particle effect plays.
localStorage keyed per language. Switching to French keeps a separate French list.HTML + CSS + Vanilla JS
Entire app, no framework
Single file
Web Speech API
SpeechSynthesisUtterance for word pronunciation
Native browser
Pointer Events
Unified mouse + touch + pen dragging
Native browser
localStorage
Word list + language persistence
Native browser
CSS keyframes
Snow, tile wobble, slot pop, star sparkle
No animation library
Every visible string in the UI ships in both English and French. Switching language updates buttons, instructions, encouragement text, the speech synthesis voice, and the saved word list. The UI uses a data-i18n attribute on each translatable element pointing to a key in a translations dictionary — a single setLang(code) function walks the DOM and rewrites all text.
Pronunciation picks the first matching voice on the platform — en-GB or en-US for English, fr-CA or fr-FR for French — with graceful fallback to any English/French voice if a regional voice isn't installed.
Each flying tile has a position, velocity, and rotation. A lightweight animation loop using requestAnimationFrame moves each tile by its velocity, bounces it off the edges of the flying zone, and applies a tiny rotation. Velocities are randomized at spawn and capped to slow gentle drift — readability for new readers matters more than spectacle.
When a tile is grabbed, its physics pauses. On release into the flying zone, it resumes drifting. On release into a slot, the tile is removed from the physics loop and rendered as a static letter in the slot.
The app is a single <script> block at the bottom of the HTML. State is held in a small state object: current word index, current language, current tile positions, star tallies, and editor open/closed. There are no classes or modules — every function operates directly on state and the DOM.
The game loop is a single requestAnimationFrame tick that updates tile positions and re-renders only the moving elements. Slots, the word display, and UI chrome are static between animation frames; only what moves gets repainted.
Persistence is two localStorage keys: spellingWords_en and spellingWords_fr. Reads happen on language switch; writes happen on editor save. There's no IndexedDB or sync — the simplest possible model for a kid's app that needs to "just work" tomorrow morning.