This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady*
The moss does not hurry, and yet it covers the whole stone.
Every productivity tool I open is quietly asking the same thing: faster, please. More velocity, more streaks, more dashboards, more “you’re falling behind” nudges dressed up as encouragement. Even the wellbeing apps have turned rest into a metric to optimize.
So for the Slow and Steady challenge — in the spirit of International Sloth Day — I built the opposite.
LazyBonsai is a digital bonsai garden that grows only while you do nothing. It is ambient, it is private, and its mind runs entirely on your own machine through local open-weight models (with offline wisdom baked right in).
No accounts. No analytics. No API keys. No audio files. And absolutely no one telling you to hustle.
What it is
Open the app and you see a small bonsai sapling on a soft canvas horizon. There is a timer, a few quiet controls, and one button: Enter Calm Mode.
While Calm Mode is on — and you are not thrashing the mouse around — the garden begins to grow:
- 5 minutes of stillness → buds appear on the branches.
- 15 minutes → full bloom, petals drifting down through the scene.
- 30 minutes → a serene gold aura settles over the tree.
Nothing is lost if you move. Frantic pointer movement just pauses the clock for a breath. The garden doesn’t punish you; it waits.
Alongside the tree lives the Slow AI Sloth, a local model that offers three things:
- Bonsai Whispers — one or two poetic sentences about slowness, arriving periodically while you sit.
- The Chill Pill — you type what you’re panicking about (“My client wants this bug fixed immediately”), and the sloth applies Occam’s razor, explains why it can safely wait fifteen minutes, and offers a quiet 15-minute timer so you can test the claim.
- Tea with the Sloth — a slow, streamed conversation for when the week has simply been too much.
And a “Why Open Innovation Matters” drawer makes the case for why this had to be local, open, and free.
There is also a full ambient soundscape — singing bowl, bamboo fountain, rain, wind — synthesized live with the Web Audio API.
Why “slow and steady” needed a real mechanic
A theme about slowness is easy to illustrate and hard to implement. A countdown is not slowness; it’s just a different kind of pressure.
So the Calmness Engine rewards the one thing productivity software never rewards: not producing. The tree is the progress bar, and the only way to fill it is to leave the keyboard alone. Growth is persisted in localStorage, so the garden you sat with yesterday is still there today. The tab can even be in the background — stepping away is the point, not a loophole.
There is a deliberate ?speed=60 time-lapse mode for demos and judging. In normal use, the garden makes you wait thirty real minutes for the gold aura. That waiting is the feature.
The stack, and the fun parts
Frontend: React 18, Vite, Tailwind CSS, Lucide icons.
The bonsai: a seeded recursive fractal on <canvas>, rebuilt from a deterministic PRNG so the same tree persists across sessions. Branch reach and thickness interpolate with calm time; blossom density, season palette, wind sway, falling petals, fireflies, and a slow day→dusk→night→dawn colour cycle are all drawn per frame. Clicking releases a ripple and a small gust of petals.
The soundscape: zero external assets. Four layers of pure synthesis — inharmonic sine partials with long exponential decays for the bowl, filtered pink-noise bursts and a wooden knock for the shishi-odoshi, looped pink noise through low- and band-pass filters for rain and wind, with a slow LFO wandering the wind’s centre frequency.
The backend: a small Express proxy in server/index.js. It exists for three honest reasons: to avoid browser CORS with Ollama, to auto-detect installed models, and to own the offline fallback.
The mind: whatever local model you already have. On my machine it’s qwen3:8b, with qwen2.5-coder:7b as a second choice, but any installed Ollama model works.
// server/index.js — the shape of every generation
const res = await fetch(`${OLLAMA_URL}/api/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model,
prompt,
system: SLOTH_SYSTEM,
stream: false,
options: { temperature: 0.85, num_predict: 220 },
...(looksLikeThinkingModel(model) ? { think: false } : {}),
}),
});
Handling reasoning models without leaking them
qwen3-class models like to think out loud, and <think>…</think> blocks are not what you want appearing in a zen whisper. LazyBonsai asks Ollama to disable thinking where supported, and otherwise strips reasoning blocks before they reach the UI — including while streaming, where the stripping has to stay incremental so token deltas never desynchronise. The chat uses Server-Sent Events, so words arrive slowly instead of appearing in one anxious block.
Never failing, even when the model does
A wellbeing app that shows a red error toast because a 7B model is cold is not calming. The proxy catches every failure — Ollama down, model missing, timeout, empty generation, a stream that dies halfway — and falls back to a hand-written pool of Taoist sloth reflections, Occam-cut panic responses, and gentle chat replies in server/wisdom.js.
Offline chat even streams word by word with a small delay, because the pacing is part of the product.
Pull the network cable out, stop Ollama, and the garden still works. That was a hard requirement, not a nice-to-have.
Why open innovation matters here
This project would be fundamentally worse as a SaaS product, and the “Why Open Innovation Matters” drawer in the app says so plainly.
Privacy by architecture. People type real panic into a de-escalator. “My client wants this fixed immediately.” “I can’t switch off.” “I feel guilty for resting.” Those sentences should not leave the laptop. With a local model behind a localhost proxy, they physically cannot. There is no analytics, no telemetry, no third-party font or CDN, and no cloud fallback quietly uploading your worst afternoon. The only stored state is your calm seconds and garden preferences, in your own browser.
Energy conservation, literally. A sloth survives on very little. Local quantized inference on hardware you already own means no datacenter spins up because you needed a gentler sentence. Token budgets are deliberately short; one stream at a time; a canvas that draws the garden instead of downloading it.
Zero SaaS bills, forever. No API keys, no seats, no usage dashboard waiting to surprise you. Clone it, npm install, and it runs on an airplane, in a cabin, or on an old tablet with a charger. Open weights mean the intelligence in your calm companion cannot be deprecated, repriced, or shut down by a vendor.
The garden is small on purpose. Small things are easier to keep alive.
Running it
git clone https://github.com/Big0boy/lazy-bonsai
cd lazy-bonsai
npm install
# optional but recommended
ollama pull qwen3:8b
npm run dev
Frontend at http://localhost:5173, proxy at http://localhost:8787. For a single-process, fully offline build:
npm run build
npm start
Then everything is served from http://localhost:8787.
Keyboard: w whisper · c chill pill · t tea · g garden · m sound.
What I learned
- Waiting is a design material. The most interesting part of this build was not the model or the canvas — it was deciding how long the app should take to respond, and then defending that delay.
- Fractals make excellent progress bars. Watching branch thickness interpolate with calm seconds feels far more alive than a percentage.
- Fallbacks are part of the art direction. The offline wisdom was originally a safety net. It became one of the most characterful parts of the project.
- Local models are good enough for gentleness. A small model does not need to be correct about the world. It needs to be unhurried, kind, and private. That is a much lower bar, and a much better fit for open weights.
What’s next
- A daily garden that keeps three or four trees, one per day, so you can look back at a week of pauses.
- Ambient audio that responds to growth — the bowl striking less often as the tree blooms.
- Optional export of a “calm receipt” (a small local image of your tree and minutes rested) that you can keep, not share.
- A screen-reader pass on the canvas with a text description of the current growth stage.
- More offline reflections, especially ones contributed by other tired people.
Try it, then close the tab
If you take one thing from this post, make it the fifteen minutes. Open LazyBonsai, enter Calm Mode, and go make tea while the tree does absolutely nothing useful.
That’s the whole product.
Repo: github.com/Big0boy/lazy-bonsai · Live Demo: big0boy.github.io/lazy-bonsai · Built for: DEV “Slow and Steady” challenge & Hacktoberfest 🦥🌿
AI disclosure: this project was developed with AI-assisted coding tools. The code is open source, reviewed, and entirely local at runtime.
Top comments (0)