Docs / Using the app / Documents
Documents
How Jotura stores PDFs, Word files and spreadsheets, mirrors them into searchable markdown, and keeps that mirror current as the originals change.
Documents
A Jotura vault is a folder of files, and not all of them are markdown notes. You can keep PDFs, Word documents, spreadsheets, presentations, images, code, and configuration files alongside your notes. Jotura treats each kind differently, and the difference matters when you want to search them.
For a document that Jotura can read text out of, such as a PDF or a Word file, the app writes a second file next to it. That second file is an ordinary markdown note holding the extracted text, and this page calls it the mirror. The original file stays untouched and opens in whatever application you normally use. The mirror is what full text search reads, so a phrase buried on page 40 of a contract turns up in the same search box as your notes.
What counts as a document
Only file types that the converter can pull real text from get a mirror. Everything else is stored as it is, because converting it would produce metadata noise rather than content.
| File type | Extensions | What Jotura does |
|---|---|---|
| Convertible document | pdf, doc, docx, ppt, pptx, xls, xlsx, odt, ods, odp, rtf, epub, msg | Stores the file and generates a markdown mirror beside it. See the note on msg below |
| Markdown note | md, markdown | Opens in the editor. Already searchable, so no mirror |
| Plain text and code | txt, rst, org, tex, json, yaml, yml, toml, xml, csv, tsv, css, scss, sass, js, mjs, ts, tsx, jsx, py, rb, rs, go, java, kt, swift, c, cpp, h, hpp, sh, bash, zsh, fish, ini, conf, env, sql, log, ps1, bat | Opens in a text editor tab. Indexed directly, so no mirror |
| HTML page | html, htm | Opens in a sandboxed preview tab with a source toggle. Indexed directly, so no mirror |
| Image | png, jpg, jpeg, gif, webp, svg, bmp, ico, heic, heif, avif, tiff, tif | Stored and displayed in notes. Never converted |
| Anything else | for example mp3, mp4, zip, exe, files with no extension | Left alone on disk. Jotura does not show these files in the file tree, does not index them, and does not upload them |
The extension test is case insensitive, so REPORT.PDF is treated exactly like report.pdf.
Two exclusions apply before the extension is even checked. Microsoft Office owner files, the transient ~$name.docx files Word leaves beside an open document, are ignored rather than converted. So is anything under a folder or file name that starts with a dot. The file tree, the search index and the conversion sweep all skip dot-prefixed entries, so a PDF stored in .archive/ is invisible to Jotura and never gets a mirror.
Outlook messages are a special case. The msg extension is convertible, but it is not one of the file types Jotura enumerates in the vault. A .msg file never appears in the file tree, is never picked up by a sweep, never appears in jotura ls-documents, and never uploads to sync. It is converted only when you import it explicitly through the app or through jotura import, and after that its mirror behaves like any other note while the .msg file itself stays hidden from the app.
HTML, CSV and TSV files were convertible in older builds and are not any more. They are first class text now, indexed from their own contents. A leftover machine generated mirror for one of them is deleted during a sweep, but only when the original file is still on disk and the mirror still carries its generated provenance. A mirror you have edited, or one whose original is gone, survives and needs deleting by hand.
Importing a document
Every route below copies the file into the vault, so the original on your desktop or in your downloads folder is untouched. If the destination already holds a file with that name, the import adds a numeric suffix before the extension, so a second report.pdf lands as report-1.pdf.
| Route | Where the file lands | Extra effect |
|---|---|---|
| Drag files from the operating system onto a folder row in the file tree | That folder | Conversion starts immediately |
| Drag files onto the file tree background | Your default document folder | Conversion starts immediately |
| Drag files into the editor | Your default document folder | Inserts a markdown link, [name](path), at the drop point |
| Paste files into the editor | Your default document folder | Inserts a markdown link at the cursor |
| Copy the file into the vault folder with Finder, Explorer or a terminal | Wherever you put it | The file watcher notices it and queues conversion |
jotura import | attachments by default, or the folder you name | Conversion runs as part of the command |
Documents dropped or pasted into the editor keep their original file name. On a multiple file drop into the editor, each link goes on its own line. Links are written relative to the note, and images are handled differently from documents. See The editor.
You cannot import into a share someone else has given you view-only access to. The app refuses the write, and jotura import exits with code 15, ReadOnlyShare. See Sync and sharing and Exit codes and JSON output.
The default document folder is attachments. Change it under Settings, Advanced, Files and folders. A value that is blank or that contains .. falls back to attachments.
| Setting | Effect | Default |
|---|---|---|
| Default document folder | Where dropped or pasted documents are stored, relative to the vault root | attachments |
The full list of settings is on the Settings reference page.
The searchable markdown mirror
The mirror takes the document’s full file name and appends .md. That keeps report.pdf and report.docx from colliding.
| Original | Mirror |
|---|---|
attachments/report.pdf | attachments/report.pdf.md |
attachments/report.docx | attachments/report.docx.md |
Projects/2026/budget.xlsx | Projects/2026/budget.xlsx.md |
The mirror is a perfectly ordinary note. It sits in the same folder as the document, it is indexed, it can be linked to, it appears in search results, and it syncs like any other note. The file tree hides the mirror’s own row so you do not see the same name twice, and clicking the document row opens the mirror. If the mirror does not exist yet, clicking the document row converts it first and announces the progress, then opens the result.
Jotura has no built in PDF, Word or spreadsheet viewer. Clicking a document opens its text mirror, not a rendering of the file. To see the real thing, use Open original externally, described below.
What is in the mirror
Every generated mirror starts with a YAML frontmatter block recording where it came from. The editor hides frontmatter in the visual view, so you see only the converted text. Toggle to source mode to see the whole file, including the block. The shortcut is Cmd/Ctrl+Shift+E, which only fires while the editor has focus, and the same toggle sits in the editor header and the command palette. See Keyboard shortcuts.
| Field | Meaning |
|---|---|
jotura_converted_doc | Marks the note as machine generated. Older mirrors use jotura_md_store |
source_path | The vault relative path of the document this came from |
source_content_hash | Hash of the document’s bytes at conversion time, used to detect a changed source |
converted_body_hash | Hash of the generated body, used to detect that you have since edited the note. Mirrors old enough to lack this field are always treated as unedited |
markitdown_version | The converter version that produced this text, or null |
converted_at | The conversion timestamp in UTC |
conversion_ok | Whether the conversion actually succeeded |
Finding documents by content
Because the mirror is a normal note, every search surface already covers it. Search for a phrase from a contract and the hit comes back as contract.pdf.md, with the surrounding text as the snippet. Opening the hit opens the mirror.
| Surface | Covers documents | Notes |
|---|---|---|
| Sidebar search pane | Yes, through the mirror | Keyword search only |
| Search page, Keyword mode | Yes, through the mirror | Cmd/Ctrl+Shift+F opens it |
| Search page, Semantic and Smart modes | Yes, through the mirror | Requires semantic search to be enabled first |
| Quick open (Cmd/Ctrl+P) | Matches file names, not contents | Matches the document and the mirror by name |
jotura search-documents | Yes | Returns the original document paths |
Full details of the three search modes are on the Search page. Files above 25 MB are skipped by the full text indexer, so a very large converted document may not be searchable even though its mirror exists.
Editing originals in their native applications
Jotura never edits a PDF or a spreadsheet itself. Right click the document in the file tree and choose Open original externally, and the operating system opens it in whatever application owns that file type. For HTML files the same menu item reads Open in browser instead.
| Context menu item | Shown for | Effect |
|---|---|---|
| Open original externally | Documents and plain text files | Opens the file with the operating system default application |
| Open in browser | html and htm files | Opens the file with the operating system default application |
| Reveal in File Explorer, Reveal in Finder, or Show in folder | Every row | Shows the file in the operating system file manager. The wording follows your platform |
| Copy path | Every row except the vault root | Copies the vault relative path |
When you save the document in that other application, the file watcher sees the change and queues a fresh conversion for that one file. The queue waits for one second of quiet before it runs, so a burst of saves collapses into a single conversion. This watcher route does not check whether the mirror is actually stale. It reconverts the file unconditionally, though it still skips a mirror you have edited.
The watcher only reacts to files being created or modified. A document renamed outside the app produces a rename event, which is not queued, so the renamed file gets its mirror from the next vault open or from a manual action in Settings.
While conversions run, the status bar at the bottom of the sidebar shows the single highest priority background job, formatted Converting {done}/{total} · {eta} left. Converting outranks embedding, indexing and syncing, and any other active jobs collapse into a +{n} badge with a tooltip.
Documents that arrive while Jotura is closed are handled on the next vault open. The app looks for documents whose mirror is missing or out of date and converts them in the background.
Editing the generated note
You can edit a mirror like any other note, and Jotura will not overwrite your edits. Protection is not a stored flag. Every time Jotura reads a mirror it compares a hash of the current body against the converted_body_hash recorded in the frontmatter. A mirror whose body no longer matches is skipped by every sweep and by Reconvert all, for as long as your edits are on disk.
The same protection applies when a note you wrote happens to already occupy the mirror’s path, because that note carries no conversion marker at all.
To get the machine generated text back, delete or rename your version and run a conversion again, which writes a fresh mirror. Restoring the body to exactly the generated text would also lift the protection, but in practice deleting the file is the reliable route.
Two consequences are worth knowing. Clicking a document whose mirror is protected announces that it was not converted because its note is user owned. And Settings cannot tell you a document is protected: the conversion status row counts only converted, failed and pending documents, and a protected one falls into none of the three. jotura doctor prints a total alongside those counts, so a total larger than the three added together is the only visible hint.
Regeneration and staleness
A sweep looks at every eligible document in the vault, decides whether its mirror is out of date, and converts the ones that are. Never converted documents are always handled before retries, so a backlog of failures cannot starve a document that has never been read at all.
| Reason | What it means | Order |
|---|---|---|
Missing | The document has no mirror yet | Converted first |
SourceChanged | The document’s bytes no longer match the hash in the mirror | Second |
ConverterUpgraded | The local converter is a newer version than the one recorded in the mirror | Third |
PreviousFailure | The last conversion failed and is eligible for a retry | Last |
Two rules keep sweeps from spinning. A failed mirror is only retried when the converter is present, conversion is currently permitted, and either the mirror records no converter version or the local converter is strictly newer than the recorded one. A conversion blocked by a missing sandbox is never retried automatically, because it would fail identically every time.
Sweeps run automatically on vault open. You can also run one by hand from Settings, Advanced, Document conversion.
| Action | What it does |
|---|---|
| Converter | Status row reading Checking…, Converter ready (markitdown <version>), or Converter not available. The version here is the one stamped into markitdown_version |
| Conversion status | Reads N converted · N failed · N pending |
| Reconvert stale | Runs a sweep over every out of date document, including ones that have never been converted, with a progress bar |
| Reconvert all | Re-runs conversion for every document, protected mirrors excepted. Confirms first, because it is heavy for large vaults |
| Convert pending | Runs the same sweep as Reconvert stale, reporting a count rather than a progress bar |
| Show N failed | Lists the failing document paths. Appears only when at least one document has failed |
| Retry failed conversions | Sits inside that list. Re-runs the failed documents now, bypassing the automatic backoff |
Reconvert stale and Convert pending are worth reading twice, because their labels suggest different scopes. They compute an identical target list and differ only in how progress is reported.
Everything from Conversion status downwards is hidden when the converter binary is missing, and replaced by a row explaining that documents still import but stay unsearchable. A vault with no documents at all shows a single row saying so.
Vaults created by older versions kept their mirrors in a hidden .md_store folder. Jotura relocates those to the sibling layout automatically at the start of a sweep, and deletes orphans whose document is gone. You do not need to do anything.
The converter and its sandbox
Conversion is done by a converter binary that ships inside the Jotura installer. It runs as a separate short lived process, isolated by the operating system’s sandbox, and its output is written into the mirror.
| Platform | Sandbox used | Network denied |
|---|---|---|
| macOS | sandbox-exec | Yes |
| Linux | bwrap (bubblewrap), when it is on your PATH | Yes |
| Windows | A restricted token plus a Job Object | No |
The Windows sandbox blocks the converter from reading anything protected by your own user or group permissions, which covers your profile, your registry hive and the vault itself. It does not block network access, and it does not block locations readable by every account on the machine. jotura doctor says as much in its own output, reporting network NOT denied on Windows.
Sandboxing is on by default and conversion fails closed. Jotura treats the sandbox as unusable in two cases: when no sandbox is available on the system at all, and when a sandbox is present but fails a health check. The health check runs the real converter under the profile once per converter path, which catches a profile that lets the converter start and then breaks it mid run. In either case Jotura skips the conversion rather than parsing an untrusted file with your full account privileges, and writes a mirror explaining why.
| Setting | Effect | Default |
|---|---|---|
| Allow unsandboxed conversion | Convert documents without operating system sandboxing when no sandbox is available. Only enable it if you trust every document you import | Off |
Each conversion is bounded on every axis. Any run that trips a bound is terminated together with every process it started.
| Bound | Value |
|---|---|
| Wall clock timeout | 60 seconds |
| Converted output kept | Up to 32 MB |
| Diagnostic output kept | Up to 1 MB |
| Processor time and file size | Limited by the operating system, through resource limits on Unix and a Job Object on Windows |
When a conversion does not succeed
Jotura still writes the mirror, with conversion_ok: false and a short quoted explanation in place of the text, so the document is visible in the vault rather than silently missing. There are three wordings.
| Situation | What the mirror says |
|---|---|
| The converter is not installed | The document could not be indexed yet and will be converted automatically once the converter is installed |
| The sandbox is unusable and unsandboxed conversion is off | The document was not converted because no sandbox is available to isolate the converter. No automatic retry is promised, because there would not be one. The Reason line says whether no sandbox was found or the health check failed |
| Any other failure, such as a corrupt or password protected file | Conversion failed and will be retried automatically, with the reason quoted |
Settings shows an Unavailable badge on the Document conversion group when the converter binary is missing, and the group explains that documents still import but stay unsearchable until it is present. Reinstalling Jotura restores it. Failures are usually corrupt or password protected files, so Retry failed conversions is the right first move only after you have checked the file opens elsewhere.
Advanced environment variables
These are escape hatches for unusual setups, not everyday settings.
| Variable | Effect |
|---|---|
JOTURA_MARKITDOWN_SIDECAR | Use the converter at this path instead of the bundled one. An empty value, or a path that does not exist, silently forces the no converter path rather than raising an error |
JOTURA_ALLOW_UNSANDBOXED_CONVERSION | Consent to unsandboxed conversion, the same as the Settings switch |
JOTURA_DISABLE_SANDBOX | Turn the sandbox off entirely and convert anyway. Setting it also grants unsandboxed consent, so conversion proceeds with no isolation at all. jotura doctor reports it as a warning |
Plain text and code files
Plain text files are not second class citizens in a Jotura vault. A .py file, a .csv export and a .yaml config are stored, opened, edited, indexed and synced with the same machinery as your notes. None of them needs a mirror, because their contents are already text.
- Clicking one opens a CodeMirror tab with syntax highlighting picked from the file name, line numbers, bracket matching, and undo and redo. There is no find bar inside the pane.
- Edits autosave one second after you stop typing, exactly like the markdown editor. There is no save shortcut.
- Changes made outside the app merge in silently rather than prompting.
- HTML files open in their own tab, rendered inside a fully sandboxed frame with no scripts, with a toggle to read the source.
- Every row in the file tree carries a small type badge, for example
PDF,Wfor Word,Xfor spreadsheets,Pfor presentations,TS,PY,RS,{}for JSON andTXT.
One inconsistency is worth naming. The search index and sync both treat .mdc as a text file, but the app’s file tree does not recognize that extension. Clicking such a row opens it in an external application instead of a tab.
Storage, sync and size limits
Documents live in the vault as ordinary files, so they are visible to every other tool on your machine. There is no hidden store and no proprietary container. When cloud sync is switched on, documents and their mirrors are encrypted on your device before upload like everything else, and sync is the one paid part of Jotura, priced on the pricing page.
| Limit | Value | Effect |
|---|---|---|
| Sync upload cap | 16 MB per file | Larger files stay local. The pending upload is dropped rather than retried forever |
| Full text index cap | 25 MB per file | Larger files are skipped by the indexer and will not appear in content search |
| Synced file types | Text and document extensions plus images | Audio, video, archives, executables, .msg files and files with no extension are stored locally but never uploaded |
More detail on what is encrypted and when is on the Sync and sharing page and the security page.
Documents from the command line
The jotura command line tool shipped with the app covers the same pipeline, which is what lets an agent import and read documents without the app being open. Full reference: Documents from the CLI.
Import a file into the default attachments folder and convert it:
jotura import ~/Downloads/contract.pdf
Import to an exact path, replacing anything already there:
jotura import ~/Downloads/contract.pdf --as Legal/2026/contract.pdf --force
Store a file without generating a mirror:
jotura import ~/Downloads/scan.pdf --no-convert
Read the bytes from standard input, which requires an explicit target path:
cat ~/Downloads/scan.pdf | jotura import - --as attachments/scan.pdf
Regenerate only the mirrors that are out of date:
jotura regenerate-md-store --stale-only
Regenerate one named document:
jotura regenerate-md-store attachments/report.pdf
Search documents and get their original paths back:
jotura search-documents "termination clause" --limit 10 --json
List every document with its conversion state:
jotura ls-documents --folder attachments --json
| Command | Flags and rules |
|---|---|
jotura import <FILE> | --folder, --as, --no-convert, --force. --folder is ignored when --as is set. --force only means anything with --as, because the folder route already de-duplicates by suffixing. With --as and no --force, an existing target exits 9. Use - for the file to read bytes from standard input, which then requires --as |
jotura regenerate-md-store [PATHS]... | --all, --stale-only. One of paths, --all or --stale-only is required, and passing none of them exits 9. Positional paths are silently ignored, with no warning, whenever --all or --stale-only is also given |
jotura search-documents <QUERY> | --limit, default 20 |
jotura ls-documents | --folder |
The --json flag is not uniform across these four commands. import and regenerate-md-store always emit JSON, so the flag does nothing on them and the examples above print JSON with or without it. search-documents and ls-documents print tab separated text unless you pass --json. See Exit codes and JSON output.
jotura doctor reports the converter version, the sandbox in use, and the converted, failed, pending and total counts, and points at jotura regenerate-md-store --stale-only when anything is failing. See Watching and diagnostics.
Limitations worth knowing
- Deleting a document does not delete its mirror, and renaming a document does not rename it. The mirror is an ordinary note, so it stays behind under the old name and becomes visible in the tree. Delete or rename it yourself.
- Renaming a document outside the app does not trigger a conversion. The new name waits for the next vault open or a manual sweep.
- There is no in-app viewer for PDFs, Word files, spreadsheets or presentations. You get the extracted text in a note, and the real file opens in another application.
- Conversion quality is whatever the converter can extract. Complex layouts, scanned pages and password protected files may produce little or nothing.
- A mirror you have edited never updates again, even when the document changes, until you remove your edited version.
- Nothing under a dot-prefixed folder is converted, indexed or synced.
- Very large documents can be stored locally but excluded from both sync and search by the caps above.
If a document is not turning up in search, open Settings, Advanced, Document conversion and check whether it is pending or failed. A document that is missing from all three counts has a protected mirror. Troubleshooting covers what to do next.