Track a physical wine cellar inside Obsidian — by note, vintage, lot and drinking window.
Every bottle you own lives in a normal Markdown note. The plugin reads and writes those notes, so your cellar stays yours: no database, no account, no network requests. Uninstall the plugin and the data is still there, readable, in plain text.
- Per-lot tracking. A wine you bought twice is two lots, each with its own price, purchase date, shelf and quantity. Drinking three bottles from the 2019 case doesn't touch the case you bought last year.
- Phased drinking windows. Split one lot across several windows — drink 3 in 2027–2031, hold 3 for 2032–2036 — and the dashboard reports each phase separately.
- Status views. Dashboard, monthly and sidebar views showing what's ready, what's overdue and what's still cellaring.
- Tasting log. Log a tasting with a score and notes, into your daily note.
- Optional finance logging. If you enter a purchase price, a spending line is written to your daily note.
Desktop only. Requires Obsidian 1.2.8 or later.
Settings → Community plugins → Browse → search for Wine Tracker → Install → Enable.
Download main.js, manifest.json and styles.css from the latest release and drop them into VaultFolder/.obsidian/plugins/wine-tracker/, then reload Obsidian and enable the plugin.
- Enable the plugin.
- Open settings and set Wine notes folder (default
Wine/Wines) and, if you want tasting or spending logs, Daily notes folder. - Run Wine Tracker: Add bottle from the command palette, or click the wine glass in the ribbon to open the dashboard.
| Command | Description |
|---|---|
| Add bottle | Add a new purchase lot to inventory |
| Consume bottle | Drink a bottle and log a tasting note |
| Edit lot | Update any field on an existing lot |
| Log tasting | Log a tasting without consuming from inventory |
| Refresh prices/windows | Update current prices and infer missing drinking windows |
| Open dashboard | Open the dashboard note |
| Rebuild index | Re-scan all wine notes and rebuild the in-memory cache |
Opens a modal. Only four fields are required: producer, cuvée, varietal, and vintage. Everything else is optional.
Optional fields: qty (defaults to 1), purchase date, purchase price, shelf location, drinking window (start/end years), phased drinking windows, region, country, style, bottle size, source/merchant, current price, gift toggle, notes, rebuy toggle, do-not-buy-again toggle.
What happens on save:
- Creates the wine note at
{wine notes folder}/{{producer}} - {{cuvee}} ({{grape}}).mdif it doesn't exist - Upserts flat frontmatter (
wine_id,producer,cuvee,grape,region,country,style,rebuy,do_not_buy_again) - Appends the new lot to the matching vintage in the
wine-inventoryblock (or creates the vintage entry) - If a purchase price is present, writes a spending entry under your finance heading in today's daily note
- Rebuilds the index cache
Phased drinking windows — enter one line per phase in the Window phases field:
3,2027,2031
3,2032,2036
Each line is qty,start,end. Use qty,before YYYY for a "drink before" style window.
If no window is entered and the varietal/style is recognised, a window is inferred automatically.
Three-step modal:
- Choose wine — searchable list of wines with stock remaining
- Choose lot — shows qty, shelf, purchase price, and window phases for each lot with stock; lot choice is always explicit
- Confirm & log tasting — enter an optional score (/5) and tasting notes
On confirm:
- Decrements the lot qty by 1 (zero-qty lots are kept as consumed history, never deleted)
- Writes a tasting stub under your tasting log marker in today's daily note:
- [ ] #log/wine/tasting-note [[St Hallett Blockhead]] 2021 4/5 %%wine-lot:2021-a%%
- Plush fruit, ready now.
Three-step modal: choose wine → choose lot → edit form.
Editable fields: qty, purchase date, purchase price, current price, shelf, source, bottle size, drinking windows (same qty,start,end format as Add bottle), notes, gift toggle.
Writes back to the wine note and rebuilds the cache.
Quick-log without consuming from inventory. A dropdown pre-fills wine, vintage, and lot ID from cached stock. Manual text fields are available for wines not in inventory (e.g. tasting at a restaurant).
Writes the same tasting stub format to today's daily note as Consume bottle.
Updates current prices and fills in missing drinking windows for a single wine note. Everything is computed locally — the plugin never contacts a price service.
If a wine note is open when you run the command, it opens directly on that note. Otherwise it shows a searchable picker.
The proposals screen shows every lot in the note. For each lot:
-
Current price field — pre-filled using this priority order:
- Existing value — if
current_priceis already set in the note, it is preserved (you can still edit it) - Heuristic estimate — purchase price compounded at an annual appreciation rate based on grape/style (Shiraz/Cabernet/Nebbiolo: 5%, Pinot Noir/Riesling: 4%, sparkling: 6%, fortified: 7%, default: 3%), calculated from the purchase date or vintage year
- No estimate — if no purchase price exists, the field is blank for manual entry
- Existing value — if
-
Proposed window — if the lot has no drinking window defined, an inferred window is shown (using the same heuristic as Add bottle). This is added on save; existing windows are never overwritten.
Nothing is written to the note until you hit Save.
Dashboard — sections for:
- Drink now — wines inside their drinking window
- Overdue — wines past their window
- Cellaring — wines not yet at window start
- All inventory — every lot with stock
Monthly block — add a wine-plugin-monthly code block to any monthly note. The reference year is read from the note's filename (YYYY-MM.md), so viewing a past month shows the status as it would have been then.
Sidebar — shows Drink now and Overdue counts in the right panel.
All views have a text search (filters by wine name, producer, region, country) and a status dropdown filter.
| Status | Condition |
|---|---|
| Cellaring | Reference year is before window start |
| Drink now | Reference year is inside the window |
| Overdue | Reference year is past window end |
| Unknown window | No window defined — shown as drinkable but filterable |
Phased windows split a lot's quantity across multiple statuses. Example: a lot of 6 with phases 3 × 2027–2031 and 3 × 2032–2036 shows as "Drink now: 3, Cellaring: 3" in 2028.
When a purchase price is entered in Add bottle, an entry is written under your finance heading in today's daily note:
## Finance
- [ ] #log/spending 84
- $84.00 USD #log/spending/alcohol/wine
- 3 x [[St Hallett Blockhead]] 2021
- Langtons
The #log/spending total on the root line is updated automatically. Finance logging only fires when a purchase price is present. If you don't want it, leave the purchase price blank.
| Setting | Default | Notes |
|---|---|---|
| Dashboard note path | Wine/Wine Dashboard.md |
Created automatically on first open |
| Wine notes folder | Wine/Wines |
All wine notes must live here |
| Flat inventory note path | Wine/Wine Inventory (flat).md |
Auto-generated table of all lots, queryable with Dataview or Bases |
| Daily notes folder | (empty) | Supports {{date:FORMAT}} placeholders |
| Daily note date format | YYYY-MM-DD |
Moment.js format for the daily note filename |
| Monthly notes folder | (empty) | Used by the monthly view |
| Monthly note date format | YYYY-MM |
Moment.js format for the monthly note filename |
| Tasting log marker | #log/review/daily-review |
Tasting notes are nested under the first line containing this text |
| Infer journal settings | on | Read daily/monthly folders from the Journals plugin |
| Currency | USD |
ISO code used to format prices |
| Finance heading | ## Finance |
Must match the heading in your daily note |
| Finance category path | alcohol/wine |
Tag path appended after #log/spending/ |
| Infer finance settings | on | Read the spending heading and currency from the Finance Tracker plugin |
Journal and finance settings are inferred on load from the Journals and Finance Tracker plugins if you have them installed. Turn the toggles off to manage the values yourself.
Inventory lives in a wine-inventory fenced block inside each wine note:
```wine-inventory
- vintage: 2021
lots:
- lot_id: 2021-a
qty: 6
purchase_date: 2025-03-10
unit_price: 28
current_price: 32
shelf: A1
source: Langtons
gift: false
notes: ""
bottle_size: ""
windows:
- qty: 3
start: 2027
end: 2031
- qty: 3
start: 2032
end: 2036
```Markdown is the only source of truth. The plugin cache is derived from the notes at runtime and can be rebuilt at any time with the Rebuild index command.
Wine Tracker makes no network requests. All prices, drinking windows and statistics are computed locally from your own notes.
node --check main.js
node --test tests/*.test.jsThe plugin is a single self-contained main.js with no bundler or local imports — all logic lives there.
Issues and pull requests welcome at github.com/arangutambo/wine-tracker.
MIT — see LICENSE.
If you find it useful, you can buy me a coffee.