ZenNotes 2.74.0 makes every record of a database linkable at once, adds next and previous tab keys that work with Vim off, opens Quick Capture on the display you are working on, and lets a link to a missing day create that day's daily note. Hovering a day in the calendar now shows its note the way it reads, and long notes draw correctly as soon as they have loaded.
Released from 9e2c651c through #978 on 2026-10-22. All installers are verified.
Features
- Create pages for all records. A database record can be linked once it has a page, and a page used to be made only by opening its record, one at a time, so a database converted from a CSV had nothing to link to (reported on Discord by ThatDwayne). Choose Create pages for all records from the database's new ⋯ menu, from the command palette, or press
Oin the grid in Vim mode: every record without a page gets one in the database folder, with its properties as frontmatter and its title as the heading. Records that already have a page keep it, a page file already in the folder under a record's name (one a script wrote, say) is linked instead of copied, and rows with an empty title are left out. It asks first and says what it will do. From the terminal,zn base pages "<database>"does the same, with--dry-runto see it first. It is new in zn 0.10.0, which this release bundles. - Next and previous tab, with Vim on or off (#973, thanks to @er-sarjan). Ctrl+PageDown and Ctrl+PageUp (Cmd+Option+Right and Left on macOS) step through the open tabs in the same order as
gtandgT, across panes, and wrap at either end. The command palette has Next Tab and Previous Tab. Ctrl+Tab stays Switch to previous note; rebind it under Settings → Keymaps if you would rather it cycle tabs. - A link to a missing day creates its daily note. Following
[[2026-11-03]]to a day that has no note yet creates that day's daily note in your daily notes folder, from your daily template, the way the calendar does, so it shows up on that day. Weekly and monthly titles work the same way. Before, the link made a plain note in the Inbox that the calendar never counted. A link that names a folder still makes a plain note there. - zn 0.10.0 is bundled. On macOS and Linux, the
znthat ZenNotes installs is now 0.10.0. It addszn base pages, the terminal side of Create pages for all records, and carries 0.9.2: a second$on a wrapped line reaches the end of the line, and three backticks make a code fence.
Fixes
- A click below a short note keeps the keyboard in the editor (#970, thanks to @vlcinsky). A click in the empty space below the last line, above the first, or beside the text column on a wide window gave the keyboard to the editor's padding, so Vim's keys did nothing and the editor looked frozen until a click on the text. Such a click now puts the cursor where it points (the end of the note below it) and keeps the keyboard in the editor, in every editor, with Vim on or off.
- Ctrl+Shift+Z redoes on Windows (#967, thanks to @lilitdn). The editor's menu showed Redo as Ctrl+Shift+Z, but on Windows only Ctrl+Y redid. Both work now.
- Quick Capture opens on the display you are on (#976, thanks to @numenbit). With more than one display, the Quick Capture hotkey always opened the panel on the display it was first shown on. It now opens on the display under the pointer, in the same spot (centered stays centered, a corner stays a corner), and back on a display it returns to exactly where it last was. A panel already on screen, pinned say, stays where it is.
- Hovering a day in the calendar shows its note. The calendar's hover card ran the whole note into one paragraph, cut off after four lines (reported on Discord by Dave). It now shows the note drawn the way it reads, headings, lists and task boxes on their own lines, beside the calendar instead of over it.
- An edited Daily Note template fills new daily notes. After editing the built-in Daily Note template, every new daily note came out as its title and nothing else, until the template was reset (reported on Discord by Dave). The edited template now applies to new daily, weekly and monthly notes, and Settings shows it instead of "[Missing template]".
- Collapsed callouts in long notes start folded (#853). A
> [!type]-callout far into a long note, past what the editor reads in its first moment (about 2 MB on an M-series Mac, less on slower machines), opened expanded. It now folds as soon as the editor reaches it, without closing one you opened or folding over the cursor. - Long notes draw correctly as soon as they have loaded. The editor reads a long note in time-limited chunks, and several parts of it drew from the partial result and did not redraw when the rest arrived: code in the body font with no language label, list lines without their hanging indent, heading arrows on
#comment lines inside code, hashtags, template tokens, highlights, wikilinks and task chips styled inside code. They redraw the moment the read finishes. A diagram being edited keeps its last good drawing through such a read instead of flashing an error. - Heading fold arrows are cheaper on long notes. At the top of a 3 MB note, the arrows cost about 0 ms per cursor move instead of 44 ms, and a whole cursor move takes 79 ms instead of 120 ms.
For contributors
- Cut-parse redraws (
c9502598,2f8c8254): eight live-preview plugins (code block font and flair, hashtags, live template tokens, heading arrows, highlights, list indent, wikilinks) andcm-task-metadataalso rebuild whensyntaxTree(update.startState) !== syntaxTree(update.state), following10597fe9; each has a tree-only test (the markdown language swapped in through a compartment) that fails without it.calloutFoldingis deliberately not one of them. - Heading arrows (
abcb3ea0): whether a heading folds depends only on the next line, and the section end is computed only when a fold starts at the heading's line end. - Callout folds (
bf26b7ab):cm-callout-foldkeeps the callouts still waiting to fold, mapped through edits, and folds each once the parser has read past it; never over the caret, never one the reader opened or edited first. - Diagrams through a cut parse (
ab96e797): while the tree is incomplete, memories of fences past where the parse stopped are kept until a tree reaches them again; the stop is the end of the tree's last block, since the note grammar pads a cut tree to the note's length. - Scroller clicks (
1fdbe581):scrollerClickFocus(lib/cm-scroller-click-focus.ts) handles a left press whose target is.cm-scrolleritself (its 20vh bottom padding and the margins of the capped column), places the caret throughposAtCoordsand focuses the content; in all six editors. - Redo on Windows (
0305e830):appHistoryKeymap(lib/history-keymap.ts) addswin: Ctrl-Shift-zto CodeMirror's history keymap; the test sets the Windows platform before CodeMirror loads. - Quick Capture placement (
56faa5ab):quickCaptureBoundsOnDisplay(apps/desktop/src/main/quick-capture-placement.ts) maps the panel's center proportionally between work areas and prefers the spot it last had on the target display;showQuickCaptureWindowapplies it only to a hidden panel. - Date links (
ee2fd2a0):dateNoteForTitle(vault-layout.ts) matches a title against the current daily, weekly and monthly patterns (one date only);create-note-from-link.tssends a match toopenDailyNoteForDateand its weekly and monthly twins. - Tabs (
d06cf66d):tabs.next/tabs.previousin both keymap lists,getTabStepTarget(open tabs only, no recent-note fallback) inbuffer-navigation.ts, palette entries, and a VimNav guard so the sidebar's arrow handling leaves the chords to the app. - Calendar preview (
27771b67): the calendar reusesNoteHoverPreview, anchored at the panel's left edge; the preview now says "Empty note" for an empty body instead of loading forever. - Templates (
6b230681):findTemplate(shared-domaintemplate-files.ts) lets an edited copy answer for the built-in id it replaces; the periodic note creators, the Settings picker and workflow template steps use it, and the picker stores an edited copy by the built-in's id (templateSettingId). - Record pages (
de82278e,ad5e52d9):planRecordPagesandrecordPageToAdopt(shared-domaindatabase-records.ts), the store'screateAllRecordPages, the ⋯ menu inDatabaseView, the palette entry, andOinDatabaseTableView(Vim mode only).openRecordPagelinks an unmapped page file under the record's name instead of writingTitle 2.md. zn mirrors the rules and the candidate names ininternal/database(ZenNotes/tuiafd8a35,ced7926). - Tests (
5d1de89f,b24efded): editor test mounts end on a complete parse instead of nudging afterforceParsing, so they pass whether or not a parse runs out of its 20 ms slice. - Bundled zn 0.10.0, verified against
zn-release-1(fe1bec33); What's New 2.74.0 (47a1bba7); version bump (37b314e0);@modelcontextprotocol/sdk1.32.0, the first release fixing the advisories that failednpm audit --audit-level=high(9e2c651c, only that package moves in the lockfile).
Demos
Screenshots of this release on the release build, attached to this release:
Create pages for all records, from the ⋯ menu of a database of five books: it asks first and says where the pages go.
Next Tab and Previous Tab in the command palette, with their keys.
A link to a missing day: following [[2026-11-03]] offers to create it as the daily note.
Hovering a day in the calendar: October 28's note, drawn the way it reads, beside the calendar.
Verification
How to test locally. Build once with npm run build --workspace @zennotes/desktop and launch with isolated stores: ZENNOTES_USER_DATA_PATH=$(mktemp -d) ZENNOTES_CONFIG_DIR=$(mktemp -d) npx electron apps/desktop/out/main/index.js.
- Pages for every record. Put a folder
Books.basein the vault with adata.csvof a few rows (id,Title,Author), and a note linking[[Dune]]. Open the database, choose ⋯ → Create pages for all records, and confirm: a page appears inBooks.basefor each titled row, and the link in the note turns from dashed to live. Run it again: it says every titled record already has a page. With Vim on,Oin the grid does the same. Before: each record had to be opened to be linkable. - Next and previous tab. Open four notes as tabs (double-click each in the sidebar). Press Ctrl+PageDown (Cmd+Option+Right on macOS) a few times: the tabs cycle and wrap; Ctrl+PageUp goes back. Turn Vim off and repeat, with the focus in the editor and in the sidebar. Before: only Vim's
gt/gTstepped tabs. - A link to a missing day. Turn on daily notes (Settings → Vault → Periodic notes), write
[[2026-11-03]]in a note and click it: it asks to create the daily note, and the note lands in your daily notes folder, from your template; the calendar shows it on that day. Before: a plain note in the Inbox. - Click below a short note. With Vim on, open a short note, press
Escape, click well below the last line, then pressAand type: the text lands at the end of the last line. Before: nothing happened until you clicked on the text. - Quick Capture on two displays. With two displays, put the pointer on the second one and press the Quick Capture hotkey: the panel opens there. Move the pointer back and press it again: it returns to the same spot on the first display. Before: always on the first display it opened on.
- Calendar hover. With daily notes on, hover a day that has a note in the calendar panel: the note shows with its headings and lists, to the left of the calendar.
- Edited Daily Note template. Settings → Templates, edit the built-in Daily Note template (rename Focus), then double-click a future day in the calendar: the new note has your edited sections. Settings → Vault → Periodic notes shows the template, not "[Missing template]".
- Redo on Windows. In the editor, type, press Ctrl+Z, then Ctrl+Shift+Z: the text comes back.
Distribution channels
- GitHub release: installers for macOS (Apple silicon and Intel DMG and zip), Windows (x64 and ARM64 installer and zip) and Linux (x64 and arm64 AppImage, deb, rpm, pacman, tar.gz), with five update manifests; the four screenshots in Demos are attached too.
- AUR:
zennotes-bin2.74.0-1 (AUR cloneb7a6086, repofc5fb4e6), pinned toZenNotes-2.74.0-linux-x64.tar.gzSHA-256ffa936e5…c148, after the tarball check confirmed the bundled CLI folder is world-readable. - Nix:
packaging/nix/release-data.jsonlifted from the update workflow (run 39829748701, bot PR #980 closed) as9840bca8, and nix-build on main passed. - nixpkgs: NixOS/nixpkgs#575797 now proposes 2.70.0 -> 2.74.0 (
9e8d39b2), rebased on master; the source hash comes from the tag tarball, and the same command reproduces master's 2.70.0 hash. - Homebrew:
zennotes2.74.0 in the tap (ece9ab9), mirrored inb94f1f88; both DMGs' SHA-256 match the cask and GitHub's digests;brew styleclean. - Website: ZenNotes/website#88 merged with the 2.74.0 entry and its four screenshots, the docs for record pages, next and previous tab, date links and the calendar's day preview, and the zn docs at 0.10.0. Laravel Cloud deployed it at
387c4e68, and the live check passed: /releases leads with 2.74.0, all four screenshots match the local files byte for byte, /docs carries Ctrl+PageDown andzn base pages, and /tui/docs names zn 0.10.0. - Server and Docker: ZenNotes/znserver v2.74.0 pins the browser app
web-2.74.0-web.h0639a421cbb4a915(1ff0e28, ZenNotes/znserver#40); all five binaries matchSHA256SUMS, and the released darwin-arm64 binary served the 2.74.0 app on a scratch vault.adibhanna/zennotes:2.74.0,2.74andlatestshare one digest,sha256:a9830109…(linux/amd64 and linux/arm64); the README's install commands follow (ZenNotes/znserver#41). - zn CLI: ZenNotes/tui v0.10.0 (
ced79267, ZenNotes/tui#15) withzn base pages, its Homebrew formula (tapc3627ec), and the same release bundled in this one. - Boundary packages:
core-2.74.0-core.h8a474e2e95d7c7eaandweb-2.74.0-web.h0639a421cbb4a915, built by CI from9e2c651c; the web package is published as a pre-release, and core is published once both phones shipped on it. No viewer this time: nothing in 2.74.0 changes how a published note renders. "Latest" still names v2.74.0. - Phones: iPhone 1.30.0 (build 46, ZenNotes/zennotesios#72, on core 2.74.0) is Waiting for Review in App Store Connect, set to release automatically; Android 1.1.44 (versionCode 47, ZenNotes/zennotesandroid#127) is in Google Play review at 100% rollout, with no devices lost. Both shells carry Create pages for all records in a database's ⋯ menu, which was checked at phone size before submission.
Release validation
Every CI failure since 2.73.0 was read before this release: ci-sweep.py v2.73.0 found none. hazard-scan.py --since v2.73.0 found no hazards.
Release-time gates, in a clean checkout with its own npm ci at 9e2c651c: typecheck 8/8 with no turbo cache, test:run with no cache (shared-domain 2,054, app-core 3,394, desktop 1,190, quicklook 15 and the rest), and a fresh build:prod. Pack: Developer ID signed; packaged launch check: page target and drawn app in 1.6 s, version 2.74.0. Smoke suites vim-editor, sidebar-vim and editor-improvements pass on the first run. Record pages, next and previous tab, the date link and the calendar hover were driven in that build over CDP with isolated stores, which is where the screenshots come from. The zn 0.10.0 manifest was verified against zn-release-1 and pinned byte for byte. The production dependency audit failed at high on @modelcontextprotocol/sdk 1.31.0 before the cut and was fixed in 9e2c651c (1.32.0, the first fixed release, only that package moving in the lockfile).
Release PR #978: all 10 checks passed on the first run. CI on main for 9e2c651c (run 39825421761): all six jobs green before the tag, and CodeQL too. Release run 39827696396: all six jobs green (GitHub kept showing the macOS job as running after its log had ended at 18:33 with latest-mac.yml uploaded and the run had concluded success); verify-installers.py ALL GOOD on the five manifests by SHA-512; the app in both DMGs is Notarized Developer ID with a valid stapled ticket. npm run verify:channels -- 2.74.0: every channel serves v2.74.0 (Homebrew, AUR, Nix and the website's eight download buttons).
After the tag, CI on main for the Homebrew commit b94f1f88 (packaging files only) went red twice. The production dependency audit now fails at high on DOMPurify 3.4.14, from advisories published that hour (a critical SAFE_FOR_TEMPLATES bypass, a high IN_PLACE one, and three low): ZenNotes uses neither mode nor the XHTML parser, and its one hook only drops attributes, so 2.74.0 is not exposed; both phones already ship 3.4.17. The one-package fix (dompurify 3.4.17, the first fixed release) follows in its own commit on main. Build (windows-latest) failed on three file-system tests in different worker processes timing out together (note-docx at 17 s, a file that took 181 to 252 ms on both earlier Windows runs of the same code), a stall of that runner rather than of the code; its re-run passed, with note-docx back at 298 ms. Every other job of that run, and of the AUR commit's run (fc5fb4e6), passed.



