Skip to main content

Working Model Overview

Literature flows in, insight flows out. This page explains the loop behind that sentence — what data moves at each station, what syncs, and what stays yours alone. Read it once and every ZotFlow feature will have an obvious place.

The Loop, as Data Flow​

① In — Zotero to local cache​

ZotFlow pulls items, collections, attachments, and annotations from the Zotero Web API into local IndexedDB. After the first sync you can browse, search, read, and annotate fully offline — the network is only needed for syncing and downloading attachments (from Zotero storage or your WebDAV server). Cached attachments are managed with a configurable LRU size limit.

Each library has its own sync mode:

ModeBehavior
BidirectionalPull + push. Requires an API Key with write permission
Read OnlyPull only. Local annotations stay local and never reach Zotero
IgnoredCompletely skipped during sync

What flows back to Zotero? Annotations (add/edit/delete), Item Notes (create/edit/delete), and tags. Item metadata, frontmatter, and persist regions never flow back. When the same field changes on both sides between syncs, a field-level diff viewer lets you pick the winner per field — no wholesale overwrites.

Practices that reduce conflicts: keep your primary editing side fixed (either Obsidian or Zotero), and sync before editing from a second device.

② Read — two readers, two destinations​

The built-in reader uses Zotero's rendering engine with Obsidian-matched theming, in two modes:

ModeWhat it readsWhere annotations go
Library ReaderAttachments synced from ZoteroIndexedDB → Zotero (via bidirectional sync)
Local ReaderLocal PDF/EPUB/HTML in vaultCo-located .zf.json sidecar — never Zotero

Annotation changes ripple forward automatically: the affected Source Note re-renders on a ~2s debounce. (Local Reader is enabled via Settings → General → Overwrite PDF/EPUB/HTML Viewer.)

③ Distill — content ownership inside a Source Note​

Each Zotero item gets exactly one auto-rendered Markdown file — a stable, addressable node in your knowledge graph. The file is a projection of the local cache through your template, which raises the central question of ZotFlow's note model: when the template re-renders, what survives?

The answer is ownership. Every piece of content in a Source Note has one of three owners:

OwnerContentOn re-renderSyncs to Zotero?
Templatemetadata, annotation excerpts, headings, structureregenerated — don't write here— (it comes from Zotero)
Zotero (shared, editable)Item Note regions, annotation comment regionsyour edits preserved, written to IndexedDB✅ on next sync
You (local)persist regions, custom frontmatter fieldspreserved verbatim❌ never
  • Zotero-owned regions are fenced by ZF_NOTE_* / ZF_ANNO_* markers with a 🔒 lock toggle. Editing them is editing the Zotero object — the change flows back on sync. Item Notes can equivalently be edited in a standalone Note Editor tab; both entry points write the same record.
  • Persist regions (ZF_PERSIST_* markers, declared in your template) are the place for your own words inside the source's page: reading notes, verdicts, todo lists. They survive every re-render and never leave your vault. If a region disappears from the template, its content moves to a clearly-bounded "Orphaned persist regions" section — never deleted.
  • Custom frontmatter fields you add by hand are preserved as-is; template-defined fields follow the ?? merge prefix rules (see Source Note).

That table yields a simple decision guide for where to write:

Should sync to ZoteroStays in your vault
About this one sourceItem Note — annotation extensions, paraphrases, summaries you want on every device Zotero reachesPersist region — private reading notes, verdicts, workflow scratch
Across sources— (Zotero has no cross-item note concept)Standalone Obsidian note — surveys, comparisons, arguments; wikilink back to Source Notes

Source Notes re-render automatically: after syncs that change an item (version-aware), after annotation changes (forced, debounced), after Item Note edits, or manually from the Tree View / command palette. Whatever the trigger, the ownership rules above decide what survives — by construction, everything that is yours does.

Insert citations while writing by dragging items from the Tree View or typing a trigger character — output as Pandoc keys, wikilinks, footnotes, or real CSL styles rendered by citeproc (see citation / bibliography filters).

Links keep their allegiance sorted: Item Notes store native zotero:// links (so they navigate Zotero's reader when opened there) while Obsidian displays ZotFlow links that open the built-in reader. Zotero's embedded annotation highlights and citation markers are clickable too. Citations and links from your drafts jump straight back into ② and ③ — closing the loop.

Cross-Cutting Principles​

These apply at every station:

  • Template-first. Nearly all user-visible output — note paths, Source Note bodies, citation formats — is rendered by LiquidJS templates you can edit. If you don't like the default output, change the template, not your workflow. See the Template Guide.
  • Offline-first. Everything synced is cached locally; the loop keeps running without a network.
  • Two panels. The Tree View (sidebar) is navigation: browse, search, drag-to-cite, open. The Activity Center (ribbon icon) is control: sync, tasks, logs, template preview, CSL styles.
  • Privacy by default. No telemetry. Network requests go only to the Zotero API and your configured WebDAV server. Credentials live in Obsidian's platform-native SecretStorage, never in synced data.json.

Why This Design​

  1. Closed loop — reading, annotating, and writing happen in one tool, zero context switching.
  2. Stable references — every source has an always-present, addressable page.
  3. Clear ownership — you always know what survives a re-render and what reaches Zotero: template content is regenerated, shared regions sync, your local content is untouchable.
  4. User control — templates put output formatting in your hands, with no hardcoded workflows.

Related Entry Points​