Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Banshan Water Tracker

PassengerC07PassengerC0718 downloads

Log cups of water with a bottle that fills up as you drink. Every entry is a plain markdown row in your vault.

Add to Obsidian
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
Banshan Water Tracker screenshot
  • Overview
  • Scorecard
  • Updates2

Log your water in cups, watch a bottle fill up as you drink, and keep the whole history in plain markdown inside your vault.

  • A bottle that actually fills. It starts empty, and every entry raises the water by exactly the amount you logged. The surface animates, so it reads well on a phone.
  • Your data is text. One markdown file per month, one table per day. No database, no binary blob, no plugin-owned format. Delete the plugin and your history is still readable.
  • Four bottles to choose from, drawn from shared geometry so the rising water behaves the same in all of them.
  • Two tabs in one sidebar view. Drink for logging, Analysis for looking back.
  • Desktop and iOS. Same code path on both, no runtime dependencies.

Where your data lives

Everything goes into <data folder>/YYYY-MM.md, one section per day:

## 2026-09-29

| Time  | Amount |
| ----- | ------ |
| 09:05 | 250 |
| 13:40 | 150 |

Those table rows are the source of truth. Totals, streaks and charts are all recomputed when the file is read, so a number can never drift out of sync with the entries beneath it. Edits go through vault.process, which reads and rewrites the file as one operation; that is what lets a desktop and a phone add to the same month without erasing each other's rows.

The time is the local wall clock at the moment you tapped, and amounts are always stored in millilitres. Switching the displayed unit changes what you see, not what is on disk.

Install

Desktop. Copy main.js, manifest.json and styles.css into <vault>/.obsidian/plugins/banshan-water-tracker/, then enable it under Settings → Community plugins. (Once it is in the community directory you can install it from inside Obsidian instead.)

iOS. The same three files have to reach the vault, so put the vault somewhere your phone can see it — Obsidian Sync is the least friction — then enable the plugin on the mobile app. Nothing in this plugin is desktop-only.

Version. Obsidian 1.13.7 or newer is required. That is what minAppVersion in manifest.json promises, and npm run app-version checks the promise against the code by reading the version tags in the installed typings: an API newer than the floor is not merely an error at build time, it is undefined on the installs the floor lets through. The store reads the same field, so someone on an older app is not offered the plugin at all rather than handed one that breaks on them.

Using it

Click the droplet in the ribbon, or run Water tracker: Open view from the palette.

  • Drink. The bottle shows the day you are editing against your goal, which is today unless you have moved. Tap it to add one cup, or use the quick buttons for other sizes. There is an undo for the last cup of that day.
  • Analysis. Streak, how often you hit the goal, your daily average, best day, the weekday pattern, a month-by-month heatmap, and which cup sizes you actually reach for.

Filling in a day you forgot

The row at the bottom of the Drink tab moves the day you are editing: the chevrons step one day back or forward, and touching a weekday in Last 7 days jumps straight to that day. The weekday goes bold moves to the day you are editing, and the 30-day strip marks that day in a row of its own beneath the bars, where it cannot crowd them, which is what tells you which day the bottle above is showing. The marker sits under today as well as under any day you step back to, so there is never a stretch where you are looking at the strip and nothing says which column is yours.

  • A cup logged into a day that has already gone by is stamped 23:59 of that day, the last minute of it a forgotten drink can honestly belong to. Logging into today keeps the real clock time.
  • Forward stops at today, because a cup claimed for a day that has not arrived is not a record.
  • The 30-day strip moves to keep the day you are editing on screen. Once that day is out of the trailing range the strip runs forward from it instead of ending on it, so the day you are filling in and its marker are both in the first cell where you can see them, and the heading reads Days from 2026-08-20 rather than claiming to be the last 30. The 7-day strip stays where it is, so the bold weekday only shows while that day is inside it.
  • The palette commands carry on working on today whichever day you have selected, which is what their names promise.

Palette commands:

Command What it does
Water tracker: Open view Opens the sidebar view
Water tracker: Add a cup Adds one cup of the configured tap size
Water tracker: Undo the last cup of today Removes today's most recent entry

Settings

Setting Default Notes
Data folder Water Tracker One YYYY-MM.md file per month inside it
Daily goal 2000 ml Drives the bottle, the graduations and the analysis
One tap of the bottle 250 ml What a tap on the bottle adds
Quick buttons 150, 250, 500 Up to four
Bottle Slim The four drawings below
Unit shown ml Display only; the file keeps millilitres

The graduations printed on the glass follow your goal rather than being fixed marks: for a 2000 ml goal they read 500 / 1000 / 1500, for 2500 they read 600 / 1200 / 1800, and each line sits at the height its own volume actually reaches. Change the goal and the bottle redraws.

The bottles

Slim glass bottle · Round flask (a straight-mouthed bottle with a swing-top clasp) · Sport bottle · Flat glass

To see them without opening Obsidian. The argument is the style id — slim, round, sport, tumbler:

npm run silhouette              # all four, half full
npm run silhouette -- round 1   # one of them, full
npm run silhouette -- tumbler   # the flat glass, half full

Development

npm install
npm test           # vitest
npm run typecheck  # tsc --noEmit
npm run build      # bundle, then copy into your dev vault and enable it there
npm run dev        # the same, watching

npm run build deploys into the vault named by TEST_VAULT at the top of build.js, and switches the plugin on in that vault's community-plugins.json. Point it at a scratch vault before you build the first time.

The bundle is built with esbuild and imports nothing at runtime beyond obsidian: moment, debounce, Notice, Setting and friends all come from the host.

Releasing

