A pixel-art koi pond for your GitHub profile. Your koi swims, eats, turns and grows with your public activity, and wears the colours of your languages.
| Your activity | Your koi |
|---|---|
| Lifetime public contributions | Size. It grows from fry to juvenile, young and adult (50, 250 and 1000 contributions). |
| Public contributions in the last 7 days | Food. It gets two pellets a day, plus one per contribution, up to 8. Each lands with a splash ring, and the koi swims over and eats it. |
| Languages across your public repos, by code size | Colour. Your top language paints the patches, the second the fins and tail, and the third gives the white body a faint sheen. |
Everything is drawn on a 240 × 80 pixel grid and scaled 4× with nearest-neighbour, so the pond, the koi and the effects share one pixel size. Every motion repeats exactly over the 120-frame loop (about 10 s), so the GIF never jumps when it restarts.
-
Open your profile repository, the one named after your username (
you/you). -
Copy
examples/profile-workflow.ymlinto it as.github/workflows/koi.yml. -
Add the pond to its
README.md:<img src="koi/pond.gif" width="100%" alt="My koi pond">
-
Run the workflow once from the Actions tab, so the first pond appears straight away. After that it redraws just after midnight UTC.
The step itself is all you need:
- uses: MemeGamer/git-koi-pixel@v1
with:
output: koi/pond.gif # where the GIF goes; palette.json is written next to it
# login: someone-else # default: the repository owner| Input | Default | Meaning |
|---|---|---|
login |
the repository owner | Account whose koi to draw |
output |
koi/pond.gif |
GIF path in the workspace. palette.json goes in the same folder. |
token |
the built-in token | Reads public data only, so the workflow's own token is enough |
The Action never commits: the example workflow's last step commits the GIF only when it changed. To pin a version, use a release tag such as @v1.0.0 or a commit SHA instead of @v1.
GitHub pauses scheduled workflows in a public repository after 60 days without a push. If your pond stops updating, re-enable it from the Actions tab or with gh workflow enable koi.yml.
Next to the GIF, the Action writes the colours your koi is wearing:
{
"stage": "juvenile",
"roles": ["patches", "fins", "body sheen"],
"koi": ["#2fa043", "#3b7bd4", "#f2c12e"],
"languages": [{ "name": "C#", "colour": "#2fa043" }, { "name": "Python", "colour": "#3b7bd4" }],
"palette": { "C#": "#2fa043", "Python": "#3b7bd4", "...": "..." }
}Read it from your own code to draw a legend that always matches the fish. The MemeGamer profile does this in its stats card: a swatch per language, labelled "koi patches", "koi fins" or "koi body sheen".
Each language has a koi colour tuned to read on the teal water. They're listed in assets/koi-palette.json, and any language not listed falls back to GitHub's own colour for it. Recolouring works on the sprite's colour classes rather than painting over it, so each pixel keeps its own light and shade: eyes and mouth stay put, the patches take the top language, the fins and tail the second, and the pale body the third as a sheen.
| Sheet | Frames | Use |
|---|---|---|
assets/koi-sprites.png |
4 swim + 4 eat, 60 × 32 each | Swimming on the passes. Mouth open and bubbles at each pellet. |
assets/koi-turn.png |
8 U-turn frames, 52 × 52 each | Right → up → left at the right end. The same frames rotated 180° give the left-end turn. |
assets/pond.png |
240 × 80 | The pond: water, lily pads, lotus, maple leaves, reeds, stones |
The originals are in assets/src/. tools/sprites.py turns a raw sheet into game-ready frames:
- removes the magenta background (chroma key)
- slices the sheet into cells
- aligns every frame on the head tip (swim and eat) or the body's centre of mass (turn), so nothing jitters
- snaps to the pixel grid with a binary alpha and a 20-colour palette
pip install pillow numpy opencv-python
python tools/sprites.pypip install pillow
GH_TOKEN=$(gh auth token) python koi.py --login octocat --out koi/pond.gifPreview without the API, with made-up activity:
KOI_LIFETIME=600 KOI_WEEK=5 KOI_LANGS="Python,JavaScript,CSS" python koi.py --out koi/pond.gif- Art: replace
assets/pond.png(keep it 240 × 80) or the sprite sheets. The sheets keep the same cell layout if you run them throughtools/sprites.py. - Colours: edit
assets/koi-palette.json. - Behaviour: constants at the top of
koi.pyset the loop length (T), the lanes and turn radius (LOW,HIGH,R,TURN), the growth thresholds (stage_of) and the pellet rule.
- Idea: an activity-driven koi for a profile README, after git-koi by Anthony Yalong (MIT). git-koi-pixel is a separate implementation with its own art and code; nothing is copied from it.
- Art: the sprite sheets, pond and preview were generated with ChatGPT image generation, then pixel-snapped and prepared with
tools/sprites.py.
MIT © 2026 Varun VP