# Oneko documentation


> A tiny pixel cat for React. Install it, choose its comforts, and give it a home.

Canonical guide: https://oneko.dhrv.pw/docs


## Give your cat a home


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.

### Install Oneko

```bash
npx shadcn@latest add https://oneko.dhrv.pw/r/oneko.json
```

Mount 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.

### Browser-only React

```tsx
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.

### components/cat-layer.tsx

```tsx
"use client";

import dynamic from "next/dynamic";

const Oneko = dynamic(() => import("@/components/oneko"), { ssr: false });

export default function CatLayer() {
  return <Oneko meow={false} />;
}
```

### Inside your existing app/layout.tsx

```tsx
import CatLayer from "@/components/cat-layer";

// Keep your existing layout, providers, and metadata.
// Add this once inside <body>, alongside your app content:
<CatLayer />
```

## Every cat comfort


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


#### skin

Type: `OnekoSkin` · Default: `"classic"`

One of the 12 bundled pixel-art coats. Changing coats keeps the current animation running.

#### scale

Type: `number` · Default: `1`

Scale of the cat and its bubble. Use a positive value; the playground offers 0.5–3.

#### opacity

Type: `number` · Default: `1`

Sprite opacity, from 0 to 1. Does not change bubble opacity.

#### hueRotate

Type: `number` · Default: `0`

Coat hue rotation in degrees. The playground offers 0–360.

#### rotationAmount

Type: `number` · Default: `15`

Maximum movement tilt in degrees. Set 0 for upright paws.

### Paws & play


#### paused

Type: `boolean` · Default: `false`

Freeze movement, activity, and bubble timers without unmounting. Existing sounds may finish. Resume from the same state.

#### followCursor

Type: `boolean` · Default: `true`

Follow the cursor or touch destination and visit favorites. False stops chasing and zoomies while allowing grooming, bubbles, and naps.

#### sleepEnabled

Type: `boolean` · Default: `true`

Allow sleepy idle animations and naps. False wakes an existing or restored nap on the next active tick.

#### speed

Type: `number` · Default: `10`

Movement speed per animation tick, with easing. Use a positive value; the playground offers 1–30.

#### followDistance

Type: `number` · Default: `20`

Distance in CSS pixels at which the cat stops chasing. Use a positive value; the playground offers 10–200.

#### idleThreshold

Type: `number` · Default: `1000`

Rest time in milliseconds before idle activities become eligible. The cat chooses an activity rather than napping immediately.

#### animationSpeed

Type: `number` · Default: `1`

Idle animation pace multiplier. Use a positive value; the playground offers 0.5–2. Does not change the 10fps engine tick.

#### freerunChance

Type: `number` · Default: `0.06`

Probability, from 0 to 1, of starting zoomies on an eligible chasing tick. Set 0 to disable spontaneous zoomies.

#### freerunDuration

Type: `number` · Default: `40`

Zoomies duration in active frames. At 10fps, 40 frames is about 4 seconds.

#### laserPointer

Type: `boolean` · Default: `false`

Replace the system cursor with a pixel laser toy. Hidden while paused or when followCursor is false. The toy takes priority over favorites.

### Bubbles


#### bubbleEnabled

Type: `boolean` · Default: `true`

Enable the cat’s speech bubbles.

#### bubblePlacement

Type: `"auto" | "above" | "below"` · Default: `"auto"`

Preferred side for thoughts. Auto prefers above and flips below near the top. Placement is constrained to the viewport when the bubble fits.

#### bubbleScale

Type: `number` · Default: `1`

Extra bubble size multiplier on top of scale. Clamped to 0.5–2; non-finite values fall back to 1.

#### bubbleText

Type: `string` · Default: `""`

Custom text for awake idle activities. Sleeping always uses sleepy cat thoughts. The playground limits this to 120 characters.

#### bubbleChance

Type: `number` · Default: `0.5`

Chattiness factor, from 0 to 1. Idle and moving states use different trigger rates; this is not a direct per-frame probability.

#### bubbleDisplayFrames

Type: `number` · Default: `180`

Regular bubble display duration in active frames: about 18 seconds by default. Zoomies use their own duration.

#### bubbleCooldown

Type: `number` · Default: `120`

Quiet frames between regular bubbles: about 12 seconds by default.

### Sounds


#### meow

Type: `boolean` · Default: `true`

Allow optional cat audio. Set false if you have not added sound files. The hosted playground starts with sound off.

#### volume

Type: `number` · Default: `0.5`

Volume for newly played sounds, from 0 to 1.

#### soundBasePath

Type: `string` · Default: `"/cat-sounds"`

Local or absolute directory URL for the optional .ogg files. Trailing slashes are removed. Keep the original filenames.

### Home & integration


#### persistPosition

Type: `boolean` · Default: `true`

Restore saved position/activity on mount and save before page unload. False disables both storage reads and writes.

#### storageKey

Type: `string` · Default: `"oneko"`

localStorage key for saved position. Use a distinct key for independent saved positions. Changing it remounts the animation DOM and reads the new key.

#### initialPos

Type: `{ x: number; y: number }` · Default: `viewport center`

Initial cat center in viewport CSS pixels. Mount-only; an existing saved position takes precedence. Disable persistence for a deterministic starting spot.

#### zIndex

Type: `number` · Default: `2147483646`

Layer for the cat and its overlays. Set a lower value to place site UI above it. Changing this remounts the animation DOM.

#### zones

Type: `readonly OnekoZone[]` · Default: `[]`

Keep-out areas and favorite spots, using CSS selectors or viewport rectangles. HTML data-oneko-zone attributes work alongside these definitions.

#### zoneAttractionChance

Type: `number` · Default: `0.3`

Chance to visit a favorite at each five-second check. Clamped to 0–1. Set 0 to skip visits; non-finite values use 0.3.

#### zoneAttractionDuration

Type: `number` · Default: `4000`

Visit duration in milliseconds, including travel. Rounded to 100ms ticks and clamped to 100–60000. Non-finite values use 4000.

#### onStateChange

Type: `(state: CatActivityState) => void` · Default: `undefined`

Called when activity changes. Use it for React UI that displays the cat’s current activity.

#### liveStateRef

Type: `{ current: CatLiveState }` · Default: `undefined`

An initialized mutable ref updated each active frame. Ref writes do not trigger React renders. Keep the ref identity stable to avoid remounting.

## Pick a coat


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.

### A calico companion

```tsx
<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.

## Chasing, grooming & naps


### A quiet companion

```tsx
<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.

## A little cat thought


### Bubble comforts

```tsx
<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.

## Room for paws


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.

### Element zones

```tsx
<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} />
```

### Typed zones

```tsx
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.

## Purrs are optional


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.

### Your cat’s sound directory

```tsx
<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.

## Remember a nap spot


### A saved spot for this site

```tsx
<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.

## Follow your cat’s day


### Activity in React

```tsx
"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.

### Optional live telemetry

```tsx
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.

## Let an agent bring the cat


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.

### Prompt for your coding agent

```text
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.

## Help your cat settle in


- 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.

## Sources and credits

- [Source repository](https://github.com/0xdhrv/oneko)
- [Skin credits](https://github.com/0xdhrv/oneko/blob/main/docs/skins.md)
- [Sound files](https://github.com/0xdhrv/oneko/tree/main/public/cat-sounds)
- [Registry](https://oneko.dhrv.pw/r/oneko.json)
