Grow a one-of-a-kind pixel-art bonsai from your GitHub history.
Every account grows exactly one tree โ deterministic, procedural, 16-bit style. The older your account and the richer your history, the bigger and denser your bonsai. It keeps growing as you keep committing.
Type any username into the playground and meet its tree in your browser: it grows from seed before your eyes, sways in the wind, changes with the seasons, and you can download the PNG/GIF on the spot. Public data only โ the Action sees more.
Every tree is unique โ your username is its seed and your history is its shape, so nobody else can ever grow yours. Post a screenshot with #gitbonsai, drop a link to your profile in Discussions, and let others see what a decade of commits looks like as a living thing.
Curious what the greats grew? Visit the ๐ Bonsai Hall of Fame โ the trees of Linus, Guido and other keepers of legendary histories.
Same stats, six different souls โ the seed (your username) decides the tree's character:
Different histories grow different trees entirely โ style and species are earned, not chosen. Left to right: hokidachi (broom โ metronome consistency, elm), fukinagashi (windswept โ bursty storm-coder, pine), bunjin (literati โ an old minimalist, pine), a sumo trunk with shari & uro deadwood scars (16 years, one long disappearance, maple), a three-era cherry (JS โ TS โ Astro), and a slanted veteran:
Some accounts don't grow one trunk. Two flagship repos grow sokan (twin trunks), several equal flagships grow a kabudachi clump, an organization grows a whole yose-ue forest โ one small tree per era of its repos โ and a single repo that towers over everything puts the tree on a rock (sekijoju, root-over-rock). The pot itself is a growth reward: young accounts start in a small shohin pot and veterans earn the big dai tray:
The tree also lives with the calendar โ leaves flush light in spring, deepen in autumn and frost over in winter, while your languages' hues stay recognizable year-round (only true greens turn amber โ a TypeScript-blue crown stays TypeScript-blue):
Bonsai is one of the oldest living art forms. It began in Han-dynasty China as penjing โ "tray scenery", miniature landscapes of trees and rock โ and came to Japan around the Kamakura period together with Zen Buddhism, where it was distilled into the art of a single tree in a single pot. A bonsai is never finished: it is a decades-long collaboration between the tree and its keeper, shaped season by season, and it embodies wabi-sabi โ the beauty of imperfection and impermanence. A crooked trunk, a dead branch, a scar: these are not flaws but biography.
That's exactly what your commit history is. git-bonsai just makes the biography visible: your years become growth rings, your streaks bloom, your burnout gaps leave honest deadwood. You don't draw this tree โ you live it.
Like a real bonsai, this tree answers to its keeper. Everything is derived from your history โ here is how to grow what you want:
| you want | you do |
|---|---|
| a taller, thicker trunk | be patient โ trunk height, thickness and branching depth come from account age (it literally can't be rushed) |
| a denser, fuller crown | commit more โ foliage and branch density scale with total contributions (private ones count if you let them โ see below) |
| sakura blossoms ๐ธ | keep streaks: each milestone โ 7 / 30 / 100 / 365 days โ adds blossoms, and a live streak of 7+ keeps the tree in bloom |
| no deadwood | don't vanish: every gap longer than 60 days turns a branch into gray jin; a year away carves a shari strip down the trunk, and coming back after 2+ years leaves an uro hollow โ worn with honor |
| a different silhouette | your rhythm picks the style: metronome consistency grows a broom (hokidachi), commit storms after long silences grow a windswept tree (fukinagashi), an old account with few repos grows a literati (bunjin), and weekend habits decide between formal, slanted, semi-cascade and cascade |
| twin trunks or a clump | concentrate your work: two long-lived flagship repos of similar weight grow a sokan (twin trunk), three to five grow a kabudachi clump โ one trunk per flagship |
| a tree on a rock | pour most of your history into one towering repo and the tree grows sekijoju โ roots gripping a boulder |
| a whole forest | run the action for an organization: every era of its repos becomes a tree in one yose-ue tray |
| a massive sumo trunk | a decade of near-daily work unlocks the heavyweight class: a flaring base with visible nebari root spread (the more repos, the wider the roots) |
| a bigger pot | pots are earned too: account age and activity move you up the traditional size classes โ shohin โ chuhin โ dai |
| seasons | re-grow daily (the default) and the leaves follow the calendar: fresh spring flush, deep summer, amber autumn, frosted winter โ your language hues stay recognizable all year. Pin it with the season input if you prefer an eternal summer |
| a different species | your language family decides it: systems languages grow layered pines, scripting grows round-cloud maples, frontend grows blossoming cherries, infra grows ragged junipers, JVM/.NET grows fine-twigged elms |
| different colors | the crown is painted by your top language of each of three eras โ the lower canopy is your past, the upper is your present; switch stacks and the tree will show it |
| richer soil | the pot's mosaic is your current year of contributions, week by week โ a green year makes fertile ground |
| a different tree entirely | you can't โ the seed is your username, forever. Like a real tree, you work with the nature you were given ๐ |
Two switches worth knowing:
- Count private work. Enable Private contributions on your profile (the gear above your contribution calendar) โ the crown fills out using your full commit count, no token required.
- Count private languages. Pass a PAT with repo access as
github-token(store it as a repo secret!) and your private stack colors the crown too.
Add .github/workflows/bonsai.yml to your profile repo (the one named after your username):
name: bonsai
on:
schedule:
- cron: '0 3 * * *' # re-grow daily
workflow_dispatch:
permissions:
contents: write
jobs:
grow:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: egorthinks/git-bonsai@v1Then embed the tree in your README.md:
<img src="output/bonsai-growth.gif" width="384" alt="my git-bonsai" />The images are auto-cropped to your tree's real size โ a young bonsai ships in a small box with no empty sky above it, and the canvas grows as it grows.
Proud of your tree? Add the badge and let visitors grow their own:
[](https://github.com/egorthinks/git-bonsai)Every run also drops a shareable summary (tree + one-click "Share on X" link) into the workflow's job summary page.
The action writes and commits four files: bonsai.svg (static), bonsai.png,
bonsai.gif (wind loop) and bonsai-growth.gif (seed-to-tree timelapse).
| input | default | |
|---|---|---|
github-token |
${{ github.token }} |
token for the GraphQL API & pushing |
user |
repo owner | account to grow the bonsai for |
output-dir |
output |
where to write the images |
commit |
true |
commit & push the result |
commit-message |
chore: tend the bonsai ๐ณ |
|
season |
auto |
spring/summer/autumn/winter, or auto to follow the calendar |
npx git-bonsai --user yourname --token $GITHUB_TOKEN # real data
npx git-bonsai --synth yourname # offline demo
npx git-bonsai --synth yourname --season autumn # try a season100% procedural, zero pre-drawn trees, zero runtime dependencies. Data flows through pure functions, one module per stage:
data GitHub GraphQL โ normalized metrics
seed username โ FNV-1a โ sfc32 PRNG
dna metrics + PRNG โ tree genotype
skeleton stochastic L-system (trunk & branches) + space colonization (twigs)
thickness pipe model / Murray's law
raster Bresenham + scanline capsule fill โ 256ร256 indexed buffer
shade 8SSEDT SDF volume โ posterized light โ Bayer dithering โ keyline
foliage Poisson-disk (Bridson) leaves, simplex silhouette, blossoms
animate wind (sine + simplex, seamless loop) & growth timelapse
frame adaptive box: union bbox across all frames, cropped + padded
encode hand-rolled GIF89a (LZW) + PNG + SVG snapshot
Determinism is a hard guarantee: the same username with the same metrics
produces bit-identical bytes on every run. No Math.random() anywhere โ
only the seeded PRNG. Real pixel art too: everything is rendered onto a small
integer buffer with a fixed 32-color palette, then upscaled nearest-neighbor.
npm install
npm test # determinism + acceptance criteria
npm run demo # render fixtures/veteran.json into out/dist/ is committed intentionally โ the GitHub Action runs straight from it
without an install step. node scripts/render-assets.js regenerates every
image in assets/ from the fixtures. node scripts/build-playground.js
rebundles the engine for the browser playground
(docs/, served by GitHub Pages) โ same code, so the same account grows the
same tree everywhere. See ROADMAP.md for the
design notes behind the growth rules.
MIT






