quantumkuba452 downloadsGrow a tree with every focus session and turn your focus, tasks and streaks into a living village. A gamified pomodoro timer with daily quests, perks and achievements.
Turn your focus sessions into a living village, right inside Obsidian.
Grow a tree with every pomodoro. Turn your trees, tasks and streaks into a village you actually want to come back to.
User guide · Quick start · Timer & task docs · Technical spec
Pomodoro timers are easy to ignore. Pomodoro Timer Forest gives your focus something to grow into.
| 🌱 Focus feels alive | 🏡 Progress you can see | 🔥 A reason to come back |
|---|---|---|
| The plant in your timer grows in real time, from seed to full tree. | Every session, task and streak day builds a village that reacts to how you're doing. | Daily quests, a streak, perks that grow, new things to unlock at every level. |
It's designed to motivate, not to nag. Missed days make the village sleepy, never broken. Rest is rewarded. Nothing you've built is ever taken away.
Start a session and a seed is planted inside the timer. As the minutes pass it sprouts, becomes a sapling and grows into a tree, while the ring fills up around it. Finish and you harvest it. Give up early and it withers.
Every finished tree becomes a sapling you can plant. Spend what you earn on buildings that give real perks: a Cozy Cabin for more Sunlight, a Village Well for more Coins, a Watermill that protects your streak while you rest. Lay paths, dig a brook, put a bridge over it, and expand your island from 5×5 up to 8×8.
Add garden plots and your focus grows carrots, tomatoes, wheat and pumpkins too: every focused minute grows them, every ticked task waters them, and a crop never wilts while you're away. A scarecrow speeds them up, and a chicken coop brings hens and fresh eggs for your first tree of the day.
Open it as a full-page tab, or keep a compact version in the sidebar under the timer.
The sky follows your real time of day. Windows glow at dusk, fireflies come out at night, sails turn, chimneys smoke and villagers stroll the paths, stop by the well and gather at the campfire after dark. Click one and they'll tell you how your day is going. When you've been away the village gets a little sleepier, and one session wakes it back up.
Unlock new species as you level up: from a humble Classic Pine to a glowing Celestial Gold Tree. Give your village a new mood with five biomes.
![]() Focus & village A growing plant inside the timer, your goal for the day, and the village right beneath it. |
![]() Harvest Every bonus is itemised, so you see exactly what you earned. |
![]() Market Buildings with perks that grow when you upgrade them. |
![]() Journey Daily quests, a chest, 20 achievements and your lifetime stats. |
Plan in lanes, focus on one card at a time, and watch the work actually get finished. Boards are plain markdown in the Kanban plugin's file format, so the boards you already have open here as they are, and every board you make here still opens in the Kanban plugin.
## Doing (3)), a gentle marker on cards that have waited too long in progress, and statistics for each board: cards finished per day, cycle time, estimate accuracy and milestones at 10, 25, 50… cards.@{2025-10-03}), Tasks emoji fields, checklists inside cards, links, tags, block IDs, the Complete lane and the archive all carry over. If you keep using the Kanban plugin, cards finished there are rewarded too.![]() Board statistics: throughput, cycle time and how good your estimates are. |
![]() Light or dark: boards follow your Obsidian theme. |
- [ ] task anywhere in your vault and it earns Coins and XP. Only real ticks count: pasting in already-checked tasks or toggling one back and forth earns nothing, and there's a daily cap.#write plants a Cherry Blossom, #code a Pine, #study an Oak. Your notes and tasks choose the tree.![]() The Grove: today's trees and a four-week activity map. |
![]() Level up: new species, buildings, biomes and land. |
One click exports a self-contained HTML snapshot of your village, with its animated scenery, that opens in any browser, or a JSON summary for building your own dashboard.
main.js, manifest.json and styles.css into <your vault>/.obsidian/plugins/pomodoro-timer-forest/ and enable the plugin under Settings → Community plugins. To build them yourself: npm install && npm run build.[🍅:: …] field on the task you focus on), session logging (daily, weekly or a chosen note), the optional daily-note line for each tree, and the Kanban boards you open with it (each change you make on a board is written to that note, and focusing a card gives it a block ID such as ^a1b2c3). Its own data is saved in the plugin's data.json.The images above are rendered by the plugin's own components and renderer using a sample level-14 village.
.obsidian/plugins/pomodoro-timer-forest/data.json.data.json. If you might return, copy the file somewhere safe first and put it back after reinstalling. The plugin is still evolving, so older saves are upgraded on load but not guaranteed to work forever. Steps in the guide.The game layer sits on top of a full-featured Pomodoro timer for Obsidian:
AudioFiles and named notification.mp3, your path would be AudioFiles/notification.mp3.
Don't forget the file extension (like .mp3, .wav etc.).play button next to the path to verify the audioThe Tasks panel (the checklist icon under the timer) lists the tasks of the note you are working in, plus every note you have pinned.
![]() One list, several notes The note you are in, plus everything you pinned. |
![]() Plan without typing Pomodoros, start date and due date, right under the task. |
This is what ends up in your note:
- [ ] Draft the methods section [🍅:: 4/6] 🛫 2025-09-25 📅 2025-10-03
4/6 is four pomodoros done out of six planned. Dates follow the Task format setting: the Tasks emoji format shown above, or Dataview fields ([start:: 2025-09-25] [due:: 2025-10-03]).
The panel is optional; you can still write the field yourself after the task's text. Enable tracking in the settings and the timer updates the count at the end of each work session.
Important: Ensure to add this inline-field before the Tasks plugin's fields. Placing it elsewhere may result in incorrect rendering within the Tasks Plugin. The panel always puts it there.
- [ ] Task with specified expected and actual pomodoros fields [🍅:: 3/10]
- [ ] Task with only the actual pomodoros field [🍅:: 5]
- [ ] With Task plugin enabled [🍅:: 5] ➕ 2023-12-29 📅 2024-01-10
The standard log formats are as follows For those requiring more detailed logging, consider setting up a custom [log template](#Custom Log Template) as described below.
Simple
**WORK(25m)**: 20:16 - 20:17
**BREAK(25m)**: 20:16 - 20:17
Verbose
- 🍅 (pomodoro::WORK) (duration:: 25m) (begin:: 2023-12-20 15:57) - (end:: 2023-12-20 15:58)
- 🥤 (pomodoro::BREAK) (duration:: 25m) (begin:: 2023-12-20 16:06) - (end:: 2023-12-20 16:07)
log object, which stores session information.// TimerLog
{
duration: number, // duratin in minutes
session: number, // session length
finished: boolean, // if the session is finished?
mode: string, // 'WORK' or 'BREAK'
begin: Moment, // start time
end: Moment, // end time
task: TaskItem, // focused task
}
// TaskItem
{
path: string, // task file path
fileName: string, // task file name
text: string, // the full text of the task
name: string, // editable task name (default: task description)
status: string, // task checkbox symbol
blockLink: string, // block link id of the task
checked: boolean, // if the task's checkbox checked
done: string, // done date
due: string, // due date
created: string, // created date
cancelled: string, // cancelled date
scheduled: string, // scheduled date
start: string, // start date
description: string, // task description
priority: string, // task priority
recurrence: string, // task recurrence rule
tags: string[], // task tags
expected: number, // expected pomodoros
actual: number // actual pomodoros
}
here is an example
<%*
if (log.mode == "WORK") {
if (!log.finished) {
tR = `🟡 Focused ${log.task.name} ${log.duration} / ${log.session} minutes`;
} else {
tR = `🍅 Focused ${log.task.name} ${log.duration} minutes`;
}
} else {
tR = `☕️ Took a break from ${log.begin.format("HH:mm")} to ${log.end.format(
"HH:mm"
)}`;
}
%>
This DataView script generates a table showing Pomodoro sessions with their durations, start, and end times.
```dataviewjs
const pages = dv.pages()
const table = dv.markdownTable(['Pomodoro','Duration', 'Begin', 'End'],
pages.file.lists
.filter(item=>item.pomodoro)
.sort(item => item.end, 'desc')
.map(item=> {
return [item.pomodoro, `${item.duration.as('minutes')} m`, item.begin, item.end]
})
)
dv.paragraph(table)
```
This DataView script presents a summary of Pomodoro sessions, categorized by date.
```dataviewjs
const pages = dv.pages();
const emoji = "🍅";
dv.table(
["Date", "Pomodoros", "Total"],
pages.file.lists
.filter((item) => item?.pomodoro == "WORK")
.groupBy((item) => {
if (item.end && item.end.length >= 10) {
return item.end.substring(0, 10);
} else {
return "Unknown Date";
}
})
.map((group) => {
let sum = 0;
group.rows.forEach((row) => (sum += row.duration.as("minutes")));
return [
group.key,
group.rows.length > 5
? `${emoji} ${group.rows.length}`
: `${emoji.repeat(group.rows.length)}`,
`${sum} min`,
];
})
)
```
| Variable | Default |
|---|---|
| --pomodoro-timer-color | var(--text-faint) |
| --pomodoro-timer-elapsed-color | var(--color-green) |
| --pomodoro-timer-text-color | var(--text-normal) |
| --pomodoro-timer-dot-color | var(--color-ted) |
To switch sessions, simply click on the Work/Break label displayed on the timer.
Break sessionsYou can adjust the break interval setting to 0, this will turn off Break sessions.
npm install
npm run dev # watch build
npm run build # type-check and production bundle
The README screenshots are regenerated from the plugin's real components and renderer (needs Google Chrome):
node scripts/readme-images/build.mjs
Built on Pomodoro Timer for Obsidian by eatgrass (MIT). The timer, task tracking and logging come from that project. The Forest & Homestead game layer is added on top.