The version lives in manifest.json and nowhere else, because that is the file Obsidian reads to decide an update exists, and because the store hands out files from the GitHub release whose tag equals that version. The two have to agree, and only x.y.z is understood: no leading v, no -rc.1, no +build.7. package.json is made to agree with the manifest rather than being edited along side it:

npm run version-bump            # manifest.json is the source of truth, package.json follows
git tag -a 0.1.0 -m "0.1.0"    # the tag is the version itself, nothing else
git push origin 0.1.0

Pushing a tag runs .github/workflows/release.yml. It installs, typechecks, tests, builds, then stops unless the tag and manifest.json name the same version; then it signs the build with a provenance attestation and opens a draft release carrying main.js, manifest.json and styles.css. You read the assets, write the notes, and press Publish. Draft on purpose: a draft release that turns out wrong is yours to delete, while a published one has already told every installed copy of this plugin that there is an update.

Every tag starts a run, including a mistyped one, and a mistyped one goes red rather than being filtered out in silence - a tag that quietly matched nothing would leave you looking at a tag with no release behind it and no clue where the release went.

Before you spend a tag, the gates in that workflow can be run here:

npm run release-dry-run

It takes its steps out of the workflow file rather than from a second list of them that could fall out of step, and runs the ones that belong to this machine under the environment Actions hands a workflow, so the tag expression is exercised the way CI writes it and not merely the script behind it. Two kinds of step are left alone: the ones that belong to a runner (checkout, setup-node, the attestation), and the one that publishes - that step is recognised by what its script says rather than by what it is named, so renaming it does not make it runnable, because a rehearsal that could publish is not a rehearsal. npm ci is skipped unless you pass --install, since it wipes node_modules and wants the network. It runs against your working tree rather than a clean checkout, so it is proof that the commands and their order are right, not a replacement for the run.

The first time, one setting outside the file is needed: in the repository, Settings → Actions → General → Workflow permissions → Read and write permissions. Without it the attestation step is refused, with an error that says nothing about what it wanted.

The same build by hand:

npm run release    # writes main.js and styles.css at the repository root, both git-ignored
npm run audit      # the manifest check on its own
npm run app-version # the declared floor against the APIs the code really calls

They sit at the root because that is where the workflow uploads and signs them from, which keeps the names in the release exactly the three names the store downloads.

In release mode the manifest audit is fatal rather than advisory: a missing field, a version that drifted from package.json, an id containing obsidian, a missing README.md or LICENSE, or an isDesktopOnly: true that contradicts this plugin's iOS support all stop the build. Each of those costs a user a broken install or a reviewer a rejected submission rather than a red build. Day to day npm run build keeps the same checks as warnings, except an id mismatch with the folder Obsidian loads, which is fatal there too: that one makes Obsidian run a stale copy of the plugin and say nothing at all.

One more thing the store does that surprises people: the community directory reads manifest.json at the HEAD of your default branch, so the committed file is part of a release, not just the tag.

npm run app-version checks the other half of the version story. It asks the TypeScript compiler which Obsidian APIs the code actually reaches, reads the @since tag above each one out of the installed typings, and fails if any of them arrived after the declared floor. That is not a linting nicety: a method the app does not have yet is undefined at runtime, so calling one is a crash on an older install rather than an error at build time. The release build runs it, so the workflow needs no step of its own, and in development it warns instead of blocking, because a stale floor does not stop you working on the artwork.

Worth knowing

  • No reminders. Obsidian's plugin API has no notification surface that also works on iOS, so this plugin deliberately does not promise one.
  • Today means your local day. The date and time come from the device clock, not UTC.
  • Analysis reads a 90-day window, so a streak longer than a chart's worth is not cut short.
  • Files are shared between devices, so the vault's own sync (Obsidian Sync, iCloud, …) is what carries your history between them.

License

Apache License 2.0. See LICENSE.

HealthExcellent
ReviewPassed
About
Log water in cups and watch an animated bottle fill as you drink, with four bottle designs and phone-friendly surface animation. Store your full history as plain Markdown (one file per month, one table per day), recomputing totals, streaks and charts from the table rows so data stays human-readable and remains intact if the plugin is removed.
TablesChartsSidebar
Details
Current version
0.1.1
Last updated
2 days ago
Created
2 weeks ago
Updates
2 releases
Downloads
18
Compatible with
Obsidian 1.13.7+
Platforms
Desktop, Mobile
License
Apache-2.0
Report bugRequest featureReport plugin
Author
PassengerC07PassengerC07drbanshan
GitHubdrbanshan
  1. Community
  2. Plugins
  3. Tables
  4. Banshan Water Tracker

Related plugins

Notion Bases

Turn any folder into a database — table, kanban board, gallery, calendar, timeline and list views powered by frontmatter.

Sheet Plus

Create Excel-like spreadsheets and easily embed them in Markdown.

Macros

Nutrition and food tracker for your notes. Log meals, calories, macros and micronutrients. Search foods by name or barcode via FatSecret, USDA & Open Food Facts. Chart your diet & weight loss.

Notebook Navigator

A better file browser and calendar inspired by Apple Notes, Bear, Evernote and Day One.

Tag Wrangler

Rename, merge, toggle, and search tags from the tag pane.

Advanced Tables

Improved table navigation, formatting, and manipulation.

Flexplorer

Enhance the file explorer with custom sorting, pinning, and hiding.

Vertical Tabs

Offer an alternative view that displays open tabs vertically, allowing users to group and organize tabs for a better navigation experience.

Checklist

Consolidate checklists across all files into a single view.

Recent Files

Display a list of recently opened files.