A tiny React loader that plays Snake on an 8×8 grid. Meant to sit inline inside buttons, cards, or forms — 24×24px by default. The snake wanders, eats food, grows, and resets when it traps itself. Zero runtime dependencies. ~4kb gzipped. MIT.
Live demo: https://jakubsalmik.com/snake-loader
npm install @scoobynko/snake-loaderimport { SnakeLoader } from "@scoobynko/snake-loader";
import "@scoobynko/snake-loader/styles.css";
<SnakeLoader /> // 24×24px, nokia theme
<SnakeLoader theme="neon" /> // glow + scanlines
<SnakeLoader cellSize={6} /> // 48×48px
<SnakeLoader
theme="custom"
cellSize={4}
colors={{ snake: "#00ff88", food: "#ff3366", background: "#000" }}
effects={{ glow: true, pulse: true }}
/>| Prop | Type | Default | Description |
|---|---|---|---|
theme |
"nokia" | "neon" | "minimal" | "custom" |
"nokia" |
Visual preset. |
cellSize |
number |
3 |
Px per cell. Grid is fixed 8×8. |
speed |
number |
10 |
Cells per second. |
colors |
{ snake?, food?, grid?, background?, glow? } |
— |
Override color tokens. |
effects |
{ glow?: boolean, pulse?: boolean } |
— |
Toggle visual effects. |
paused |
boolean |
false |
Pause the tick loop. |
className |
string |
— |
Pass-through class. |
style |
CSSProperties |
— |
Pass-through style. |
aria-label |
string |
Loading |
A11y label. |
All tokens are also exposed as CSS variables (--snake-loader-snake, --snake-loader-glow, --snake-loader-trail-ms, etc.) so you can theme via stylesheet.
- Fixed 8×8 grid.
- Snake starts length 2 and moves 10 cells/sec (configurable).
- Motion is weighted-random: 70% uniform random among safe directions, 30% biased toward food. Simulates a casual human player — wanders, drifts toward food, occasionally traps itself.
- On food contact: snake grows +1.
- On self-collision or wall collision: resets to initial state.
- No progress mode, no score, no game over — runs forever until unmounted or
paused.
role="progressbar"witharia-busy="true"and anaria-label(defaults to "Loading").- Respects
prefers-reduced-motion— halves tick speed, disables pulse/trail.
PRs welcome.
- Branch off
main—fix/...,feat/...,chore/..., ordocs/....mainis protected. - Before pushing, run
npm run typecheckandnpm run build. Both must pass. - If your change touches
src/, add a changeset:Picknpx changeset
patch(bug fix),minor(additive feature), ormajor(breaking change), and write a one-line summary from the consumer's perspective. CI fails without one. - Open a PR with
gh pr create.
You don't run npm publish, npm version, or tag releases by hand.
- Merging a PR to
mainruns the Release workflow. - If pending changesets exist, it opens (or updates) a "version packages" PR that bumps
package.jsonand updatesCHANGELOG.md. - Merging that PR publishes to npm and tags the release.
Don't commit dist/ or node_modules/, don't edit changeset files in the version PR, and don't add runtime dependencies — this package is zero-deps.
MIT © Jakub Šalmík
