ONEKO / DOCUMENTATION
A little guide
for little paws
A pixel cat, at home in your React app. Install it, pick a coat, and make its little habits your own.
Oneko is a shadcn registry component for React. The installer copies the component, hooks, animation engine, 12 bundled skins, and skin credits into your project. You own the code. Start from a React project with shadcn configured and a working import alias.
npx shadcn@latest add https://oneko.dhrv.pw/r/oneko.jsonMount one cat near the root of your app. It attaches its sprite and bubble to document.body; it does not take up layout space. For a browser-only React app, import Oneko and render it directly.
import Oneko from "@/components/oneko";
export default function CatLayer() {
return <Oneko meow={false} />;
}In Next.js App Router, put the no-SSR dynamic import inside a client component. Render this wrapper from your layout. This also ensures the default starting position is computed in the browser.
"use client";
import dynamic from "next/dynamic";
const Oneko = dynamic(() => import("@/components/oneko"), { ssr: false });
export default function CatLayer() {
return <Oneko meow={false} />;
}import CatLayer from "@/components/cat-layer";
// Keep your existing layout, providers, and metadata.
// Add this once inside <body>, alongside your app content:
<CatLayer />All props are optional. These are component defaults; the playground starts with sound off and its own cat thought. The engine runs at 10fps, so 10 active frames is about one second. Hidden tabs and paused cats do not advance those timers.
Most props update live. initialPos is mount-only; changing persistPosition, storageKey, zIndex, or the liveStateRef object restarts the animation DOM. Suggested playground ranges are guidance, not automatic clamps unless explicitly stated below.
Coat & appearance
skinOne of the 12 bundled pixel-art coats. Changing coats keeps the current animation running.
scaleScale of the cat and its bubble. Use a positive value; the playground offers 0.5–3.
opacitySprite opacity, from 0 to 1. Does not change bubble opacity.
hueRotateCoat hue rotation in degrees. The playground offers 0–360.
rotationAmountMaximum movement tilt in degrees. Set 0 for upright paws.
Paws & play
pausedFreeze movement, activity, and bubble timers without unmounting. Existing sounds may finish. Resume from the same state.
followCursorFollow the cursor or touch destination and visit favorites. False stops chasing and zoomies while allowing grooming, bubbles, and naps.
sleepEnabledAllow sleepy idle animations and naps. False wakes an existing or restored nap on the next active tick.
speedMovement speed per animation tick, with easing. Use a positive value; the playground offers 1–30.
followDistanceDistance in CSS pixels at which the cat stops chasing. Use a positive value; the playground offers 10–200.
idleThresholdRest time in milliseconds before idle activities become eligible. The cat chooses an activity rather than napping immediately.
animationSpeedIdle animation pace multiplier. Use a positive value; the playground offers 0.5–2. Does not change the 10fps engine tick.
freerunChanceProbability, from 0 to 1, of starting zoomies on an eligible chasing tick. Set 0 to disable spontaneous zoomies.
freerunDurationZoomies duration in active frames. At 10fps, 40 frames is about 4 seconds.
laserPointerReplace the system cursor with a pixel laser toy. Hidden while paused or when followCursor is false. The toy takes priority over favorites.
Bubbles
bubbleEnabledEnable the cat’s speech bubbles.
bubblePlacementPreferred side for thoughts. Auto prefers above and flips below near the top. Placement is constrained to the viewport when the bubble fits.
bubbleScaleExtra bubble size multiplier on top of scale. Clamped to 0.5–2; non-finite values fall back to 1.
bubbleTextCustom text for awake idle activities. Sleeping always uses sleepy cat thoughts. The playground limits this to 120 characters.
bubbleChanceChattiness factor, from 0 to 1. Idle and moving states use different trigger rates; this is not a direct per-frame probability.
bubbleDisplayFramesRegular bubble display duration in active frames: about 18 seconds by default. Zoomies use their own duration.
bubbleCooldownQuiet frames between regular bubbles: about 12 seconds by default.
Sounds
meowAllow optional cat audio. Set false if you have not added sound files. The hosted playground starts with sound off.
volumeVolume for newly played sounds, from 0 to 1.
soundBasePathLocal or absolute directory URL for the optional .ogg files. Trailing slashes are removed. Keep the original filenames.
Home & integration
persistPositionRestore saved position/activity on mount and save before page unload. False disables both storage reads and writes.
storageKeylocalStorage key for saved position. Use a distinct key for independent saved positions. Changing it remounts the animation DOM and reads the new key.
initialPosInitial cat center in viewport CSS pixels. Mount-only; an existing saved position takes precedence. Disable persistence for a deterministic starting spot.
zIndexLayer for the cat and its overlays. Set a lower value to place site UI above it. Changing this remounts the animation DOM.
zonesKeep-out areas and favorite spots, using CSS selectors or viewport rectangles. HTML data-oneko-zone attributes work alongside these definitions.
zoneAttractionChanceChance to visit a favorite at each five-second check. Clamped to 0–1. Set 0 to skip visits; non-finite values use 0.3.
zoneAttractionDurationVisit duration in milliseconds, including travel. Rounded to 100ms ticks and clamped to 100–60000. Non-finite values use 4000.
onStateChangeCalled when activity changes. Use it for React UI that displays the cat’s current activity.
liveStateRefAn initialized mutable ref updated each active frame. Ref writes do not trigger React renders. Keep the ref identity stable to avoid remounting.
Choose classic, black, gray, calico, tora, catppuccin, ghost, silver, spirit, valentine, maia, or vaporwave. All skins ship with the registry; there is no separate image download. They use the original pixel art without smoothing.
<Oneko skin="calico" scale={1.5} rotationAmount={0} meow={false} />The installer includes docs/oneko-skins.md with artwork provenance. Code is MIT; preserve the artwork credits and review the skin-specific notes when redistributing.
Meet the cat artists<Oneko
followCursor={false}
sleepEnabled
freerunChance={0}
meow={false}
persistPosition={false}
initialPos={{ x: 80, y: 120 }}
/>- paused freezes the current activity; it does not make the cat sleep. Use paused={isDialogOpen} with your existing dialog state to pause while a dialog is open.
- followCursor={false} keeps the cat resting in one spot, with grooming, bubbles, and optional naps. Keep-out zones can still relocate it to safety. Re-enabling follows the latest pointer position.
- sleepEnabled={false} wakes a sleeping cat on the next active tick. If paused, it wakes after resuming.
- The laser toy is hidden while paused or when cursor-follow is disabled. While active, it takes priority over favorite spots.
- On touch screens, a tap on non-interactive space gives the cat a destination. Taps on buttons, links, and form controls are ignored.
<Oneko
meow={false}
bubbleText="Dreaming of treats…"
bubblePlacement="above"
bubbleScale={1.2}
bubbleDisplayFrames={60}
bubbleCooldown={100}
/>bubbleScale multiplies the bubble’s inherited scale without changing the cat. Auto placement prefers above and flips below near the top. Bubbles are kept inside the viewport when they fit; an oversized bubble is centered horizontally. Keep-out zones constrain the cat, not its bubble.
Custom text is used for awake idle activities. Sleeping always uses sleepy thoughts. Keep your copy cat-themed. bubbleChance controls regular chatter; zoomies have their own thoughts and timing.
Bubble styling reads --background, --foreground, and --border from your theme. It uses --font-geist-pixel-square when available, otherwise monospace. Geist Pixel is optional; the component does not require this site’s fonts.
Mark real page elements as keep-out areas or favorite spots. These attributes work without a zones prop and follow visible elements as the page moves.
<section data-oneko-zone="avoid">
{/* Your checkout or other UI that needs room. */}
</section>
<div data-oneko-zone="attract">A cozy cat bed</div>
<Oneko meow={false} />import Oneko, { type OnekoZone } from "@/components/oneko";
const zones: OnekoZone[] = [
{ id: "checkout", type: "avoid", selector: "#checkout", padding: 12 },
{ id: "bed", type: "attract", selector: ".cat-bed" },
{
id: "corner", type: "avoid",
rect: { left: 0, top: 0, right: 160, bottom: 100 },
},
];
export function CatLayer() {
return (
<Oneko zones={zones} zoneAttractionChance={0.3}
zoneAttractionDuration={4000} meow={false} />
);
}- OnekoZone has id, type (avoid or attract), and either selector or rect. A selector takes precedence and includes all matching visible elements. Use distinct IDs for separate definitions.
- Rectangles use viewport CSS pixels with left, top, right, and bottom. Optional padding adds extra space around avoid zones. Invalid selectors and empty rectangles are ignored.
- Avoid zones protect the entire scaled, tilting cat, even during zoomies. A new zone around the cat moves it to the nearest safe spot. If no room remains, the cat hides until space returns.
- Favorites are checked every five seconds. A visit includes travel time, followed by an eight-second break after it ends. Offscreen favorites and favorites inside keep-out areas are skipped.
- Zones are sampled at the 10fps tick. Keep-out boundaries take priority; paused cats do not reconcile moving zones until resumed.
The registry does not include audio files. Keep meow={false} for a silent install, or copy public/cat-sounds/ from the source repository into your app’s public assets, preserving the .ogg filenames. Browsers may require user interaction before audio can play.
<Oneko meow volume={0.3} soundBasePath="/assets/cat-sounds" />soundBasePath also accepts an absolute directory URL. Mute and volume apply to future playback; sounds already playing can finish. Sleeping audio uses the purr pool.
Find the cat sound files<Oneko storageKey="my-site:cat" persistPosition meow={false} />Position and idle activity are restored from localStorage on mount and saved before page unload. Storage failures are ignored. A saved spot takes precedence over initialPos. Use persistPosition={false} for a predictable starting position or when saving is unwanted.
The component does not save its configuration props. The hosted playground separately remembers its controls under oneko:playground:v1. Copy your cat in the instantly available install panel exports your selected configuration. Open customization and install panels keep the cat outside; zone sample spots sit below the controls.
"use client";
import { useState } from "react";
import Oneko, { type CatActivityState } from "@/components/oneko";
export function CatActivity() {
const [activity, setActivity] = useState<CatActivityState>("idle");
return (
<>
<Oneko meow={false} onStateChange={setActivity} />
<p>Cat activity: {activity}</p>
</>
);
}Activity values are idle, moving, sleeping, scratchSelf, tired, alert, scratchWallN, scratchWallS, scratchWallE, scratchWallW, and freerun. In a Next.js app, use the no-SSR wrapper pattern from installation for the Oneko import.
import { useRef } from "react";
import type { CatLiveState } from "@/components/oneko";
// Inside your client component:
const liveStateRef = useRef<CatLiveState>({
state: "idle", posX: 0, posY: 0, velMag: 0,
idleTime: 0, distToMouse: 0, frameCount: 0,
freerunActive: false, freerunTimer: 0, bubbleVisible: false,
pathLength: 0, obstacleCount: 0,
});
// Pass liveStateRef={liveStateRef} to Oneko.
// Read liveStateRef.current when needed; writes do not rerender React.CatLiveState exposes activity, position, speed, idle ticks, cursor distance, total ticks, zoomies status/time, bubble visibility, and nearby movement information. Public types OnekoProps, OnekoSkin, OnekoZone, CatActivityState, and CatLiveState are exported from @/components/oneko.
Copy this prompt into your coding agent with your project open. It points to the same documentation in Markdown, gives the exact install command, and asks the agent to adapt to your existing app.
Add the Oneko pixel cat to this project using its shadcn registry component.
Read https://oneko.dhrv.pw/llms.txt, then https://oneko.dhrv.pw/docs.md for the full API and integration recipes. Fetch https://oneko.dhrv.pw/r/oneko.json if you need the exact installable source.
1. Inspect the framework, package manager, existing shadcn setup, import aliases, theme tokens, and client/server boundaries. Preserve unrelated changes.
2. Install with: npx shadcn@latest add https://oneko.dhrv.pw/r/oneko.json
3. Mount one Oneko instance in an appropriate client component. For Next.js App Router, use the documented dynamic import with ssr: false inside a client wrapper, then render that wrapper from the layout.
4. Start with meow={false} unless the sound assets are installed. Keep the built-in reduced-motion behavior, pixel art, and theme-token bubble styling. Keep cat thoughts cat-themed, and sleeping thoughts sleepy.
5. Use documented props to match this site. Put data-oneko-zone="avoid" on sensitive UI that needs space. Use initialPos with persistPosition={false} when a fixed starting spot is required. Do not add new settings unless needed.
6. Check desktop and touch behavior, light and dark themes, keyboard controls, and reduced motion. Run the project’s relevant lint, type, test, and build checks. Report the files changed, chosen props, and any missing sound assets.
Implement the integration in this project. Do not deploy or publish it.Agents can read /llms.txt for discovery, /docs.md or /llms-full.txt for the complete guide, and /r/oneko.json for the installable source. These resources are public and need no login. The HTML guide is rendered on the server, so it is readable without JavaScript.
- No cat? Check that it is mounted in the browser. Reduced motion is checked when the animation mounts; a matching preference skips the cat. Keep-out zones covering the whole viewport can also hide it.
- Cat stays still? Check paused, followCursor, followDistance, and whether the tab is hidden. A resting cat may need the cursor moved farther away before it chases.
- Starting spot ignored? A saved position overrides initialPos. Disable persistence or use a new storage key, then remount the component.
- No purrs? Check meow, volume, the sound directory and filenames, and whether the page has received a user interaction. Sound files are not part of the registry download.
- Cat covers a dialog? Lower zIndex or use paused with your dialog state. The cat is mounted on document.body, so a parent’s stacking context does not contain it.
- Bubble font differs? Load Geist Pixel and expose --font-geist-pixel-square, or keep the monospace fallback. Define theme variables in both light and dark modes.