LightNote Help
Lightweight code and notes editor for Windows. The sidebar lists the sections and follows what you are reading; the Home and Back buttons at the top of the window return to the start, and the Search box finds text within this help (Enter moves forward; F3 / Shift+F3 navigate). Press F1 at any time to open this help right at the section for the current screen.
Index
Editing
- Overview
- Workspace and windows
- Code editor
- Markdown and wikilinks
- Diagrams (Mermaid)
- Mathematics and chemistry (LaTeX)
- Calendar in a note
- Numbering and cross-references
- Citations and references
- Connections graph
- Tables (Parquet, CSV, JSON, Excel)
- Analysis area: pivot table and several charts
- PDF and images
- Images: marking up a screenshot
- HTML pages (.html)
- Printing
- Zip as a folder (.zip)
- Blocks (.lnb)
- Tasks (Kanban / Gantt)
- Custom table (.lnd)
- Bases (saved queries over your notes)
Tools
- Search in files and Pending items
- Versioning (easy Git)
- Snapshots and backup
- Review changes (checkpoints)
- Compare files (diff)
- Run code (F5)
- Terminal and AI CLIs
- AI assistant on the selection (Ctrl+K / Ctrl+I)
- AI sessions
- AI Chat
- Test HTTP APIs (.lnh)
- Databases (.lnc)
- SSH connection (.lns)
- Security: Passphrase, PIN and Secure Markdown
- Daily notes, quick capture and tray
- Resurface old notes
- Your notes on your phone
- Record audio (voice, meeting) with AI transcription
- Sticky notes
- Calendar
- Command palette
Automation (AI / scripts)
Reference
- Settings and themes
- Portable mode: your data next to the program
- Keyboard shortcuts
- License, editions and community
Overview
LightNote opens a folder as a Workspace and shows the file tree on the left, the editing tabs on the right and the status bar at the bottom. The small strip at the top of the sidebar switches between the Explorer (tree), Search, Versioning (Git), file History and Pending items (TODO/FIXME and note tasks) sections.
Beyond code and notes, it opens and edits many formats in the right place:
tables (Parquet/CSV/JSON via DuckDB and Excel .xlsx), PDF, images
(including animated GIF), .zip as a folder, Blocks notebooks
(.lnb), Tasks boards (.lnt), custom
tables (.lnd), database connections (.lnc)
and SSH connections (.lns). There is an integrated terminal,
global search (ripgrep), simplified Git versioning, integration with AI CLIs, an
MCP server and a command line (lnote) for
automation.
New here? The introductory material (the welcome workspace) stays available at any time under Help → Reopen welcome tour.
Workspace and windows
The root folder and the window
The opened root folder is your Workspace. Just opening it creates nothing; when you close it, LightNote only writes a small session file (open tabs and position). The workspace only becomes a "project" — with its own persisted configuration — when you enable Versioning (Git) or the MCP in Tools → Workspace Settings.
The General Settings apply to the whole application; the Workspace Settings apply only to the opened folder. Configuration and state live in a central database, not scattered across the folder.
LightNote runs as a single instance: opening a second folder reuses the
process (multi-window, less memory). There is a tray icon and a
launcher with a search box listing the Workspaces (pin your favorites to
the top via the context menu) — see
Daily notes and tray. Each tab can get a color
label through the tab bar's context menu. For repetitive notes, create a
Modelos (or Templates) folder at the workspace root with .md files and use
File → New note from template… Four academic templates come ready in the same list — Academic paper, Reading note, Lab notebook and Experiment protocol: picking one writes the .md into that folder, and from then on it is yours to edit.
Organizing and writing templates. Subfolders of Templates become categories: Work/Meeting.md shows up as Work/Meeting, and that is the name a folder records when it adopts the template. The fields {{title}}, {{date}}, {{time}} and {{date:dd/MM/yyyy}} are filled in on creation — the title is the note's name, and renaming the note right after creating it, before writing in it, redoes the title — and nothing is replaced inside code (between backticks or in a block), so a template can teach its own syntax. In a template they are marked like the fields to fill in, with the same background — in the formatted editor, with the solid border of syntax —, and in an ordinary note they get no colour, because there they do nothing. The template's frontmatter goes into the note, except description:, which describes the template, and citation-style:, which belongs to the folder. Templates and prompts (the Prompts/ folder) are tools, not content: they stay out of search by meaning and of the AI Chat context, and the tags and aliases: declared in them do not count — text search still finds both. With a template open, a strip at the top of the editor says that it is a template and offers Insert field, Show syntax and the Preview — the note as it is born right now. The Template library (under Tools, and the same one File → New note from template… opens) lists them all with search by name and description, groups them by subfolder and shows the preview; it is also where a new template is created — including from the open note, where its title and today's date become fields. The gallery also brings a From the site group: templates we publish, in the interface language, fetched only when you open it. Importing is a copy — the template becomes a file of yours under Templates, and nothing links the two afterwards: a template fixed on the site does not chase what you already imported, and a template of yours with the same name always wins. Without a connection the gallery says it could not fetch them and goes on showing what is already on this machine.
Fields to fill in. A template can leave gaps: {{ask:Meeting subject}} is a free field and {{choice:draft|review|final}} is a list. They are not replaced on creation — the note is born with them marked in the text, and that is what makes them work in Today's note, in lnote and in the MCP too, where there is no screen to ask anything. In a note, the formatted editor shows each field as a tag with a dashed border around its label (the question, or the first option); clicking it selects the whole field, and the next key replaces it. On a choice field the click also opens the list: picking an option swaps the field for it, and closing the list without picking leaves the field selected, ready for you to type something else. When the note is created, the cursor already lands on the first field; from there Tab and Shift+Tab move from field to field — the status bar says which one you are on —, Alt+↓ opens a choice's list from the keyboard, and Esc (or leaving the field's line) gives Tab back its usual job. In the template itself, Show syntax is on: the fields appear as {{…}} with a solid border and a click puts the cursor inside them, so you can fix the question or the options; off, the template looks like the note that will be created from it. The six fields are also in the / menu and under Insert → Template fields — only in template files. In the text editor a field appears exactly as it is in the file, with coloured braces, and the spell checker stays out of it.
Creating files
Creating a file and choosing its type. The New menu (☰ File, the New button on the activity bar, or Create new in a folder's context menu) offers New note (.md), New text file (.txt) and the New code file submenu with the most used languages. In all of them the file is created on disk right away with a default name, and the tree opens the name editor — only the base name is preselected, so typing a title does not erase the extension. To accept the suggested name, just click in the editor and start writing. For an extension outside the submenu, create a file and rename it (F2): changing the extension changes the view — renaming .txt to .md reopens the same tab as a note, with the reading view and outline, and the other way round brings back the code editor. LightNote's own extensions (.lnc, .lne, .lnq, .lnh, .lns and the bundles) are the exception: there the extension declares the format of the content, so renaming asks for confirmation and is refused while the tab is open.
A new file you never got to use. If you close the tab of a just-created file without naming it, without saving and without typing anything, it goes to the Recycle Bin and the status bar offers Undo — so a New triggered by accident leaves no trace in the folder. Any sign that the file is yours makes it permanent: renaming it, saving it (Ctrl+S) or typing anything into it.
The scratchpad is a Markdown editor. The Scratchpad tab (which is not a file on disk) now uses the same text editor as your notes: markup highlighting, spell checking, [[ completion and Ctrl+click on wikilinks and tags. What it does not have is unchanged — there is no file, so there is no autosave and no view modes; the content survives closing the app and is gone if you close the tab.
Where the new file is created. New always creates in the marked folder in the Explorer, and exactly one is always marked. At the top of the tree sits the root folder row, named after the workspace: it is an item like any other — click it to send the destination back to the root. Selecting a folder moves the mark to it; selecting a file marks the folder that contains it. In List mode, which shows no folders, the mark stays on the root row and that row displays the effective destination. The root row's context menu offers Create new and Create folder.
Standalone files and favourites
To open a loose file without turning it into a workspace, use Open loose file… (tray menu): the standalone window shows the file tree, but without Git, MCP or theme override. If enabled in Settings → General → Features, LightNote integrates with the Windows Explorer menu (per user, no administrator required): besides the "Open with" list, the context menu gains "Open with LightNote" on any file and "Open as LightNote workspace" on folders (on Windows 11, under Show more options). Files open in that standalone window; folders open as a workspace.
If you select several files at once in Windows Explorer — even from different folders — they all open in the same standalone window, tab next to tab (instead of scattering one window per file). That window's tabs are remembered: close it and open it again, and the same files come back. Since the focus here is on the tabs, the file tree starts collapsed — press Ctrl+B (or the button at the top of the activity bar) to show it.
Getting back to a session. The standalone files window is called Standalone files everywhere — including in the title bar, where other windows show the workspace name, so you can tell them apart in Alt+Tab. In the tray menu, under Open, the item gains a (N tabs) suffix when there are saved tabs — clicking it brings them all back. It is also the first row of the launcher, next to your workspaces. And when you reopen LightNote, it comes back with everything that was open when you quit: each window in its folder, plus the standalone window. To open only the last folder used instead, change Settings → General → Interface → On startup, open. A window you closed before quitting is left out — closing is how you say "I'm done with this space".
Favorites: the sidebar has a Favorites section with whatever you pinned (context menu of the tree or of a tab → Add to favorites) plus the recently opened files. Pinned items are per folder and are stored as relative paths, so they survive moving the workspace.
Open a tab in its own window: in the tab's context menu,
Open in new window reopens that file in a standalone window (handy to keep a
note beside your code). File types that depend on the workspace (.lnc,
.lne, .lns and the bundles) cannot be detached.
The Explorer
Moving a file while its tab is open. Dragging the file to another folder in the tree takes the tab with it — it stays open, now pointing at the new location — and the same holds for cut and paste and for moving a whole folder, in which case the tabs of the files inside follow along. Hold Ctrl to copy instead of moving. Out of LightNote, a drag always COPIES: take a file from the tree — or drag the tab itself from the tab bar — onto a Windows folder, an e-mail or a Teams conversation, and the original stays in your workspace. Inside the program a tab is still just a tab: dragging it to another pane moves the tab, and passing over the editor or the tree with it writes and moves nothing.
Multiple selection. The tree accepts Ctrl+click (individual) and Shift+click (range) in all three view modes. With several items selected, the context menu acts on the whole selection: Cut and Copy (interoperating with Windows Explorer), Delete (a single confirmation for all), Duplicate, Copy hash, Compress to .zip (one archive, each item under its own name at the top), Apply color, Favorites, Git (add/restore) and Copy paths (one line per item). Actions that only make sense for a single item — inline rename, Properties, Open as, Convert — are disabled, with the reason in the tooltip. Right-clicking inside the selection keeps it; clicking outside selects just the clicked item. Selecting a folder and something inside it does not run the operation twice: the inner item is dropped.
Peek without opening. A single click on a file already opens a preview tab (recycled, shown in italics on the tab bar). While walking the tree with the arrow keys, Space does the same and returns focus to the tree, so you can keep moving down the list.
File tools. The Explorer context menu has a File tools submenu: Batch rename (filter by extension/wildcard/regex + a rule pipeline with live preview and collision detection), Split file (by lines, size or regex separator), Merge files (optionally keeping only the 1st CSV header), Duplicate, Copy hash (MD5/SHA-256) and Compress to .zip / Extract here. With several items selected, Batch rename and Join files receive exactly the chosen items (instead of scanning the folder) — and Join honors the selection order.
Navigating the standalone window. Above the tree there are back (Alt+←), forward (Alt+→) and up buttons, plus a clickable folder trail — each segment jumps to that level. The mouse side buttons also go back and forward. To type a path, click the empty area of the strip or press Ctrl+L; Esc cancels and restores the trail. Switching tabs also moves the shown folder: since the standalone window gathers tabs from different folders, clicking a tab navigates to that tab's folder.
Menus and zoom
Menus. The ☰ button (top of the activity bar) holds the File, Edit, View, Window, Tools, AI and Help menus. AI actions have their own menu (also on the wand button in the activity bar). Under Tools, the groups live in submenus: Run (F5/F6/F8, lint, send to terminal, macros), Capture (today's note, quick capture, quick task, record audio, sticky notes) and Workspace (settings, snapshot, export copy, move folder) — the latter also in the gear menu. The New menu is the same in the three places it appears: ☰ File, the New button and Create new in a folder's context menu.
Zoom, in every view. The zoom level lives in a single place: the − 100% + group on the right of the status bar. The middle button opens the standard list — Fit width and Fit window (only where the content has a size of its own, such as PDF and images), the levels 200%, 150%, 120%, 100%, 75% and 50%, and Custom… —, with a mark on the active one. The shortcuts are the same in every view that has zoom (code, notes, PDF, images, HTML and spreadsheets): Ctrl++, Ctrl+−, Ctrl+0 to go back to 100% and Ctrl+mouse wheel. In a view without zoom the group simply does not appear; under a fit mode the label reads Width or Window instead of a percentage. Zoom belongs to the tab, not to the file: a tab that sat idle and had its memory released — or that came back when you reopened LightNote — returns at the zoom you left it; opening the file again, from scratch, starts at 100%.
Code editor
Opening, highlighting and formatting
Text/code files open in the editor (Scintilla) with syntax highlighting. There is comment/uncomment (Ctrl+/), move and duplicate line, bookmarks (Ctrl+F2), a symbol/function list, word-based autocompletion, indentation guides, word wrap, zoom and detection of file changes on disk. With versioning enabled, the margin marks the lines added/changed since the last version.
There are also macros (record/replay a sequence of edits with Ctrl+Shift+R / F4, in Tools → Macros), format/beautify (Shift+Alt+F), an ASCII table on the tab's toolbar (to insert characters/box-drawing) and a spell checker (Hunspell). pt-BR and en-US ship built in; other languages you download on demand from the table in Settings → Notes & writing → Spelling (one row per language, with a Download/Remove button). To follow a log file being written, use the Monitor (tail -f) button on the tab's own toolbar. Very large files (above ~1 MB) open in a virtualized lightweight editor that loads only the visible chunks; you can force it through File → Open in Lightweight Editor…
Format and lint: Shift+Alt+F formats the document with the language's external formatter (black, prettier, clang-format, gofmt, rustfmt…) when installed, falling back to the internal formatter (JSON/XML) offline; F7 runs the language's linter (ruff, eslint, shellcheck, luacheck…) and marks the problems with an underline in the editor and in the Problems panel (bottom pane, navigable). Both have a catalog with Add in Settings → Formatting and → Linters, plus format on save / lint on save options. Run the file in the output panel with F6 (captures exit code and duration, with stop/restart) or just a snippet with F8.
A .md opened as code becomes a note again in one click. The editor toolbar shows Open as note when the open file is a note — the inverse of Open as → Code in the tree menu, returning the tab to the note view, with formatted editing, reading, outline and properties. The button only appears when the switch is possible: a note that is too large stays in the code editor.
Multi-cursor, history and definition
More editing features: per-occurrence multi-cursor (Ctrl+D, all
with Alt+F3), duplicate line (Ctrl+Shift+D), join lines
(Ctrl+Shift+J), expand/shrink selection by scope (Ctrl+Shift+Space /
Ctrl+Alt+Space), rectangular selection (Alt+drag), fold/unfold all,
snippets (Ctrl+J, editable in Settings → Editor), Go to
symbol in file (# in the palette) and in the project
(Ctrl+T or ##), navigation history (Alt+←/→), a
breadcrumb trail at the top of the editor, column rulers,
bracket-pair colorization, auto-close/wrap pairs and cleanup on save (trim spaces,
final newline) — all in Settings → Editor.
Local history and clipboard: on every save, LightNote keeps a version of the file (File → Local history…, restorable), independent of Git. Ctrl+Alt+V opens the clipboard history to paste a previously copied item. Ctrl+Shift+T reopens the last closed tab; tabs can be pinned (context menu), which protects them from being released when idle.
Go to definition: F12 or Ctrl+click on an identifier jumps to where it is defined in the project; Shift+F12 finds its uses.
Minimap and text operations
Minimap. A thumbnail of the whole document sits on the right edge of the editor: it shows the “shape” of the code (the syntax highlight colours, scaled down) and marks the visible region. Click or drag it to jump anywhere in the file. Toggle it in View → Minimap or in Settings → Editor. The Minimap button on the code tab's own toolbar (next to ASCII) toggles it without leaving the editor. A mark strip runs along the thumbnail's left edge: blue for bookmarked lines (the same dot as in the margin) and amber for quick-search matches — so you can see at a glance how they are spread across the whole file, including the parts that are off screen.
Text operations. The Edit menu — and the editor's context menu — hold the Lines (move, duplicate, delete, sort, join, reverse, number) and Cleanup (trim whitespace, remove empty/duplicate lines, tabs ↔ spaces) submenus. With text selected, the context menu also offers Save selection as a new file…: it writes the snippet to a file next to the current one and opens it in a tab (the original is left untouched).
Markdown and wikilinks
Display modes
.md notes open with editor and reading side by side
(configurable). The markup is dimmed outside the cursor's paragraph so the page
looks like a finished document.
Shortcuts: Ctrl+B/Ctrl+I apply bold/italic and Ctrl+E cycles the view mode (editor → split → formatted → reading).
The / menu: in the formatted editor, type / at the start of the line (indentation is fine) or after a space: the insert list opens at the cursor. Type to filter (/table, /callout, /h1), choose with ↑/↓ and insert with Enter; Esc or Space close the list and what you typed stays as text. The right-hand column shows the markup each item writes, so you can type it directly next time. The menu does not open inside a code block, a formula or a table cell.
Reading mode: the last Ctrl+E mode is the same screen as formatted editing, but read-only — which is why it can show what the file does not contain: the table of contents for the [TOC] token. The folder listing for the [files] token and the body of notes transcluded with ![[note]] also show up in formatted editing. None of it is written to the .md: the file keeps the token, and the generated text does not accept editing. In this mode a plain click follows links, wikilinks and tags (no Ctrl needed), and the editing buttons are disabled — including undo, cut and paste, which used to act on the off-screen text editor. Copy still works, and copies what you are looking at. Ctrl+F searches what is on screen; the replace row is disabled, with the reason in its tooltip, because a replacement here would never reach the file.
Calculations with units, in reading mode. A line ending in = gets the result: 3.5 km / 2 s = shows as 3.5 km / 2 s = 1.75 km/s. The file does not change — same idea as [TOC] and the formatted citation. It does dimensional analysis, and that is what earns it its keep: 1 km + 1 s = is refused naming both, because a calculator that answered 2 there would not be worse — it would be one that lies, and in a lab notebook the mistake would survive all the way to the paper. Adding the same quantity in different units works and converts (2 h + 30 min =), and the result comes out in the unit you wrote. It knows the SI prefixes, the physical constants (c, h, k_B, N_A, g…), explicit conversion (3 km in m, also to and ->) and uncertainty: (2.00 ± 0.05) m / (1.0 ± 0.1) s = propagates the error and writes only the digits the measurement allows. Code and formulas stay out — inside a ``` fence, between backticks or in a $…$, the = at the end of the line is somebody else's syntax. And a line that is not a calculation (Total =) is left alone, silently. It ships turned off: switch it on in Settings → Features → Academic → Calculator with units.
Spaced repetition flashcards. A note tagged #flashcards becomes a deck: inside it, every Question::Answer line is a card, ::: also creates the reverse card, a lone ? between two lines makes the multi-line card, and ==like this== becomes a blank. Without the tag, no note has cards — that is what stops a std::vector in a programming note from becoming a card you never wrote. Tools → Flashcards → Review flashcards opens the session: the answer stays hidden until you ask for it (that is the whole feature — seeing both at once is rereading, and rereading does not stick), and the four grades carry written on them how much time each one buys. Scheduling is FSRS, the same algorithm Anki uses. A card's identity is its QUESTION: fixing the answer does not touch the schedule, and rewriting the question retires that card and starts another — which is right, because the question is what you are learning. The history lives in an open file next to the note (note.md.cards.ndjson): you can version it with Git and read it in any editor, and the price is one more file in the folder. Export to Anki writes the text file it imports — the schedule does not go along, because Anki's text importer does not accept it; it stays in the .ndjson files.
Code blocks
Code blocks come out colored. A fence with a declared language (```python) gets its body highlighted token by token, using the same colors as the code editor — including the code theme chosen for this window. This applies to formatted editing, reading mode, the exported file and the answers in Ask your notes. A fence with no declared language stays monochrome, and so does a language with no highlighting available: the text never fails to show.
Folding, sticky headings and export
Folding sections and pinning the heading also work in formatted and reading modes. Ctrl+Shift+[ collapses the cursor's section and Ctrl+Shift+] expands it; clicking the little arrow left of the heading does the same, and View → Collapse/Expand all headings acts on whichever surface is in front. As you scroll, headings that went off the top stay pinned in a band — click one to jump to its section. Folding is screen state: the .md does not change, and folded text stays in the file.
Export: the PDF and the HTML are generated from the same document as reading mode — the file you get is what you have just read, with the table of contents, the folder listing and transclusions included. The HTML is self-contained (local images are embedded) and the PDF has vector text, so it stays searchable. The HTML comes out with semantic markup — headings with anchors, callouts as <aside>, tables with a header, footnotes with a way back — and formulas in MathML: real text, which can be copied, read aloud and never blurs when zoomed. The theme follows each format: the HTML keeps the colours you see on screen, dark theme included (the file carries its own background); the PDF always goes on light paper, because it is meant to be printed and sent — if your content theme is dark it is printed with the default light theme, and a light theme you already use is preserved. Word, OpenDocument, LaTeX, Typst and EPUB are written by LightNote itself, with nothing to install. The .docx and the .odt come with headings, lists, tables, footnotes, images and formulas as editable equations — Word equations in one, LibreOffice Math objects in the other; the .tex has a complete preamble and compiles with pdfLaTeX, XeLaTeX and LuaLaTeX. If the folder has a bibliography and the Academic section is on, the .tex comes out with live citations: [@key] becomes \autocite, the [bibliography] token becomes \printbibliography, and a refs.bib with the cited works is written next to it — the app tells you it did. Compile with biber. The .typ is the same idea in Typst, which compiles in seconds with no LaTeX distribution installed: formulas travel as LaTeX through the mitex package (downloaded on the first compile) and citations come out as @key with #bibliography. The .epub is the e-book: one chapter per level 1 heading, a navigation table of contents, images as package files and the same semantic markup as the HTML. The .ipynb is the Jupyter notebook: prose becomes a text cell and the fence in the kernel's language becomes a code cell — only that one, because a code cell is sent to the kernel, and a Mermaid diagram turned into a cell would run as Python the first time anyone executed it. The kernel comes from the kernel key in the note's properties, or from the most frequent fence. No output is invented: the cells come out with no result, because a result comes from running — the same rule the notebook import already follows when it drops the stored outputs. And there is Markdown for…: the same note in the destination's dialect — a > [!NOTE] alert on GitHub, !!! note on MkDocs, :::note on Docusaurus, ::: {.note} on Pandoc, the Obsidian spelling or strict CommonMark. Wikilinks become relative links (outside Obsidian) and the %%…%% comment is not published, because it is private. With Typst installed (winget install --id Typst.Typst), the export itself offers Compile the PDF right there — and without it the button becomes Install Typst..., which opens the guide. If your course or client hands out a Word template, point at its .docx in Workspace settings → Citations and references → Word template: the exported file comes out with the template's styles, paper size, margins and header. A note can use a different one by declaring reference-docx: template.docx in its properties. All three start from the reading Markdown — citations already formatted, figures numbered — and whatever does not make it across is reported when the export finishes. Mermaid diagrams and chemical structures go in as images — drawn on light paper in the .docx, the .odt and the EPUB, in the screen colors in HTML —; only through lnote, which has no window to draw them, do they come out as code blocks. And there is Markup text for…: reStructuredText, AsciiDoc, Org mode, MediaWiki and plain text, also written by LightNote itself. Each one gets its own native construct, not an imitation: the box becomes .. note:: in Sphinx, [NOTE] in AsciiDoc and #+begin_note in Org; the formula becomes .. math::, latexmath:[], plain LaTeX and <math>; the footnote becomes footnote:[] and <ref>. Plain text carries no markup at all — the table comes out aligned in columns, so it fits in an e-mail or a commit message. Whatever the destination lacks is reported at the end: MediaWiki has no box in its core (it becomes a quote with the label in bold) and reStructuredText has no strikethrough. To take a piece along without writing a file, the editor's context menu has Copy selection as (or Copy note as, with nothing selected): formatted text to paste into Word, Google Docs or an e-mail, GitHub Markdown, LaTeX and Typst. LaTeX and Typst carry the body only — no preamble, no title — because the destination is a document that already has them; a package the passage needs, or a citation that depends on the destination's bibliography, is reported in the status bar, and the %%…%% comment stays behind as well. RTF lives under More formats (pandoc) and goes through pandoc, a separate program (winget install --id JohnMacFarlane.Pandoc): without it that destination appears disabled, with the reason, and Install pandoc... in the same submenu opens the guide and does the install. If you already have pandoc somewhere else, point at the file with I already have it: locate on disk... in the guide, or in Settings → Code tools → External programs.
Export with options... is the first item of the export menu — the tab's and the one under File → Export note are the same menu. It lists every destination, with a search that matches name, use and extension (wiki finds MediaWiki, sphinx finds reStructuredText), and shows only the options that apply to the chosen destination: Table of contents at the start, when the note has no [TOC] yet; Document language, which decides hyphenation and the labels the document generates by itself; Citations live or resolved in the text, for LaTeX and Typst; the Word template, with the box that makes it the folder's default; the Formulas of HTML and EPUB as MathML or as images, for older e-book readers or HTML pasted into an e-mail; the PDF Paper, A4 or Letter; and Compile the PDF with Typst right after. An option that applies but cannot be used is disabled with the reason — live citations with no bibliography in the folder —, and a destination that depends on a missing program offers to install it right there. The last choice is remembered per folder and the dialog reopens the way you left it; the direct menu items keep exporting with the factory values, so that a choice made weeks earlier does not change the file a shortcut writes. A [TOC] written in the note works in every destination: it becomes the table of contents in Word and LibreOffice (Word updates it on opening), \tableofcontents in LaTeX, #outline() in Typst and a list of links in HTML and Markdown. In the formatted text of Copy selection as, formulas and diagrams go as images, with the LaTeX source as alternative text: there is no telling where the text will be pasted, and only an image looks the same in Word, Google Docs and an e-mail — if you need the editable equation, export the .docx or the .odt.
The whole folder goes out too: File → Export folder... (or right-click a folder in the tree) turns its notes into an HTML site — one page per note, with an index when no note already became index.html —, a set of .docx or .odt, or a tree of Markdown in the destination's dialect. The subfolder structure is preserved, the links and wikilinks between the notes now point to the files that came out (in Word and LibreOffice too, from one document to the other) and the images and attachments that live inside the folder go along, in the same place. What is outside it is not copied: it stays as you wrote it, and the report at the end lists every case, together with the links with no target. The destination folder must be empty — or you tick Replace files with the same name — and cannot contain the exported folder. With no window: lnote folder-export --path . --format html --out site, and the folder_export tool over MCP; there transclusion, [files] and figure numbering are not resolved, because the window is what resolves them.
Formatted editing
Formatted editing (WYSIWYG): the fourth mode shows the note as it
looks — a heading in heading size, a list with its bullet, a table as a grid and
an image inline — instead of the markup. The file is still the same
.md: LightNote writes it, not Qt, which is why bold, italic,
wikilinks, transclusion and callouts survive the round trip. Entering the mode
and leaving without editing does not change a byte of the file. The toolbar
offers only what Markdown can represent — heading, bold, italic, strikethrough,
code, lists (with task checkbox), quote, link, table and horizontal rule;
alignment, indentation and font size are left out because they would be lost on
save.
Inside a table, Tab moves between cells and creates the next row on
the last one.
Enter in the empty space beside the table — where the caret lands when
you click to the right of a row — appends a row at the end, with the cursor in
the first cell.
Inside a cell, Enter breaks the line right there (it goes to the file
as <br>, the only form a Markdown table accepts) and
Ctrl+Enter creates the row below, with the cursor in the same column.
Hovering the table reveals discreet handles: to the left of the row, a
pair of arrows that moves it up or down — and that you can also drag to
take it somewhere else; above the column, the pair that moves it sideways; and
a + on the bottom edge and another on the right one, which add a row and
a column. The first row is the header and does not move. All of it is in the
context menu too, under Table — which also carries Remove the
table, the safe way to take the whole table out.
In a box (<details> or :::), the last line
closes the box and cannot be deleted: it is what keeps the content below
from being swallowed by the box. To undo the box and keep the text, use
Remove the box in the context menu. Enter always creates a line. In an empty list item it leaves
the list without adding a line — as Word does — and in an empty paragraph it
creates the blank line. One blank line in the file is the normal separation
between paragraphs and does not show as an empty line; from the second one on it
does, and it goes back to the file exactly as you wrote it.
Dragging an image's right edge resizes it, and the width goes to
the file as . The bar has twelve controls: bold, italic and heading directly, plus two menus that split the rest by what they do — Format acts on what is already written (marks, lists, quote, table alignment and the Text operations) and Insert creates something new (link, image, table, block, diagram, formula, callout). Formatting a table and the Text menu still belong to the text editor: here they appear disabled, with the reason. Fading the markup moved to the View button, next to the reading column and typewriter scrolling, which work in all four modes. And the Insert menu offers here the same as in the text editor — highlight, superscript, subscript, wikilink, footnote, callout, collapsible block, table of contents and definition list —, everything this mode already knew how to show and did not know how to create.
What reading mode shows, formatted editing shows too. The :fire: emoji appears as 🔥, ==highlight== as a yellow mark, ^2^ and ~2~ as superscript and subscript, #tag as a pill and a bare web address as a link. The file keeps the written form: opening the note rewrites nothing. Editing inside a rendered span keeps the markup — typing in the middle of a highlight stays highlighted — and what you type right after it stays outside. The %%…%% comment stays visible, dimmed: hiding it would make it invisible and uneditable.
Callouts become a box in formatted editing too. A quote starting with > [!NOTE] — or [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION] — shows a coloured bar and title, just like in reading mode: the marker gives way to the type's label, or to your own title when you write > [!TIP] My title. The file keeps the marker as written, and editing the title preserves the callout's type. The callout names from Obsidian and MkDocs are understood as well: [!SUCCESS], [!ABSTRACT], [!FAILURE], [!QUESTION] and their aliases (tldr, missing, faq) fall into the closest box, so a note that came from there already shows up in colour — and, on export, each destination gets the name it knows.
This is the default mode on a new installation. If you already used LightNote, your previous mode is kept; to change it, use Settings → Markdown → Default view when opening a note. Clicking a heading in the Outline jumps within the current mode, without pulling you out of formatted editing or reading.
Aligning a table column. With the cursor inside the table, the context menu offers Table → Align column: Left, Centered, Right or Default. Alignment belongs to the whole column — that is how Markdown represents it — and goes into the file on the separator line (:--, :-:, --:); Default goes back to ---. The check mark in the menu tells you which one is in force: on screen a --- column and a :-- one look alike.
The Outline shows what is on screen. The list of headings comes from the surface you are looking at: in formatted editing, a heading you have just typed shows up right away, without waiting for the text to reach the text editor; in reading mode it also includes the headings of notes transcluded with ![[note]], which are part of what you are reading. Clicking an item lands on the right heading in both cases. And in split mode scrolling now works both ways: scrolling the reading pane takes the text editor along, as it already did the other way round.
Markup becomes formatting as you type. Writing
**test** applies bold and removes the asterisks; the same goes for
*italic*, ~~strikethrough~~, `code` and the
underscore forms. At the start of a line, # through
###### become headings, - and
1. become lists (the number you type is where it starts),
- [ ] becomes a task with a checkbox, >
becomes a quote and --- alone becomes a horizontal rule when you
press Enter. The markers that draw something take effect on the space itself;
only the heading waits for the first letter, because an empty heading would show
nothing. Ctrl+Z undoes only the conversion and
brings the literal markup back — the way out for someone who really wanted the
asterisks. Pasting converts too: text with markup pasted in comes out formatted, without the markers. The rule here is more cautious than while typing — only unambiguous markup fires — because when pasting you do not watch the result form: that way a code snippet, full of * and _, stays code. Nothing is converted inside a code block, because there the markup is
the subject. To turn it all off: Settings → General → Convert the markup as you
type. From Word, Google Docs or a web page, what arrives is the text with its structure: headings, lists (including Word's, which underneath is not a list at all), tables, links, inline code and code blocks with the language. The source's font, size and colour stay out — Markdown does not represent them, and keeping them would leave a blue Arial run that vanishes on save. A picture that comes along becomes an attachment of the note when Word or the browser left it in the temporary folder, which empties itself; one that points to the internet keeps pointing there, and its context menu offers Download the image into the workspace.
Images, links and wikilinks
Images and links. There are three ways to put an image in:
Insert → Image… on the toolbar, typing , or
dragging the file into the note — dragging an image inserts the image,
dragging a .md note inserts a [[wikilink]], and any
other file becomes a clickable link labelled with the file name — and
dropping several at once puts each one on its own line. The stored path is relative to the
note's folder whenever possible, so the note keeps working after the vault is
moved. A link's address does not appear in the text (what you see is the
label), so it is shown in the status bar on hover, and Ctrl+click opens
it: a web address goes to the browser, a local path opens in LightNote.
Editing an existing link: put the cursor in it and use the
Link button (or Edit link… in the context menu) — the dialog opens
with the text and the address filled in. The context menu over a
link also offers Copy link address and Remove the link, which
undoes the link and leaves the text. Over a [[wikilink]] it offers
Open the note and Copy the target; over a #tag,
Search the tag and Copy the tag. Over an image there is
Alternative text… — invisible in the formatted mode, but it goes to the
file and to the search — and, once you have dragged the handle, Original
size, which gives the image its own size back. Over an image with a
web address you get
Download the image into the workspace: the file goes to
Attachments/ next to the note and the note points at it — otherwise
it would depend on that URL still being there. And there is the shortest path of all: select some text and paste a
URL — it becomes [text](url) instead of replacing the selection.
It works in both editing surfaces. Until it is downloaded, a web image shows up as a card with the
address and the menu path — LightNote does not go to the network to render a
note, and the spot used to hold the empty broken-image box, saying nothing about
what to do.
And the markup can be undone. In the Format menu, the
Highlight, Superscript and Subscript items appear checked
when the cursor is inside one of them, and clicking there removes the markup
instead of applying it again. From the keyboard there is the quick path: with the
cursor at the end of a formatted run, Ctrl+Shift+Backspace gives the
literal markup back minus one character — bold becomes
**bold* as plain text — and completing the missing delimiter forms it
again. It works for bold, italic, strikethrough, code, highlight, superscript and
subscript. Backspace on its own deletes a character, there as anywhere
else.
Edit the diagram without leaving the note. A Mermaid diagram or a
$$…$$ formula appear drawn in the formatted editor; to reach the
source, put the cursor on them and press Ctrl+Enter — or use Edit this
block… in the context menu. The bottom bar shows the text, the note stays locked
while it is open, and closing it (✕, Esc, Ctrl+Enter, a click on the note)
applies: the way back is Ctrl+Z. In the same menu, Extract to new note…
writes the selected passage to a note beside this one and leaves a
[[wikilink]] in its place — the markup goes along, so heading, list and
table arrive intact in the new note. The field shows only the content: the ```mermaid and ``` lines (or the $$) became the type selector in the bar’s header, which also switches between diagram, formula and code block. Enter keeps the line’s indentation, which in an indented language like Mermaid is the gesture of every line. And the block’s context menu offers Copy the Markdown code and Copy the image — the code pastes into any Markdown editor and draws again; the image pastes into an e-mail or a chat. Both also work in reading mode.
Asking the AI for the change. With the block bar open, the AI button in the header opens a line where you write what should change — “add an error path that goes back to the start”, “turn the sum into an integral” — and Enter sends it. Next to the field, a button shows which AI will answer: its menu switches assistant for this block only, without touching your default AI, and carries See what will be sent. It is worth a look, because the AI receives the block, the note's title and section and the text around it — that is what lets you ask the diagram to reflect what is written there. The answer lands in the field and the drawing is redone at once: Ctrl+Z brings back what you had written. LightNote checks the answer with its own renderer and, when it does not draw, asks for one fix, telling the model the line and the command it refused — if that fails too, it writes the answer anyway and leaves the reason on the bar, so you can fix the two lines by hand. The button only appears on diagrams, formulas and chemical structures.
Point at a section, and tag from the properties.
[[Note#Section]] opens the note at that section — the anchor
names the heading text — and ![[Note#Section]] transcludes only
it (up to the next heading of the same level or higher, subheadings included). An
anchor that matches no heading says so in the status bar, and the transclusion is
left as written: bringing in the whole note there would be handing over something
else in silence. And frontmatter tags: now count as the note's tags,
in both spellings (tags: [a, b] and the list on its own lines) — they
reach Bases, tag search and what the assistant sees, together with the
#tags in the body. With no note name, the anchor points at the note itself: [[#Conclusion]] jumps to that section without opening any tab, and ![[#Conclusion]] brings the section to where you are. And anchors nest: [[Thesis#Method#Sample]] is the Sample inside Method, not the first one with that name in the note. The third form points at a block: a line ending in ^id (or an ^id alone right below the block) is the target of [[Note#^id]]. LightNote does not create those identifiers — it takes you to what you wrote. And the anchor of a target that is not a note is the address inside it: [[paper.pdf#page=3]] opens the PDF at that page.
The Tags panel. The sidebar strip has a Tags section: the tree of every #tag in your notes, nested by / (#project/alpha and #project/beta become branches of project), with the number of notes beside it — counted per note, not per occurrence. Selecting a tag lists the notes that carry it below (a parent also shows the ones in its branches); double-click opens the note. The panel reads the index, so it sees both sources: the #tags in the body and the tags: in the frontmatter. Ctrl+clicking a tag inside a note opens this panel with that tag selected — before, it opened a text search for #tag, which does not find the note that declares the tag in its frontmatter. For the literal occurrence in the text, keep using global search.
Wikilinks: type [[ to autocomplete with the workspace
notes; the link closes itself with ]]. Hold Ctrl and click a
[[note]] to open the corresponding note. The Links panel
shows the connections between notes. The Obsidian embedded figure shows up too: ![[photo.png]] is drawn as an image, and ![[photo.png|300]] honours the width. The file keeps what you wrote — the image path is never written in place of the token. And an attachment that is not an image becomes a card: ![[paper.pdf#page=3]], ![[lecture.ogg]] and ![[map.canvas]] show up as a box with the file name, clickable — and the PDF opens on the page you pointed at. Obsidian’s .canvas and .base carry one extra line, saying the file stays in the folder and LightNote does not draw it. A target that does not exist stays exactly as you wrote it: a card there would promise a file that is gone. In the middle of a sentence, the picture shows the same way and the attachment becomes just the file name, which Ctrl+click opens: a card there would split the paragraph. The same note under another name: write aliases: [Sampling, Sampling method] in the note properties and [[Sampling]] opens it — the alias also joins the [[ autocomplete. A file with that name always wins over an alias. Aliases come from the folder index, which the app rebuilds in the background when the workspace opens: a freshly written aliases: resolves on the next scan, not the same second.
Boxes, footnotes and rich markup
Rich reading: fenced code blocks appear in a box with the language label
and a copy link; ~~strikethrough~~ and ==highlight==
are rendered; and GitHub-style callouts (> [!NOTE],
[!TIP], [!WARNING], [!IMPORTANT],
[!CAUTION]) become colored boxes. #hashtag tags are
highlighted and, with Ctrl+click, open a search for that tag; the YAML
frontmatter block at the top (---) is highlighted. On the tab's
toolbar there is a button to export the note as PDF/HTML, a centered
toggleable reading column and the note's display modes. Zen
mode (F11) and typewriter scrolling help you write without
distractions.
Footnotes jump both ways. The [^1] reference appears as a superscript number, and Ctrl+click on it goes to the definition; in the definition, the [^1]: marker stays visible — it is the jump target, and you need to see it to know which note you are editing — and Ctrl+click on it goes back to the reference. Unlike many Markdown viewers, the editor does not renumber footnotes or move definitions to the end: the file's order is yours. The inline spelling from Obsidian and Pandoc — ^[the note text] — draws too: you write the text where the note is called, and in reading mode it shows up numbered at the end. The file keeps exactly what you wrote, and on export it becomes a real footnote in Word, LaTeX, Typst and EPUB.
The MkDocs admonition (!!! note with the body indented by 4 spaces) is kept exactly as written in formatted editing: the indentation is what makes the body belong to the admonition, so its text gets no rich formatting — in exchange, opening the note and saving does not undo the construct.
Boxes with a closing marker also show up as a box. :::tip … ::: (Docusaurus) and <details> … </details> get a coloured bar and title, in both spellings — the compact one and the one with blank lines. The opening marker gives way to the type's label, to the title you wrote, or to the <summary> text; the closing one leaves the screen and stays in the file, because markup the app itself writes should not sit literally on the page. What remains is the last line of the box: it is what delimits the box, it is where you put the cursor to keep writing inside it, and it cannot be deleted — without it, the content below would be swallowed. To undo the box and keep the text, use Remove the box in the context menu. The : of a definition list is still dimmed. The <summary> has to be on the same line as the <details> to become the title: on a line of its own it shows up as written, and the box keeps the default label.
Inline HTML and code blocks. <kbd>, <mark>, <sub> and <sup> are rendered in formatted editing too — the tags disappear and only the content stays, just like in reading mode. A fenced code block gets a box, with the language name and a copy link in the corner — the same link in formatted editing and in reading mode, where code gets copied the most. It takes only the fence's body (without the markers) and says copied for a moment; both labels only appear when they fit without writing over the code.
More in reading: the YAML frontmatter block at the top is not shown in the rendered note — you edit it in the Properties panel. #hashtag tags become clickable chips that open the search for that tag (the same as Ctrl+click in the editor). Obsidian-style comments (%%this stays hidden%%, or a block between lines containing %%) stay in the file only. Besides GitHub callouts, the boxes of the Docusaurus (:::tip Title … :::) and MkDocs (!!! note "Title" with an indented body, and ??? note) dialects are rendered as well — handy when reading documentation repositories.
New in reading: besides ~~strikethrough~~ and
==highlight==, you also get superscript ^x^, subscript
~x~, shorthand emoji (:rocket:),
autolinked URLs, footnotes [^1], collapsible
blocks <details>, definition lists, tasks
- [ ]/- [x] (⬜/✅) and the [TOC] token
(a clickable table of contents in reading); plus local images and inline
HTML (<kbd>, <mark>…). The Outline
panel (tab toolbar) walks the headings and follows the cursor, and the
Insert button (or the context menu → Format/Insert) applies
any markup.
Headings, folder notes and text tools
Sticky headers (sticky scroll): as you scroll, the headers enclosing the top line stay pinned in a strip at the top of the editor; clicking one jumps to that section (toggle it in Settings → Markdown). A folder's context menu in the tree creates/opens the Folder note (index.md with frontmatter), handy as an index.
Folder note and file list: double-clicking a folder opens its index.md, if it exists. Inside any note, the token [files] (or [arquivos]) alone on a line is replaced in formatted editing and in reading by the list of the note's folder files, as clickable links — generated on the fly, writing nothing to the file (like [TOC]).
Text and line operations. The code editor's operations work in notes too
— via the Text submenu of the Format button on the tab bar, the context menu and the Lines
and Cleanup submenus of the Edit menu: move the line (or the
selected lines) up/down (Ctrl+Shift+↑/↓), duplicate
(Ctrl+Shift+D), delete (Ctrl+Shift+L), sort (A→Z / Z→A),
reverse the order, join lines, remove duplicate or empty
lines, trim spaces and case (UPPERCASE/lowercase/invert).
Number lines… opens a dialog with start, step, leading
zeros and separator — with the default (". ") the result is
a valid Markdown ordered list. With a selection the operation applies only to it
(expanded to whole lines); with no selection, to the entire document — always a
single undo step. The tab bar also has an AI button: Ask / Edit with AI — the same Ctrl+K / Ctrl+I as in code — and Ask your notes, the chat that answers using the notes in the workspace.
Foldable headings: click the little arrow to the left of a heading (or use Ctrl+Shift+[ / Ctrl+Shift+]) to collapse and expand the section; under View there is Collapse/Expand all headings. Folding is purely visual — it is never written to the file — and LightNote remembers it across sessions. Jumping from the Outline or from a search into a collapsed section expands it.
Binder: the folder as one work
What it is: a folder whose notes are chapters, in an order you declare. It works for a book, a thesis, a course, a manual, a runbook or a work journal — the mechanism is the same. In the folder's context menu, Turn into a Binder opens a screen with the notes in their current order: drag to reorder and confirm. The order is saved in the chapters: key of the folder's index.md — a text file of yours, which travels with the notes and still works on any machine. A subfolder can also be named in the order: its chapters enter at the position where it appears, and it declares its own order in its index.md — that is how a book gets parts. A subfolder's cover does not become a page of the document; it is there to declare the order of that level and to navigate.
Navigating: with a declared order, the note's toolbar shows Chapter 3 of 12, with an arrow on each side (Alt+PgUp and Alt+PgDn); the middle button lists every chapter. The Outline panel then shows two levels: the chapters of the work and, under the one that is open, its headings. At the ends of the work the arrow is greyed out. In a folder without a declared order none of this appears, and everything stays as it always was.
The note template: a Binder can declare which template the notes created inside it start from (the template: key). There are five ready-made templates — book chapter, thesis chapter, lesson, procedure step and journal entry — and picking one saves it as a file in the Templates folder, where it stays editable. A note created inside the Binder joins the order by itself; a file dropped in from outside sits under Out of order until you adopt it. Renaming a chapter fixes the key and keeps its position. To start from a ready-made work, Structure from a template… (in the folder's context menu) writes both keys at once — the order and the chapters' template — keeping whatever cover you have already written; and while a declared chapter does not exist yet, the Outline shows a button that creates them all at once, each already from the folder's template. Nothing is overwritten: a chapter that is already there stays as it is.
Compiling into one document: when exporting the folder, the Compile the chapters into one document box produces one file with the chapters in the declared order. Because the text is joined before it is rendered, footnotes, figures, tables and citations are then numbered across the whole document — and a cross-reference from one chapter to a figure in another starts working. Whatever is not in the declared order is left out, and the report says what.
Properties, theme and zoom
Note properties: the Properties side panel shows the YAML frontmatter as typed fields (text, number, date, checkbox), with the Type box at the top. Setting the type and the properties is what lets you gather notes into a Base.
Note theme: the Theme box in the
Properties panel sets the look of this note — text colors and font —
without touching the theme of the rest of the app. The choice goes into the
frontmatter (the theme key), so it travels with the file:
the note looks the same on any machine. The button next to it writes the colors
into the note itself, so it looks the same even for someone who does not have
that theme. Without the key, the note follows the workspace theme. If you would
rather have notes from elsewhere not change your look, turn off Respect the
theme declared in the note under Settings → Markdown.
A theme LightNote does not know yet: the theme list is a single file downloaded from the site, so a note citing a theme published after your last update simply will not find it. The note then opens with the workspace theme and the Properties panel says so, with a shortcut to see the available themes. LightNote looks for the updated list on its own — once per session, in the background, without holding up the note. If you would rather it never fetched anything, turn off Fetch tool catalog online under Settings → Features.
Ctrl++ and Ctrl+− (or Ctrl+mouse wheel) change the size of the note, and Ctrl+0 goes back to 100% — handy to read a long note without changing the font of every note. The editor and the reading pane scale together: in split mode both sides stay the same size. An <svg> written straight into the note is drawn in reading too: you can paste an AI-generated chart without turning it into a separate file.
How many words, and where. The status bar counts the words in the note and estimates the reading time; next to it, section N is the count of the section the cursor is in — the same one the Outline highlights, from its heading to the next one of equal or higher level. Set a daily goal in Settings → Notes & writing and today N/M shows up too: what grew in the notes you opened today. Deleting does not subtract — revising your own text must not become a punishment —, a note you did not open does not count, and at midnight the tally resets.
Diagrams (Mermaid)
How it works
Mermaid diagrams. A ```mermaid fence holding a flowchart (flowchart/graph, in all four directions), a sequence diagram (sequenceDiagram) or a pie chart (pie) is drawn as a diagram in reading mode, in the exported file and in the answers of Ask your notes — which is where most diagrams come from. The drawing follows the note theme (ink, paper and accent), so it matches the surrounding text in both themes. In formatted editing — the default mode — the diagram is also drawn, with the block bar on top (copy, edit, delete). Edit opens a bar at the bottom with the source: the note is locked while it is open and the drawing is redone as you type; closing applies it (there is no save and no cancel), Ctrl+Z undoes the whole change in one step, and emptying the field removes the block. In split mode, clicking the diagram takes the cursor to the fence in the raw text. In the text editor everything stays text: press Ctrl+E to see the diagram. Inside a list item, the diagram — and also the SMILES structure, the block formula, [files] and ![[note]] — stays as text in formatted editing and appears drawn in reading mode: there the item's marker would have no way back into the file.
Subgraphs (subgraph … end, nested ones included) become boxes with a title, and edges cross the border starting from the real node; a subgraph id can also be an edge endpoint (sub --> X). Author-declared colors apply: classDef, class, :::class and style (fill, stroke, width, dashes and text color). To start one, use Insert → Diagram (Mermaid) in the note toolbar: it drops in a ready skeleton for the type you pick. The menu offers the six most used directly; All diagrams… opens a picker with all 33, grouped by what they are for, with search (by name or by what the diagram shows) and a rendered preview of each one — there are 33 drawings, and seeing the drawing decides faster than reading the name. The diagram frontmatter — the block between --- before the first line — is read too: title becomes the title drawn above the diagram (a title in the body wins) and the config keys LightNote knows reach the diagram (gitGraph.mainBranchName, gantt.displayMode, and the packet ones: bitsPerRow, bitOrder: descending — which mirrors the row — and showBits: false); what it does not know is ignored, without refusing the note.
Sequence, entities, classes and states
In the sequence diagram you get participant/actor (with as), the arrow forms (->>, -->>, -x, -)), activation (+/- and activate/deactivate), notes (Note left of/right of/over), the loop/alt/else/opt/par blocks and autonumber. Whatever is not drawn yet — other diagram types — keeps showing up as a code block, colored as before; direction inside a subgraph and linkStyle are ignored. The Mermaid v11 node syntax (A@{ shape: rounded, label: "text" }) is read, and the v11 shape catalog is drawn: doc, lin-doc, docs, tag-rect, win-pane, hourglass, bolt, flag, das… — each one is the symbol its name says, and none of them falls back to a rectangle, because a rectangle in place of a document would be another diagram. A name Mermaid does not have turns the diagram back into a code block, with the line pointed out. The edge id (A e1@--> B) and e1@{ animate: true } are accepted and ignored: the animation is not drawn. A typed participant (participant DB@{ "type": "database" }) draws the UML symbol above the lane — boundary, control, entity, database, queue and collections — and the "alias" declared there works like as.
The erDiagram is drawn too: each entity becomes a box with its attributes and the cardinality shows at both ends of the relationship (||--o{, }o--||, |o, |{); -- is an identifying relationship and .. a non-identifying one. The alias p[Person] names the box without changing the id the relationships refer to. subgraph … end works here too: the entities inside get a box with a title, subgraphs nest, and the box id can be one end of a relationship (CUSTOMER ||--o{ Sales : places), attaching to the boundary instead of to an entity by that name.
The classDiagram too: a three-compartment box (name, attributes and methods, split by the method parentheses), <<interface>> on its own line, namespace as a box and the six relationships (<|--, *--, o--, -->, ..>, ..|>). Mind the direction: in A <|-- B the triangle sits on A — the one that inherits is B. Quoted cardinality shows at both ends ("1" --> "*"). Generics List~T~ show up as List<T>, in members too. The lollipop interface (bar ()-- foo) draws the circle on top of the box on the side where the () is — and only there — with the relationship touching the circle; namespace blocks also nest, and after the inner } a class goes back to the outer namespace.
The stateDiagram-v2 draws the state machine: [*] is the start (filled disc) and the end (disc with a ring), state X { … } becomes a box, <<fork>>/<<join>> become a bar and <<choice>> a diamond. A -- inside a composite state separates the concurrent regions, marked by a dashed line.
Timeline, journey, quadrants and Gantt
The timeline is drawn too: each period becomes a column of the timeline, with its events stacked underneath, and section groups the eras into colored bands. Both spellings for several events work — colons on the same line (2004 : Facebook : Google) and a continuation on the next line (: another event) —, and here any line that is not title, section or direction is free text. direction TD (a vertical timeline) is not drawn yet and keeps the code block.
The journey (user journey) is drawn too: each task becomes a box on the journey axis, and the score from 1 to 5 moves its face up or down — it is the profile they form that the diagram exists to show. section groups the phases, and the actors become colored markers on the task, with a legend on the left. Here the grammar is strict (Task: score: Actor, Actor), unlike the timeline's: without the name/score pair there is nowhere to put the face, so a malformed line — or a score outside 1 to 5 — refuses the diagram, pointing at the line.
And the quadrantChart draws the four-quadrant plane: x-axis and y-axis name the ends of each axis (the right-hand side of --> is optional), quadrant-1 to quadrant-4 label the regions, and each point goes in as Name: [x, y], with x and y from 0 to 1. Mind the numbering: it is the one from the cartesian plane, not from reading order — quadrant-1 is the top-right one, and from there it goes counter-clockwise; y = 1 is at the top. A point's color and radius can come directly (P: [0.5, 0.5] radius: 10, color: #109060) or from a class (P:::class plus classDef), and the direct style wins over the class. A coordinate outside 0 to 1 refuses the diagram and points at the line instead of being clamped — it is the position on the plane, and clamping would put the point in a quadrant you did not write.
The gantt draws the schedule: dateFormat declares the format of the dates you write (default YYYY-MM-DD) and axisFormat the one used for the axis labels (%m/%d); section groups the tasks into bands. Each task reads Text : tags, id, start, end — the tags done, active, crit and milestone come first and can be combined, the start is a date or after otherId, and the end is a date, a duration (5d, 2w, 3h, 45m) or until otherId. With a single field, the task starts where the previous one ended. after may name a task declared further down the note; an id that exists nowhere — or a circular dependency — refuses the diagram and points at the line, instead of dropping the bar on today. excludes weekends (or excludes monday, or a date) pushes each task's end past the excluded days, and therefore changes how long the bars are; includes 2026-03-07 overrides the weekend, to say that this particular Saturday is a working day. A milestone shows up as a diamond, and todayMarker off removes today's line. displayMode compact stacks several tasks on the same row, and here a task only shares a row when nothing it occupies touches what is already there — the label included. The vert marker (Opening : vert, v1, 20:15, 0m) draws the instant as a vertical line crossing the whole chart, taking up no row of its own, and its label goes below the axis. dateFormat X (or x) reads the date as Unix time in seconds (or milliseconds), and on the axis %s/%Q writes it back. A tickInterval Mermaid does not know (1decade) is silently ignored, as it is there, and the axis goes back to automatic.
Mind map, requirements, Git and C4
In the mindmap the hierarchy comes from the indentation: an item's level is the column its text starts at, with no braces or arrows (a tab counts up to the next stop of 4, like in an editor). The first item is the root — a second item in its column would be a second root, and the diagram is then refused with the line pointed out. Each item may declare its shape: [square], (rounded), ((circle)), {{hexagon}}, ))bang(( and )cloud(; with no delimiter it comes out rounded. ::icon(...) and :::class are recognised and ignored (we do not ship the icon font, and the class refers to external CSS that does not exist here). The drawing has two sides — the root in the middle, the branches split left and right —, each branch with its own colour that the descendants inherit, and the twig gets thinner with depth. It is a tree, not a force simulation like in mermaid: in a mind map the hierarchy is the content, so it has to be readable from the position — and, since the drawing is redone when the theme changes, a layout converging from random starting points would rearrange the whole map every time.
treeView (treeView-beta) draws a project’s folder tree, and it accepts both spellings: indentation (what you type) and the very characters of the tree command (├──, │, └──), which is what lets you paste terminal output straight into the note — indentation alone would not do there, because │ and a space take the same column and only the first says the branch goes on. A trailing slash marks a folder (src/), a name with spaces goes in quotes, ## text hangs a comment at the end of the line, and :::highlight highlights the name. icon(...) is recognised and ignored, like the mind map’s ::icon(): icon packs come from Iconify through JavaScript, and not even Mermaid itself draws them by default.
ishikawa (ishikawa-beta) draws the fishbone of a root-cause analysis: the first item is the EFFECT (the head, on the right), the next level are the categories (the bones) and the two inner ones are the causes and sub-causes. Three levels — a fourth one refuses the diagram with the line pointed out, because it does not exist in Mermaid. The bones alternate above and below the spine, which is what lets two neighbouring categories fit without one’s text landing on the other’s, and the order you write the causes in reads top to bottom on both sides.
venn (venn-beta) draws overlapping sets: set A["Desirable"] declares one, union A,B["Buildable"] names the shared region (a union is named by the sets it crosses) and text A1["React"], right below one of them, puts an item inside that region. It takes up to three sets, and a fourth refuses the diagram with the line pointed out: with four circles there is no arrangement that produces every region, and drawing an "almost right" one would hide a region you declared. The :number after the label (set A["Alpha"]:20) scales the circle — area follows the number — and not the intersections: a Venn with proportional intersections is a different diagram (Euler), which needs numeric optimisation. style A fill:#ff6b6b paints one set, and with a comma (style A,B color:#333) it applies to the union of those sets.
cynefin (cynefin-beta) draws Snowden’s framework for classifying decisions: the five domains have fixed names — complex, complicated, chaotic, clear and confusion — and fixed positions (the four quadrants, with confusion in the middle); what you choose is what goes inside each one. Each item goes in quotes, one per line, and complex --> complicated : "Pattern identified" draws the transition between two domains. A name outside the five refuses the diagram with the line pointed out and the list of what exists. The border between clear and chaotic comes out wavy: in the model it is a cliff, and the shape says so — here the wave is always the same, so the note does not change drawing every time it is opened.
swimlane (swimlane-beta) draws a process in lanes, one per owner: the syntax is the flowchart’s (same shapes, arrows, labels and classDef), and each subgraph stops being a box and becomes a lane. Every node must sit inside one — a loose node refuses the diagram, because there would be no way to say whose task it is — and a lane inside a lane refuses too. With LR the lanes are rows and the flow runs right; with TB they are columns and the flow runs down. The position along the flow comes from the longest path to each task, and the band is the owner’s: a task never leaves its lane, even when that would make the drawing more compact.
agentflow (agentflow-beta) draws an AI agent flow, and it is another vocabulary for the flowchart: the arrows are the same, flow id["Name"] … end plays the part of subgraph (and nests), global … end holds what every agent consults, and connector id["Name"] declares an outside system. What really changes is the shape, which says each step’s role: @{ shape: input }, task, tool (a tool call), decision, refdoc (reference document) and action (the final action). Attach the document with -.-, no arrow: it is consulted, not a step of the flow. The keys that describe the agent in words (instruction, params, returns, connectorRef, protocol, endpoint) are read and ignored in the drawing. These shape names only work here — in a flowchart they refuse, because Mermaid does not have them there either.
usecase (usecase-beta) draws UML’s use case diagram: whatever is declared with actor becomes the stick figure, and everything else is a use case, drawn as an ellipse — that is the distinction the type exists to show. A use case can be written as Id("Label"), Id[Label], just Id, or just the quoted text; systemBoundary "Name" … end is the system boundary and note for X "text" attaches a note. The relations are UML’s: --> associates, --|> is generalization (the hollow triangle sits on the general one) and A ..> : include B — with the target after the colon — draws the dotted « include », which also works for extend. What describes the actor without changing the drawing (type, business, icon) is read and ignored, and <<Stereotype>> goes into the label. The json node is not drawn yet and keeps the code block: it is a multi-line block with the data tree inside, and there the JSON stays readable as text.
wardley (wardley-beta) draws a Wardley map: a plane whose vertical axis is visibility to the user (the top is what they see) and whose horizontal axis is evolution, from Genesis to Commodity. Mind the order of the pair: component Tea [0.63, 0.81] is [visibility, evolution] — the first number is the vertical axis, and read the other way the map still draws and starts telling a different strategy. anchor is the user at the top, A -> B links the chain (a name may contain spaces, quoted or not), A +> B is flow (thicker; +<> both ways and +'text'> with a label) and evolve Kettle 0.62 draws the dashed arrow to where the piece should get to. Also supported: evolution (renames the axis stages), size, (build)/(buy)/(outsource)/(market), (inertia) (the resistance bar), label [dx, dy], pipeline X { … }, note, accelerator/deaccelerator and numbered annotations with the annotations legend.
eventmodeling draws an event model: a timeline in three lanes — the screen on top, the command (and the read model) in the middle, the event at the bottom. Each line reads tf 02 cmd AddItem: the number is the moment (the column) and the middle word is the type, which picks the lane — ui, cmd/command, pcr/processor, rmo/readmodel, view and evt/event (the long forms work the same). The lane is not declared: it is the method. rf (resetframe) opens a new slice, with a dashed divider — that is where the story restarts. A frame’s schema goes in braces ({ description: string }) or by reference ([[Data]]) to a data Data { … } block, which may come later; and ->> 02 ->> 03 links the frame to the moments that feed it, by number.
railroad (railroad-ebnf-beta, -abnf-beta, -peg-beta or railroad-beta) draws a grammar as railway tracks: each rule becomes a path you can follow with a finger, and what you can write is what you can walk. A rule is name = expression ; (or name <- … ; in PEG) and may span several lines — it closes at the ;. Quoted text is a terminal (drawn as a capsule) and a bare name is another rule (a rectangle); | (or /) is choice, ? optional, + one or more, * zero or more, and ( ), [ ] and { } group, make optional and repeat. ABNF puts the repetition first (1*( ALPHA / "-" ), *DIGIT), PEG accepts the predicates !x and &x — which go into the label, because they consume no input — and railroad-beta takes the function spelling (sequence(choice(terminal("+"), …))). All four land on the same drawing: the bypass above is the optional and the loop below, with the arrow pointing back, is the repetition.
The requirementDiagram draws requirements and elements as compartment boxes: the declared type (requirement, functionalRequirement, performanceRequirement, interfaceRequirement, physicalRequirement, designConstraint) appears in guillemets above the name, and the fields id, text, risk and verifymethod become rows — in an element, type and docref. The relationships (satisfies, traces, derives, verifies, refines, copies, contains) are written a - satisfies -> b or mirrored as b <- satisfies - a, and in the mirrored form the first name is the destination. Only contains is a solid line, with the symbol on the side of whoever contains; the others are dashed with the arrow at the destination. A name with a space goes in quotes.
The gitGraph draws a repository history: each commit moves forward in time, branch name opens a new lane and starts working on it (like git switch -c), checkout goes back to another one and merge joins the two. Attributes take a colon: commit id: "text" tag: "v1" type: HIGHLIGHT (also REVERSE), and branch name order: 2 changes the lane order; cherry-pick id: "…" requires the id of a commit that exists. The shape tells the type — a filled dot for an ordinary commit, a square for a highlighted one, a circle with an X for a reverted one, a double ring for a merge and a cut circle for a cherry-pick —, because in a theme where two shades of the palette look alike only the shape separates them. LR: (the default), TB: and BT: turn the time axis. A checkout/merge of a branch that does not exist refuses the diagram and points at the line, instead of creating a lane you did not ask for.
The C4 family (C4Context, C4Container, C4Component, C4Dynamic and C4Deployment) is drawn as well, and in it everything is a macro — there is no arrow anywhere in the syntax. Each element becomes a box with the type in guillemets, the name in bold and the description below: Person(alias, "Name", "Description"), System, Container, Component and the Db, Queue and _Ext variants. In Container and Component the third argument is the TECHNOLOGY (Container(app, "App", "C++/Qt", "what it does")); in the others it is already the description. Boundaries (Boundary, Enterprise_Boundary, System_Boundary, Container_Boundary and the Node of C4Deployment) open a brace and become a titled box, nested ones included. The link is Rel(a, b, "label", "technology"); BiRel puts an arrow at both ends and Rel_Back points backwards. C4Dynamic numbers the relationships in the order they appear. The placement hints (Rel_U, Rel_D, Rel_L, Rel_R) and the Update…Style calls are accepted and ignored — the arrangement comes from the same layout as the other diagrams, and the colour comes from the note theme. A relationship naming an alias that was never declared refuses the diagram and points at the line, instead of inventing a box you did not write.
Board, charts and packet
In the kanban indentation is the syntax, with two levels: the outer one is the lane and the inner one is the card (id[Label], or just the text). The @{ ticket: LN-9, assigned: 'ana', priority: 'High' } after a card does not go into its text: ticket and assignee go to a footer of their own, and the priority (Very High, High, Low, Very Low) becomes the colour of the stripe on the left edge, on a warm-to-cold scale. All lanes end on the same line, and a lane with no card still shows — it is what tells you the column is empty. This is a drawn board, to explain a flow inside a note; the board you actually work on, with cards you drag, is the app's own Tasks panel.
The xychart (xychart-beta) draws bars and lines over two axes: x-axis "Title" [jan, feb, mar] gives the categories — a name with a space or a comma goes in quotes — y-axis "Title" 0 --> 100 fixes the scale, and each bar [10, 40, 90] or line [20, 30, 80] adds a series with one value per category, in the order they were declared. A series with more or fewer values refuses the diagram pointing at the line: the bars would slide onto other categories and the chart would start claiming something else. Without y-axis the scale comes from the data and starts at zero when the data does not go below it — starting at the smallest value exaggerates the difference between bars, and nobody asked for that; with a declared range, a value outside it refuses instead of overflowing the plot. x-axis also takes a continuous range (0 --> 100), and without it the categories are the indices. Two bar series appear side by side, not overlapping as in mermaid — overlapping, the one behind disappears. xychart-beta horizontal is not drawn yet and keeps the code block, because drawing it vertically would hand you the chart transposed. A series can have a name (bar "Open" [10, 40], line "Closed" [20, 30]): the names become a legend above the plot, each with its series’ own shape — a filled bar, a line with a dot — because colour alone does not tell them apart. And in a line series a value can carry a label ([540 "PaLM", 65]), drawn above the point; on bars the label is ignored, as in Mermaid.
The radar (radar-beta) draws the profile of one or more curves over axes that radiate from the centre: axis a["Label"], b, c declares the axes — the line may repeat — and curve x["Name"]{80, 60, 90} gives one value per axis, in the order the axes were declared; the named form ({a: 80, c: 90, b: 60}) works too. Mind the direction: the first axis points up and the turn is clockwise. max and min fix the scale — without max it comes from the largest value read — and a value outside it refuses the diagram pointing at the line instead of being clamped; ticks changes the number of rings, graticule circle makes them round and showLegend false drops the legend. A curve with more or fewer values than axes also refuses: it would not be an incomplete drawing, it would be a different one.
The packet (packet-beta) draws the bit map of a packet: each field is 0-15: "Label", and the range is closed at both ends — 0-15 is sixteen bits. A single bit is written 4: "Label", and the relative form +16: "Label" takes the next sixteen, so you do not have to renumber everything when you insert a field in the middle. Fields must be contiguous: a gap or an overlap refuses the diagram pointing at the line, because either one would silently shift everything after it. A row holds 32 bits, and a field that crosses the turn is drawn on both, with the label in the wider part; the numbers above the grid mark where each field starts, plus the last bit of each row.
Grid, areas, architecture, flow and ZenUML
The block (block-beta) draws a grid of boxes, and in it the position is the order you wrote them in: columns 3 sets how many columns the grid has — without it everything goes in a single row — each box takes the flowchart shapes (a["Label"], b(("circle")), c{"rhombus"}), a:2 makes a box span two columns and space (or space:2) leaves a hole. block:id … end nests a grid inside another, with its own columns, and becomes a box around it. Arrows are the flowchart ones (a --> b, labelled as a -- "text" --> b), but here they only reference blocks already declared: an arrow to a name that does not exist refuses the diagram pointing at the line, instead of inventing a box in a cell you did not write. The gap between columns grows until the arrow label fits, so it never touches the neighbouring box. The block arrow (a<["Out"]>(right)) is a box shaped like an arrow: the directions go in parentheses (right, left, up, down, or x for both horizontal ones and y for both vertical ones) and combine ((x, down)); a made-up direction refuses the diagram with the line pointed out, instead of becoming just any arrow.
The treemap (treemap-beta) draws a map of areas: each rectangle has an area proportional to its value, and indentation nests, with free depth. A leaf declares the value ("Name": 12) and a section declares nothing — its value is the sum of its children, and a total of its own would allow a rectangle that lies about its own parts, so that refuses the diagram pointing at the line. A name with a space or a colon goes in quotes; classDef and :::class give colour. The arrangement is squarified, which keeps rectangles close to square — always slicing on the same axis would produce strips you cannot compare by eye, and comparing areas is the only thing this type does. Label and value appear only when they fit whole inside the rectangle: cut off at the border they would tell you nothing.
The architecture (architecture-beta) draws services and the links between them: service api(server)[API] declares a component, group cloud1(cloud)[Cloud] opens a boundary, the in cloud1 suffix puts the service inside it (groups nest) and junction j creates a corner to bend a link. The side of the link is what decides the position: a:R -- L:b touches the right of a to the left of b, that is, it puts b to the right of a; L, R, T and B all work, and the arrowhead appears on the side of the < or the > (-->, <-->, or -- with no head at all). The {group} suffix on an end sends the line to the group boundary instead of the box inside it. The icons are the five Mermaid ships built in — cloud, database, disk, internet and server — and any other name refuses the diagram, pointing at the line and naming the ones that exist. The rest (logos:aws-lambda and the like) come from Iconify and only show up where whoever publishes the page registers the pack in JavaScript, which not even GitHub does: accepting them here would hand you a drawing that reproduces nowhere else. align row a b c (or align column) puts the members named on the same row — or in the same column — and a name that does not exist refuses the diagram with the line pointed out, instead of leaving the arrangement as it was without saying why.
The sankey (sankey-beta) draws a flow diagram in which the thickness of the ribbon is the value: the body has no arrows at all — it is a three-column CSV (source,target,value), one link per line, and repeating a name at both ends is what chains the flow. A label containing a comma goes in quotes, and a quote inside it is written doubled ("Fixed ""cost"""); the same source/target pair repeated is summed. A node's bar is as tall as the larger of what comes in and what goes out, so that the outgoing ribbons of a node that distributes more than it receives do not spill past the edge. The columns come from the longest path to each node, and whatever has no outflow goes to the last column. A value of zero or less, a link from a node to itself and a cycle refuse the diagram pointing at the line — in a cycle there is no longest path, and cutting a link in order to draw would show a flow you did not write. There is no title here: the body is plain CSV, and accepting one would draw fine in LightNote and be a syntax error in Mermaid.
The zenuml is another syntax for the same drawing — a sequence diagram — written as code instead of arrows. A synchronous call names only the target (Store.register(item)) and the sender is the block that encloses it: inside Store.register() { Stock.reserve() }, the one calling Stock is Store. At the outer level the caller is the starter — @Starter(Ann) names it, and without it a stick-figure User is used, appearing only if some call needs it. The asynchronous message is A->B: text (open head, nobody waits) and A->B.method() is the synchronous call with the sender spelled out. {} nests, return x goes back to whoever made the enclosing call (an if in between does not change that), x = A.m() is the other spelling of the same reply, new A(args) creates and // comment becomes a note above the next message. The blocks are if/else if/else, while/for/forEach/loop, opt, par and try/catch/finally — and } else { continues the same frame with a divider instead of opening another. @Actor draws the stick figure; the other annotators (@Database, @Boundary…) become a stereotype in the label («Database» Stock), because their icons are not drawn here — the name still shows, which is what matters. A name with a space goes in quotes. Mind where this block ends up: in Mermaid, zenuml is an external diagram the page must register in JavaScript — GitHub does not do that, so the same note that draws here shows up there as a code block.
And when LightNote cannot read a diagram it says why and on which line, right below the block — a type we do not draw yet gets no warning, because nothing you wrote is wrong there.
Mathematics and chemistry (LaTeX)
Formulas (LaTeX)
Math (LaTeX). $E = mc^2$ in the middle of a sentence and $$…$$ as a block become a drawn formula in reading mode, in the exported file and in Ask your notes answers. The drawing follows the note theme. In formatted editing a block formula is drawn too, with the block bar on top (edit, copy, delete); and so is a formula in the middle of a sentence, seated on the text line. To edit it, double-click it or press Ctrl+Enter: it opens in the same bar. And Backspace right after it turns it back into $…$, to edit in place. In the text editor everything stays text: press Ctrl+E to see the formula. To get started, use Insert → Formula (LaTeX) in the note toolbar. Formulas are drawn with the system math font — on Windows, Cambria Math — rather than with the note's body font: that is where the math italics come from, along with the symbols a text font does not have and the parentheses and roots that grow with their content. With no math font installed, LightNote falls back to the note's font and draws those signs itself.
The subset covers Greek letters, operators and relations, the ^ exponent and the _ index, \frac, \sqrt (with index), \left…\right with growing delimiters, \sum/\prod/\int with limits, roman functions (\sin, \log…), \text/\mathrm/\mathbf/\mathbb the \mathcal/\mathfrak/\mathsf/\mathtt/\boldsymbol alphabets, \binom, \overset/\underset, \bmod/\pmod, the \big…\Bigg family the spaces \,/\quad/\hspace, the environments cases, matrix/pmatrix/bmatrix/vmatrix, aligned, gathered and array (with | and \hline), \overbrace/\underbrace, \begin{CD} and \begin{tikzcd} (commutative diagrams), \xrightarrow, \boxed/\cancel, \not, \substack, \|/\middle, \smash, \textcolor/\color (your hue; the lightness adjusts to the note's theme), \colorbox/\fcolorbox (the background comes out in the color you wrote, and the text adjusts to it), \tag (the equation label, right after it; in an align, one per row, lined up in a column), \phantom, \displaystyle and the infix forms \over/\atop/\choose. Coverage goes beyond this list: the comparison variants (\leqslant), logic (\land, \vDash), statistics operators (\argmax), the stretchy double arrows (\xRightarrow) and double brackets (\llbracket) are in too. The old TeX font switches also work — {\rm d}x, {\bf A}, {\cal L} — as does Dirac notation (\braket{\phi|\psi}). Macros defined in the formula itself (\newcommand, \def) last until its end, Unicode symbols typed directly (x ∈ ℝ) count as their commands, \text{…} accepts math between $…$, and a standalone formula can span several lines with \\. \label{eq:name} inside a $$ block numbers the equation in reading mode, with the same counter as {#eq:name}, and \eqref{eq:name} in the text becomes the number in parentheses. The LaTeX spelling works too: \(…\) inline and \[…\] as a block draw the same — it is the form ChatGPT usually emits. Whatever it cannot draw keeps showing up as the text you wrote.
Commutative diagrams with diagonal arrows (\begin{tikzcd}). \begin{CD} only draws horizontal and vertical arrows; the commutative triangle — the most common diagram there is — needs the diagonal. Each object is a cell (& separates them, \\ starts a row) and arrows are written inside the cell: A \arrow[r, "f"] \arrow[rd, "g"'] & B. The direction is a run of r/l/u/d (rd is the diagonal, rr spans two columns), and \ar and the shorthands (\rar, \dar, \drar) are the same arrow. The quoted label sits above an arrow going right; ' (or swap) puts it on the other side, which is what says whether the name falls inside or outside the figure. hook (inclusion), two heads (surjection), dashed, Rightarrow and equal work too. Curving (bend left) and any option this subset does not draw are refused with the name — drawing two curved arrows as straight ones would lay them on top of each other, claiming there is only one.
A $ in prose does not become a formula: in costs $5 and $10 the price stays a price, because the opening cannot be followed by a space nor the closing be preceded by one nor followed by a letter (that is what keeps PATH=$dir1:$dir2 from becoming a formula) — and $x$ between backticks stays code. When the formula does not appear, LightNote says why: a line below the $$ block, and only once per distinct message when the formula sits inside the text, naming the command or the delimiter it could not read. If the formula was pasted in the \(…\) spelling and you prefer $…$, Format → Normalize formulas to $ rewrites the selection (or the whole note) — in the text editor, which is where the note's characters are on screen.
Chemistry: mhchem and SMILES
Chemistry. The mhchem notation is drawn as well: \ce{2 H2 + O2 -> 2 H2O} places the subscripts on its own, -> and <=> become arrows (labelled with ->[\Delta]), Na+ and SO4^2- become charges, (aq) and (l) come out upright and tight, ^{227}_{90}Th lines up the isotope, and v/^ mark a precipitate and a released gas. \pu{123 kJ//mol} writes a quantity with its unit — the double slash becomes a fraction. The shifted equilibrium (<=>> and <<=>) draws the long arrow in the direction the reaction favors, spelled-out bonds (\bond{~}, \bond{~-}, \bond{...}) overlap their strokes the way textbooks do, and Kröger–Vink notation (O''_{i,x}, Li^x_{Li}) puts the effective charge in the superscript. Variables come out italic and elements upright: in NO_x the x is a variable, in Fe^{II} the II is the oxidation state.
Structures in LaTeX (\chemfig). \ce writes the formula; \chemfig{...} draws the skeleton inside the formula itself — \chemfig{H_3C-[:30]CH_2-[:-30]OH} is ethanol, \chemfig{*6(-=-=-=)} is benzene. The angle is yours: [:30] is absolute, [::45] is relative to the previous bond, and [3] counts eighths of a turn. Bonds are -, = and ~, and the stereochemistry wedges are >, <, >:, <:, >| and <| — the narrow tip sits at the stereocentre. Parentheses hang a branch and *6(...) closes a regular ring (**6(...) draws the aromatic circle); from a ring vertex, a bond with no written angle points outwards. Element symbols come out upright, and the line stops before the letter. chemfig’s departure and arrival nodes ([,,1,2]) are refused with the reason: they choose which part of the label the bond attaches to, and ignoring them would draw a different structure. A fused ring goes inside the first ring's body, right after the bond they share, and the inner one writes one bond fewer — that side is already drawn: naphthalene is \chemfig{*6(-=-*6(-=-=-)=-=)}.
Chemical structure (SMILES). A ```smiles fence with one SMILES line (CC(=O)Oc1ccccc1C(=O)O) is drawn as a skeletal formula in reading mode, in formatted editing, in the exported file and in Ask the notes answers. It is the counterpart of \ce: that one writes the formula, this one draws the molecule. The skeletal convention holds — carbon is not written (it is the vertex), the heteroatom gets its symbol in the theme accent, and the aromatic ring (c1ccccc1) gets the dashed circle inside. Stereochemistry is drawn: [C@H] and [C@@H] become a wedge — solid when the bond comes toward you, hashed when it goes back, with the narrow end at the stereocenter — and F/C=C/F and F/C=C\F come out trans and cis as written. What has no representation on paper (the named non-tetrahedral forms, such as @SP1) is accepted, and a caption inside the image says it was declared and not drawn. One fence draws one structure: a space in the middle of the line is refused, because in SMILES it ends the structure. When it cannot be read, LightNote says what is wrong (the bracket, the ring number, the element) and the code block stays as you wrote it. To start, use Insert → Structure (SMILES) on the note bar.
Calendar in a note
A ```calendar fence draws a calendar inside the note, in reading mode, in formatted editing and in print. It is a real table, not an image: you can select it, copy it (pasted into Word or Excel it keeps the cells) and find an event with Ctrl+F. The first line says which calendar: a month (2026-09) shows the month; a date (2026-09-24) shows the week that contains it, with days in the columns and hours in the rows; and week shows a week without dates — a class timetable, a routine, a shift roster. Each following line is an event or an option, and lines starting with %% are comments. To start, use Insert → Calendar on the note bar (monthly, weekly or weekly without dates, already filled with examples) or type /calendar.
Month. An event starts with the day number: 15: Thesis defense marks a day, 22-26: Conference marks a range, and 24: with no text just highlights the day. A range's text appears on its first day and, when it crosses into the next week, also at the start of the following row.
```calendar
2026-10
15: Thesis defense
22-26: Conference
```
Week. An event starts with the day's name — mon, tue,thu or mon-fri — followed by the time: mon 09:00-10:30: Meeting. The time is written 09:00, 9h30 or just 9; without it, the event goes to the top row, the all-day one (fri: Deadline). Because the day is a name, copying the block to the next week changes only the first line. days: mon-fri picks the columns, in the order of the list; hours: 8-18 fixes the range (without it, 8 to 18, stretched to fit the events; with it, an event outside the range is refused); and step: 30 gives the minutes per row. A long event writes its text, with the time, only in its first row and tints the following ones.
```calendar
2026-10-14
days: mon-fri
mon,wed 09:00-10:30: Team meeting
tue 14-16: Study
tue 16-17: Review
fri: Project due
```
In all three forms, title: replaces the bar's title (in the week without dates, the bar appears only with it), week: monday starts the week on Monday (the default comes from the note's language; with days:, the order of the list rules) and today: no removes the mark on today — in the week without dates, the mark is the weekday. Events that touch get different colors, so they don't read as one. The language of the months and weekdays is the note's (the lang key in the frontmatter), and the weekend follows that language's custom. Today is marked only on screen: on paper and in PDF it is not, because whoever reads it does so on another day. To change the calendar, press Ctrl+Enter on it and edit the source in the bar — typing in a cell changes nothing, because the table is generated from the source. With the bar open, the table is redrawn as you type; closing the bar applies it, and Ctrl+Z undoes the whole change in one step. When exporting (Word, OpenDocument, HTML, LaTeX, GitHub Markdown), the calendar becomes a regular table with the title. When the source cannot be read as a calendar, LightNote tells you the line and the text, and the code block stays as you wrote it. Inside a quote or a list, the calendar appears in reading mode and stays as code in formatted editing.
Numbering and cross-references
Give a figure a label and it gets a numbered caption in reading mode:
{#fig:cycle} becomes the image
followed by Figure 1 — The water cycle. A table takes its label on a line
starting with a colon, right below it:
: Collected samples {#tbl:samples}. And a display equation gets its
number in the right margin when the closing $$ carries
{#eq:mass}. This feature comes turned off: switch it on in Settings → Features → Academic → Numbering and cross-references. LightNote is a simple editor that also handles a thesis, and someone who does not write academic work should not pay for it with menus and options they never use.-numeracao
Then just point at it: @fig:cycle becomes Figure
1, [@fig:cycle] becomes (Figure 1) and
-@fig:cycle becomes the number alone. Same grammar as citations, on
purpose. Inserting a figure in the middle renumbers everything by
itself — the count belongs to the document, in reading order.
Numbering is opt-in, through the label: an image without
{#fig:…} stays exactly as it is today. And a label that does not
exist stays as you wrote it, like a citation: that is the clue that a
reference is broken.
Numbered sections (ABNT NBR 6024): declare
section-numbers: true in the note's properties and the headings get
their indicative — 1, 1.1, 1.1.1 — left aligned, separated
by one space and with no trailing dot. A heading with {#sec:method}
can be pointed at by @sec:method; without numbering, the reference
becomes the section's title.
Alone on a line, [list of figures] and
[list of tables] build the lists the standard asks for, the way
[TOC] builds the outline. All of this belongs to reading
mode (and to the exported PDF/HTML): in the editor the file keeps what you
wrote, which is what makes renumbering possible without touching the note.
Citations and references
Write a citation inline with [@key] — the key is the one the work
has in your bibliography. Typing @ makes LightNote suggest the works
it knows, showing author, year and title; only the key goes into the note. There
are also [@key, p. 45] (with the page), [-@key] (when
the author's name is already in the sentence) and [@a; @b] (several
works at once). This feature comes turned off: switch it on in Settings → Features → Academic → Citations and bibliography. LightNote is a simple editor that also handles a thesis, and someone who does not write academic work should not pay for it with menus and options they never use.-citacoes
In reading mode the citation becomes formatted text — (Silva, 2020,
p. 45) — and the token [bibliography] alone on a line becomes
the list of the works you cited, in the order the style requires. In the
editor the key stays visible, because the key is what you edit.
The bibliography is a file in your workspace: any .bib,
.ris or .csl.json in the folder counts. That is what
makes it travel with your notes through Git or a USB stick and keep working on
another computer. Opening one of those files shows the list of works with each
key, ready to copy.
To bring works in: Tools → Bibliography → Add work by DOI takes a DOI or an arXiv identifier and fetches the rest by itself; and Import from Zotero reads the library of the Zotero 7 running on this computer (first tick Preferences → Advanced → Allow other applications on this computer to communicate with Zotero).
The style belongs to the folder, and a note may disagree. Pick the
default in Tools → Workspace Settings → Citations (ABNT, APA 7 or
Vancouver); a note headed elsewhere declares citation-style: apa in
its properties. A key that is not in the bibliography stays as you wrote
it, so you can see which one to fix.
Connections graph
Tools › Connections graph (Ctrl+Alt+G) shows every note in
the workspace as an interactive graph: each node is a .md note, each
line a wikilink. Nodes settle into place on their own (animated physics) and can be
dragged; hovering highlights the neighbors and fades the rest;
click opens the note. Scroll to zoom (names appear as you get closer) and
drag the background to pan.
On the tab's toolbar: filter by name (fades non-matching notes), a toggle for orphan notes (no links at all — shown in gray), force sliders (repulsion, distance and gravity), fit the graph to the window and rescan the notes. The more connections a note has, the bigger its node; each top-level folder gets its own color.
Similar notes. The Connections mini-bar, inside the note itself, lists incoming links, outgoing links and mentions by name. At its end is the Similar notes section: notes about nearby subjects even without a link or a shared word. It is computed when you ask (click Compute), not on every note switch, because walking the index costs disk reads. Each row shows the name, how close it is and the excerpt behind the suggestion — without that evidence there would be no way to judge it. It spends no AI call: it uses the meaning index that already exists, so the section only appears with semantic boost (embeddings) turned on in Settings → General → Features.
Tables (Parquet, CSV, JSON, Excel)
Opening and querying
.parquet files open as a table; .csv,
.tsv and .json open as text, and the tree's context
menu offers Open as table. Reading is paginated (on demand) via
DuckDB, with sorting (click the header) and filtering pushed
down to the engine. The Structure button shows columns, types, row count
and, for Parquet, row-groups and compression. The view is read-only.
The free SQL bar at the top of the table accepts any DuckDB query —
the view t stands for the opened file. From a folder's
context menu in the tree, Open folder as table reads every file of the
same format as a single table; from the table's menu you can export the
current view (CSV/Parquet/JSON), and from the tree's menu, convert a
tabular file to another format. Free-form SQL is also available in the
query command of the command line and in the
MCP.
Excel spreadsheets (.xlsx) open as a read-only table with
a sheet selector — a lightweight reader, no Excel installation needed.
Excel spreadsheets
Faithful to the file. The sheet shows up with the file's own
formatting: numbers, currency, percentages and dates follow the format set in
Excel — a value stored as 3750.5 with a currency format shows as
$3,750.50, and a percentage comes out as 15% instead of
0.15. The font (name, size, bold, italic, underline), text colour, fill
colour, per-cell borders, alignment, text wrapping, indent, rotated text and
column widths also come from the file. Numbers sit on the right and text on the left,
as in Excel.
When the sheet carries its own colours, the grid is drawn on a white background: Excel's colours were picked for white paper and would be unreadable over the dark theme. A file with no formatting at all keeps following the LightNote theme. The sheet opens in the order it was written — clicking a header sorts it, like every other table.
Original layout and zoom. When the sheet uses merged cells, custom row heights or hides the gridlines, the tab opens in Original layout mode (button on the toolbar), which reproduces that geometry as in Excel. The mode governs only the geometry — colour, font, borders and number format apply in both — and while it is on, sorting and filtering are unavailable, because reordering would leave the merged band on the wrong row; turn the button off to sort again. A sheet with none of that opens in the normal mode. Zoom is the same as in every view and lives in the status bar (see Workspace and windows); Ctrl+mouse wheel works over the grid too. A sheet formatted as an Excel Table also shows up coloured: its style is built into Excel and does not travel in the file, so the header and the banded rows are reconstructed from the theme.
Copying, filtering and charting
Copy as. In the context menu of any LightNote table (Parquet/CSV/JSON, Excel, SQL results, Tasks, Bases), the Copy as item puts the selection on the clipboard already formatted. Formatted table (Teams, Outlook…) pastes as a real table, with borders and a header, into programs that understand rich text — Teams, Outlook, Word, Excel (where there is no rich text, it falls back to TSV automatically). The others paste as plain text: Markdown table (ready for a note), CSV (quoted per RFC 4180), TSV (tab-separated), HTML (the <table> markup), JSON, JSONL (one record per line), YAML, and the Code submenu, which generates a literal ready to paste into a source file: Python (list of dicts) or JavaScript / TypeScript (array of objects). In JSON, YAML and code, cells that are numbers come out unquoted — but the original text is preserved, so IDs like 007 stay text. Ctrl+C still copies as TSV, as before.
Every table behaves the same way: Ctrl+F focuses the quick filter ("contains in any column"), a counter shows how many rows are left, and there is Export to CSV — including in .xlsx spreadsheets, in Tasks and in Bases. The grid's context menu still offers Copy as.
Result chart. The table's side bar has a Chart button (bars, line or scatter): the aggregation runs in DuckDB (no raw rows are pulled), and an Add to today's note button saves the chart as an image. The Structure panel also includes a per-column profile — a mini-histogram of numeric columns and the most common values of the others.
Several charts and a pivot table. To cross two fields and aggregate a third — and to keep more than one chart per table — see Analysis area.
Analysis area: pivot table and several charts
The chart and the statistics
A table tab has two modes, on the Data and Analysis buttons in the bar. Data is the usual table; Analysis is a board where as many charts and pivot tables as you like live side by side over the same source — each on a card, with an editable title, a gear button that reveals the selectors and a ⋮ menu (move, duplicate, remove).
Real statistics. Besides bars, line and scatter, the chart does a box plot: one box per category with the quartiles, the median as a thick line and the whiskers at the Tukey fence (1.5 × IQR) — not at the minimum and maximum. Over the mean of a column, the Error selector adds the spread whisker: ± standard deviation (which describes the data), ± standard error or ± 95% CI (which describe how precise the mean itself is). All three appear only with the mean chosen, because "sum ± deviation" means nothing. The Log Y axis box switches to a logarithmic scale, for data spanning orders of magnitude; when some value is zero or negative it is ignored with a notice, because the logarithm does not exist there and dropping the point silently would make the chart lie. On the scatter, Trend line draws the regression line with R², fitted in the database over all the rows — not over the sampled points shown on screen. Under the drawing sits a line of descriptive statistics for the chosen column (n, mean, deviation, 95% CI, minimum, quartiles, median and maximum), which is a query of its own: deriving it from the bars would give the average of averages, which matches the real mean only when every group has the same size.
Pivot table and totals
Pivot table. Pick the fields that go on Rows and on Columns (you can nest more than one on each axis; dragging reorders the levels), the field on Value and how to reduce it: Sum, Count, Distinct count, Average, Minimum or Maximum. With no field on Value, rows are counted. It is also on the table's side mini-bar, next to the Chart, for a quick look without leaving the data.
The aggregation runs in the database and comes back already reduced — no raw row travels up, so a Parquet file with tens of millions of rows stays workable. Because the query is standard SQL, the pivot table works on every database of the SQL client (SQLite, DuckDB, PostgreSQL, MySQL, SQL Server and Oracle), and not only on DuckDB as the chart does.
Totals. The Row totals and Column totals boxes add the closing row and column. For Average the total is weighted, not the average of averages — which would be wrong whenever the groups have different sizes. A Distinct count cannot be totalled (the union of distinct sets does not follow from the sum of the parts), so there the boxes are disabled, with the reason in the tooltip, instead of showing a wrong number.
Where it is saved, CSV and grouping
Where the analysis is saved. In a JSON next to the data file (sales.parquet → sales.parquet.analysis.json): an open format that goes into Git along with the data and travels with it to a colleague. The Analysis file button opens that JSON in a tab, and emptying the analysis deletes the file. A whole folder opened as a table has no path of its own, so that analysis is not saved — the button says so. Each card also has Add to today's note: the chart goes as an image and the pivot table as a Markdown table, which in the note remains text you can copy and edit.
With a CSV, a single gesture — and a way out when the separator fools it. Open as table opens through DuckDB, with free SQL, chart, pivot table and the analysis area. Sometimes the separator is not recognised (rows with differing column counts usually cause this) and the table comes back with a single column, the whole line inside it. When that happens, a bar appears above the table saying how many columns the file seems to have and offering the tolerant read: it reads line by line without requiring equal columns — the same reading search and the AI use — and it filters and sorts, but has no free SQL, chart or pivot table. For text that is not saved yet, or with a delimiter you choose by hand, use View → View as delimited file….
Group by pattern. In a column of dates or codes the distinct values are almost as many as the rows, and grouping by them says nothing. The pattern mask turns every letter into A and every digit into N, leaving the rest: 2027/10/10 becomes NNNN/NN/NN. Millions of rows then collapse into two or three shapes — and whatever escapes them is exactly the dirty data (the date that came as 10-10-2027, the code without its prefix). In the chart it is the Pattern checkbox next to the X axis; in the pivot table, right-click a field's pill (it is per field, so you can cross the shape of a code with a normal dimension); and in the Structure panel the most common patterns appear under the most common values of each column. The work runs in the database. On SQLite and generic ODBC the option is disabled with the reason: the text function the mask relies on is missing.
PDF and images
.pdf files open in a native viewer (Qt6::Pdf, no heavy dependencies), rendered on the CPU and without WebEngine. Images open in the image view; animated GIFs play in the animated view.
The tab toolbar offers six side panels, one at a time: Outline (the table of contents stored in the file itself — when the PDF has none, the button is disabled and says so), Thumbnails (the pages at a glance, rendered as you scroll), Search, Links, Properties (title, author, dates, page and file size) and Highlights (the passages you highlighted, in reading order).
Search (Ctrl+F) looks through the whole document: matches are highlighted on the pages and listed with their surrounding text, and F3 / Shift+F3 step between them. The scan is progressive, so the list grows as the document is walked through.
The page field accepts the number or the printed label: in a document whose front matter is numbered in roman numerals, typing 1 goes to the printed page "1", not to the first sheet. The page mode button switches between continuous scrolling and one page at a time.
A password protected PDF asks for the password when opened (up to three tries); cancelling simply leaves the tab unopened. Within the same LightNote run the password is not asked again — the app reopens the tab by itself when it releases it for being idle, and it would be the app creating the annoyance. Ticking "Remember this file's password" in the prompt makes it last across runs too: it is protected by Windows (only for you, only on this machine), never goes to Git or to the cloud, and is not carried by the settings export. To erase them all: Settings → Features → PDF passwords. A protected PDF is not reopened on startup — instead of queueing password prompts before showing the window, it waits for you to open it.
From the toolbar action menu: copy the page text, export the whole document's text, copy or save the page as an image, and send the page to today's note. The Links panel exists because Qt's PDF component follows internal links on its own but ignores external ones — that is where a web address is opened, with a confirmation.
Highlighting. The Highlight button turns on the marker pen: drag over the page's text and the passage is highlighted; the arrow beside it picks the colour. The highlight attaches to the text, not to a rectangle — that is why it follows zoom and page mode without drifting, and why it does not work on a scanned PDF, which has no text layer (the app says so instead of doing nothing). In the Highlights panel, clicking jumps to the page and the context menu adds a note, copies the passage or deletes it. In the toolbar's action menu, Copy the highlights and Save the highlights as a note… write the reading notes in Markdown: each passage as a quote and, per page, a link that opens the PDF there (paper.pdf#page=12). The price: highlights are saved in a file beside the PDF (paper.pdf.highlights.json, readable text you can version with Git) and not inside it — so they show up in LightNote and not in another PDF reader. If the file is replaced by a different version, a highlight that lost its place is marked as such instead of being painted over the wrong sentence.
Limitation: outside the marker pen there is no mouse text selection, because Qt's PDF component does not provide it. To take the content with you, use "copy this page's text", the document export or the highlight itself.
Images: marking up a screenshot
The tools
An image opens in a tab with its own toolbar: besides rotating, mirroring and zooming, it carries the markup tools — the path from taking a screenshot to pointing at what matters and carrying it off into the documentation. And you do not need a screenshot to start: New → New blank image creates a white .png sheet in the marked folder and opens it with the Pen already in hand — Move, the default when you open an image, would have nothing to drag here.
The starting tool is Move: dragging still moves the image, as it always did. Select picks a part — drag to create it, drag from inside to shift it and use the handles on the corners and edges to resize; Esc deselects and Del erases the contents of the region. In Move mode, Shift+drag also selects. In any tool, the middle mouse button moves the image.
The Eyedropper picks a colour from the image itself: the left button sends it to the border colour, the right button to the fill. It reads from the already marked-up image, so it also repeats the colour of a mark you have just made.
The others draw: Rectangle, Ellipse, Arrow, Line, Highlight (translucent, like a marker pen), Pen (freehand), Brush, Numbered step (which numbers itself — 1, 2, 3...), Text, Blur and Spotlight (darkens everything except the chosen region). While drawing, Shift locks squares/circles and 45° angles.
Colours, thickness and blur
There are two colours, in two buttons: the border one (which is also the stroke and the label colour) and the fill, which may be none. With no fill, the rectangle and the ellipse come out as outlines only, and the numbered step and the text use the border colour as their background, with the label in white or black — whichever contrasts. Choose a fill and it becomes the inside of the shape and the background of the label, while the border becomes the text colour.
The Brush paints with the fill colour, in a dab the size of the stroke width — round or square, by the button next to the width. A single click already leaves the mark. With a white fill it is the eraser: it covers whatever is underneath.
The width applies to the stroke, to the size of the label and to the block size of the blur; it is greyed out in the tools that ignore it. Colour and width are remembered across sessions. Ctrl+Z and Ctrl+Y undo and redo the markup, and Clear markup wipes it all at once (also undoable).
Blur is for hiding (a token, an e-mail address, a path). While the tab is open the markup is reversible, but on saving or copying the pixels of that region really are destroyed: the file that leaves does not keep the original anywhere.
Cut, paste, rotate and capture
Three operations have similar names and do different things. Cut (Ctrl+X) copies the selection to the clipboard and erases the region, painting it with the fill colour (white when there is none) — and the selection stays put, so Paste right afterwards brings the piece back exactly where it came from, floating: that is how you move a piece of the image. Del is cut without copying. Keep only the selection, in the Image menu, does the opposite: it keeps the region and throws the rest away, changing the size of the image.
The rest of the family: Copy takes the marked-up image or just the selection; Paste brings the image from the clipboard as a floating paste — move and resize it by the same handles and click outside (or press Enter) to keep it, Esc discards it; and Ctrl+A (or Ctrl+T) selects the whole image. There are also Save (writes the markup into the file itself), Save as... and Send to today's note, which writes the PNG into Anexos/ and inserts the ![]() in the note. While there is unsaved markup the tab keeps the asterisk, and closing it asks whether you want to save.
The Image button gathers everything that acts on the whole picture: rotate, mirror, resize by percentage, reduce to 1600 / 1200 / 800 px wide (a screenshot is born far too big for documentation), trim borders of a uniform colour, add a margin, drop shadow and burn the markup into the image — this last one turns the marks into pixels there and then, which is what lets you blur over a mark. Resizing carries the markup and the stroke width along.
To capture the screen without leaving LightNote: Capture screen... in the tray menu (or Ctrl+Alt+P) freezes the desktop, you drag to choose the area (Esc cancels) and the cut-out opens in a new tab, ready to mark up.
Limitations: a mark once drawn cannot be moved or edited — undo it with Ctrl+Z and draw it again; animated GIF and WebP open in the animation view, which has no markup; and an .svg is rasterised on reading, so saving asks for a PNG destination.
HTML pages (.html)
An .html file opened from the tree becomes a preview tab backed by a real layout engine: flexbox, floating blocks, positioning, media queries, gradients, CSS variables and CSS3 selectors. That is what makes a modern report — the kind an AI generates, with metric cards, a table and a chart — look like it does in a browser instead of collapsing into a wall of text.
Text is selectable: drag to select, double-click to take a word, Ctrl+A selects the whole page and Ctrl+C copies (the context menu offers Copy and Select all).
The top bar has the Outline (the page headings; click to jump) and Find (Ctrl+F — highlights every match, F3 and Shift+F3 move between them, Esc closes). Zoom has left the tab bar: it lives in a single place, the status bar, as in every view (see Workspace and windows).
Export PDF paginates the page into A4 with vector text — the PDF stays searchable and the text selectable. The tab also follows the file on disk: regenerate the report and it refreshes on its own without losing your reading position. And a page that does not pick its own colours follows the application theme; one that defines its own is shown as it was designed.
Links work: a link to another file in the same folder opens right there, #anchor scrolls to the section, and a web address opens in your browser.
What it does not do is JavaScript and networking — nothing is downloaded. When a page depends on that (a script, <canvas>, <iframe> or a remote resource), a bar appears with Open in browser. Tip for reports: ask the AI for HTML without JavaScript and without CDNs, with the chart as inline SVG — then it opens complete in here.
Even so, a few things respond to a click, without running any script: a <details> box opens and closes from its header (and the toolbar gains Expand all when the page has one), a set of tabs switches the visible panel, and clicking a table header sorts the rows — clicking the same column again reverses it, and a column of numbers sorts by value, not as text. When the tab→panel pairing is not unambiguous, nothing is changed: the page stays exactly as it came.
Two adjustments happen automatically, because the engine lacks them: display:grid and gap become the equivalent flexbox, and inline <svg> is drawn. box-shadow is ignored. To go back to the old viewer, clear HTML viewer with full layout under Settings → General → Features.
Printing
File → Print… (Ctrl+P) opens a paginated preview: the sheet appears as it will come out, with the margins, the page break and the numbering. The print button sits inside it, next to the zoom, the page navigation and the paper setup. The note, the code, the HTML page, the image and the open PDF all print; on the other screens the item stays greyed out saying why. The same button sits in each screen's own toolbar: in the note, next to the export one; and in code, in the PDF, in the image and in the HTML page, in their own toolbars.
What reaches the paper is what reading mode shows: transclusion resolved, figure numbering in place and the private comment (%%…%%) left out. With a dark content theme the sheet comes out on white paper — a black page would waste ink and clash with any document handed to someone. Margins are 20 mm at the sides and 15 mm top and bottom, and the footer carries Page X of Y. In the preview, the Margins button switches between the document margins and the minimum the printer can reach; for a PDF and for an image it starts at the minimum, because there the file already carries its own margin. Next to it, Theme changes the colours of the printed sheet: the default is automatic (it is what turns a dark theme into white paper), and the list offers the light themes from the catalogue and your own — someone reading in Dracula Dark can print in Dracula Light, the same colour language made for paper. Dark themes are left out because on paper they would paint the whole page. The theme already in use is marked (in use) in the list: choosing it does not change the sheet.
In code, the syntax comes out coloured on white paper, with the line numbers in the margin, and a long line wraps instead of being cut: on paper there is no horizontal scrolling to reach what runs past the margin. The image comes out with the markup you drew, and a small image is not enlarged — it comes out at its own size, centred on the sheet. A GIF prints the frame currently on screen.
Printing a PDF from LightNote rasterises the pages, and your highlights go along; for the best typographic quality, print the PDF from the system reader, where the text stays vector. Exporting to PDF (File → Export note) is a different thing and stays as it always was: if you want the page number or the document margins in the file too, tick the two boxes in Export with options… — they start off so the PDF of anyone already exporting does not change. In a very long document the preview is skipped, because it holds every page in memory at once; the app goes straight to the print dialog, which has no such limit.
Zip as a folder (.zip)
A .zip opens in its own tab: the member tree on the left (name,
size, date) and the selected member's content on the right — text/code, Markdown (rendered), image or PDF — opened in memory, without extracting
anything to disk. Text and Markdown can be edited: Ctrl+S rewrites
the member inside the .zip itself.
The same tab opens .7z, .rar, .tar (including .tar.gz, .tar.bz2 and .tar.xz), .cab and .iso — those are read-only: you can browse, view and extract members, but not edit. Only .zip is writable, because it is the one format we can safely rewrite (.rar is proprietary and not even free libraries compress it).
Images and PDFs are read-only; very large members (and .parquet)
only offer Extract to…. Creating, renaming or deleting members is not
supported.
Password protected members are read normally: when you open one, LightNote asks for the password (up to three tries) and, by ticking "Remember this file's password", does not ask again — within the same run by default, and across runs too if the box is ticked (protected by Windows, for you on this machine only; erase them all in Settings → Features). Note one difference of the format compared to PDF: in a .zip the encryption is per member and the index stays in cleartext, so the file listing shows in full even without the password — only the content is protected. A .zip with encrypted members is not reopened on startup.
Blocks (.lnb)
A Blocks bundle is a folder whose name ends in .lnb,
treated as a single item in the tree (double-click opens it). Each block is a
real file on disk; the order lives in a blocks.json at the bundle
root. It works like a notebook: stacked cells of code or text. A Jupyter notebook comes in this way: right-click an .ipynb in the tree and choose Import as Blocks (.lnb). Each cell becomes a real file — versionable and read by search — and the .ipynb stays where it was, because importing is not converting. The outputs stored in the notebook do not come along: running the cell here produces the real result, with its time and command.
Each cell has a name, a type button (sets the interpreter/lexer) and buttons to copy, insert, delete and run. Run up to here executes all code cells up to the current one in sequence; the output (stdout+stderr) appears in a panel right below the cell. Create one from the tree (New) or via File → New.
Ctrl+Enter runs the focused cell — the same gesture as the SQL editor.
Results are saved (like a lab notebook): when a run finishes it becomes a
.md file under saida/<cell>/ inside the bundle —
with the timestamp, exit code, duration, command and the output itself. Being
Markdown, it reads in any editor, versions in Git alongside the notebook, and is
picked up by AI Chat. Reopening the bundle
brings back the Last run strip above the panel: click it to see the result
without running again.
History: the History button next to that strip lists the previous
runs of that cell (timestamp and exit code) — handy to compare what the same cell
returned over time. We keep the 10 most recent per cell; to change that, edit
the historyLimit key in the bundle's blocks.json
(0 turns saving off). Very large output is cut (the file says
truncated: true). Renaming a cell or changing its type takes the
history along; deleting the cell sends its history to the Recycle Bin.
SQL cells against a real database: point the notebook at a
.lnc connection from the strip at the top
(Choose connection…) and cells of type sql start running on the
database instead of through an interpreter. A SELECT result becomes
a table in the output file (real Markdown, which any viewer renders
formatted); INSERT/UPDATE and friends report how many rows
changed, and a database error stops the script and records the statement that
failed. We fetch up to 100 rows per query (the file says when there were
more) — the result is a note, not a copy of the table.
The connection lives in blocks.json as a relative path, so the
notebook keeps working when you move or sync the folder. For a self-contained
notebook, keep the .lnc itself inside the bundle: it counts as
configuration, not as a cell. It is the same connection as the
Database tab — connecting in one place applies to the other, and the password
follows the Passphrase rules. With no connection set, an
sql cell still runs through the configured interpreter, as before.
Tasks (Kanban / Gantt)
A Tasks bundle (.lnt) opens a task board with Kanban
(status columns, drag the cards), Gantt (effort-based schedule) and
calendar views. Each task can have a title, a column (status), an effort
in hours and an associated .md note. Tasks are also reachable by
AI, via MCP and CLI (create, move, update,
read/write the note).
The task note is a note like any other. The embedded panel now shows the same screen as .md notes: Ctrl+E cycles text editor, reading and formatted editing, and the note theme, outline and properties all apply. It still saves by itself — including what you just typed in formatted mode, when you switch task or close the tab. Opening the note in its own tab also follows your view preference instead of forcing the text editor.
Per-task fields: besides status and effort, each task has a priority (colors the card border and sorts the Table), a due date (red chip when overdue), multiple tags, a subtask checklist (progress badge on the card) and recurrence (completing a recurring task spawns the next occurrence). Edit them from the context menu (Table/Kanban) and in the Properties panel.
Capture and lists: the tray's Quick task understands natural language (e.g. Pay bill tomorrow 5pm #home !high). The Templates button saves/applies task templates; Due-date lists filter Today/Next 7 days/Overdue; Saved views store filter+sorting; and the tray/Launcher show reminders for tasks due today or overdue.
Kanban board: you can group the columns by status, priority or tag, create swimlanes, set per-column WIP limits (the header turns red when exceeded) and sort the cards. Linear-style keyboard navigation: ←/→ move the focus, Ctrl+←/→ move the card, N creates, Space completes/reopens and Delete deletes. There is also the Calendar view (by due date).
Embedded note: selecting a task shows its .md note next to
the views (autosaved when you switch tasks); the Note button toggles the
editor and Open note in a tab opens it in its own tab. Archiving a
task hides it from all views; the Show archived toggle reveals the archived
ones (dimmed).
In Task Settings you can set Archive completed tasks after N days: when the board opens, tasks that have stayed in the final column longer than that are archived automatically (0 = off).
The note opens embedded by default (double-click the task) and saves itself as you type — Tasks never ask "save?" on close. The AI actions (Ctrl+K / Ctrl+I) work inside the note.
Tab toolbar. The actions that depend on the selected task (Delete, Dependencies, History (Git)) and Export CSV live in the ⋮ button. The Views button gathers the due-date lists, the saved views and show archived — all of which act on the Table. Ctrl+F focuses the quick filter, and the counter on the right shows how many tasks the filter left.
Custom table (.lnd)
A Custom table (.lnd, under File → New) is your
mini database: you define the columns at runtime — text, number, date,
fixed list with colors, path, tags and password — and fill
the rows like a spreadsheet, with sorting and filtering. A path field
groups the rows into a tree (e.g. Home/Office).
Password cells are encrypted individually with the Passphrase and revealed on demand. Like Tasks, the bundle persists as Git-friendly text (NDJSON) — it can be versioned and merged across machines.
In text columns, opening a cell shows a floating multi-line
editor: Enter inserts a line break and Ctrl+Enter confirms; the
grid shows the text on a single line (with …) and the full content in
the tooltip. To change a column's type, use the header menu: converting
text → password encrypts the values with the Passphrase; converting
password → text asks for confirmation and the PIN/Passphrase and writes the
content as plain text (irreversible). Other conversions keep the values.
Bases (saved queries over your notes)
A Base (.lnq, under File → New → New Base) is a
saved query over your notes: filter by type and by properties
and see the result as a table or a board. A Base stores no data at
all — the rows are your .md notes and the source of truth for each
cell is the note's frontmatter. Deleting a .lnq loses no note.
Editing a cell writes to the note. In the table, changing a property rewrites only that line of the file's frontmatter. In the board, dragging a card from one column to another writes the new value of the grouping property (for example moving from reading to read).
Each note declares its properties in the frontmatter (type,
status, author…). Use the note's Properties side
panel to edit them as typed fields (text, number, date, checkbox) instead of
raw YAML — see Markdown notes.
The .lnq file is NDJSON (one record per line), designed for
Git: two machines can edit the same Base in parallel — one adds a column, the
other tweaks a filter — and the merge keeps both changes without conflict.
Declared schema (optional). By default LightNote infers each type's
fields from what your notes already use — you don't have to declare anything. When you
want to pin the schema down, open Tools → Note types... (or the gear button on the
note's Properties side bar): declare each type's fields, their data
type (text, number, date, checkbox, option list) and a default template.
With a schema, an option list field becomes a drop-down of the allowed values,
declared fields show up in the Base's column and filter pickers even before any note
uses them, and the Apply type template button drops in the note's skeleton. The
schema lives in .lightnote/types.ndjson — mergeable NDJSON, versioned in Git
along with your notes; deleting it changes no note, it just goes back to inference.
Relative dates in the filter. In the value of a condition you can write terms like today, yesterday, tomorrow, 7 days ago and in 2 weeks (also 3 months ago, in 1 week). With them, due = today and due < today (overdue) still hold tomorrow — before, you could only type the day's date by hand, and the saved query aged out in 24 h. The value is always a point in time, and the range comes from composing it with the operator: modified > 7 days ago means "touched this week". A note with no readable date in that field matches no date comparison, not even the negative one. An ISO date typed by hand (2026-09-01) still works as text.
The index runs in the background. The Base and Tools → Query notes (SQL) scan your notes before showing the result — a stat on every file plus reading the ones that changed since last time. That now happens off the window: the Base opens right away saying Indexing the notes… in its bar and fills in when the scan ends; the Reindex button stays disabled meanwhile, because a second scan of the same folder would gain nothing.
Search in files and Pending items
Searching files and documents
Use Ctrl+Shift+F for the global search in the sidebar's Search tab, powered by ripgrep: it supports regex, case sensitivity, whole word and bulk replace. Within the current file, Ctrl+F finds and Ctrl+H replaces.
Search reaches documents too. Beyond .md notes, it
reads the text of PDF, spreadsheets (.xlsx/.ods),
Word documents (.docx), LibreOffice text (.odt),
presentations (.pptx) and books (.epub). The same goes for
AI Chat and for the semantic search. A hit inside a PDF opens the file on the
page of the excerpt. The extracted text lives in a cache outside the
workspace, refreshes itself when the file changes, and is deleted once the file is
gone. The first time costs: opening a workspace with many PDFs starts an extraction that takes minutes, and until it ends the documents are not in the search yet. The Search tab says so while it happens — preparing the documents (12 of 80) — and tells you when you can run the search again. From the second time on, only what changed is redone.
Also covered: .rtf, .xps/.oxps, LibreOffice presentations (.odp), video subtitles (.srt/.vtt), plain-text tables (.csv/.tsv), saved pages (.html/.mhtml), archived email (.eml), Jupyter notebooks (.ipynb), bibliographies (.bib/.ris) and plain-text files (.txt). Text markup languages have their own reader — reStructuredText (.rst), AsciiDoc (.adoc), Org (.org) and Typst (.typ): sections become headings, lists and tables become ours, formulas are drawn, and the preamble is left out — without that, #set page(...) and :stem: latexmath would become indexed chunks, and the section name would not travel with its text. A hit in a subtitle opens at the moment the line was spoken. A scanned PDF does not vanish in silence. A document with pages and no text (a photo of each page, without OCR) enters the index carrying a line that says so, and the Search tab tells you how many there are — without that sentence you would look for something that is in the book, not find it, and conclude that the search is broken. And you can make it readable: with Tesseract installed (LightNote offers to install it in one click), the PDF's ⋯ menu offers Recognize the text (OCR)…. It runs once, per document and may take several minutes — after that the text sits in the index like any other PDF's. The Search tab notice takes you to the first document in that state. The cache stores the text in the clear. It lives in your user folder, outside the workspace: anyone with access to it can read your documents' contents there, even if the original sits on an encrypted disk. An .lne file (the encrypted note) never enters the cache — it exists precisely so it is not readable on disk.
LaTeX goes through a reader of its own. A
.tex file is not read as raw text: the preamble is left out,
\section becomes a heading, \cite becomes
[@key] and the formula passes through whole — it is drawn by the same
engine that draws the mathematics in your notes. A hit opens the file on the
line it came from. The file's context menu — or the tab bar, with it open —
offers Import as note (.md): the note is created next to it, the
.tex stays where it is and importing twice does not overwrite. The other
direction is Export as LaTeX (.tex)..., on the note's bar.
Document preview and source code
Opening a document shows a text preview. A .docx,
.odt, .epub or .pptx opens read-only,
with the extracted text and the document's images — without Word styles,
image positioning, complex tables or tracked changes. The tab is still the document: its name, its folder and the session
point to it, not to the cache. An .xlsx spreadsheet still opens in the
table view, which shows far more.
Turning the document into a note. From File → Import document as note... (several at once), the tree's context menu or the Import as note (.md) button in the preview itself, a .docx, .odt, .epub, .rtf, .pptx, .html, .eml, PDF or LaTeX file becomes an editable note next to the file. Along come the text with headings, lists, links and tables, the footnotes, Word equations as LaTeX formulas and the images, saved in the Attachments folder next to the note. The document's title, author and date become properties, with source saying which file the note came from. The original stays where it is — importing is not converting — and importing again creates name 02.md instead of overwriting what you edited. It is not offered for Jupyter notebooks (they become Blocks), .csv (it opens as a table), the .bib/.ris bibliography (citations read it directly) or source code. The structure comes from the document's styles: a Word heading is recognized even when the style name is translated, character styles give bold, italics and code, quote and code paragraphs become our blocks, and the automatic table of contents becomes a [TOC] that the note keeps up to date; from .rtf come lists, tables and links, and from HTML — including what Word and Google Docs save — and from EPUB come headings, nested lists and tables.
See what the folder uses from another editor. In Tools → Check folder compatibility..., LightNote reads the notes in the open folder and sorts what it found into three groups: what it draws (wikilink, transclusion, callout, tag, highlight, formula, footnote, task, block marker), what stays in the file without being drawn (the plugin query dataview, tasks or query, the .canvas board, the .base database and block transclusion) and what can be converted to the spelling used here. Converting is your choice, never a side effect of saving: tick the constructs, look at the side-by-side preview and confirm — each changed file gets a point in File history before it is written, and anything open with unsaved changes is left out. There are two conversions today, and neither costs anything on the Obsidian side, which reads both spellings: an obsidian:// link to this folder becomes [[note]] — one pointing at another vault is not converted, because the destination would change — and the inline footnote ^[text] becomes [^n], with the definition at the end.
Bringing a whole Notion workspace across. In Notion, use Export → HTML (or Markdown & CSV) with Include subpages, put the downloaded .zip — or the folder — inside your workspace, create the destination folder and run lnote vault-import --path <export> --out <destination> (or the vault_import tool, from the AI assistant). There is no need to unzip, not even the whole-workspace export, which carries another .zip inside. Each page becomes a note: page properties become note properties, the coloured Notion callout becomes our box (in HTML the colour decides the type; Markdown keeps no colour, so the box arrives as a note), a to-do arrives with its checkbox ticked or not, an equation becomes a LaTeX formula, a toggle becomes a <details> box (and a toggle heading becomes a heading), the page's table of contents becomes [TOC], and links between pages are rewritten to the new notes — two pages with the same title live side by side, because the second becomes name 02.md and the links still point at the right one. Databases are copied as .csv into Anexos, and a #topic written in Notion stays text — it was no tag there, and it does not become one here. Nothing is overwritten, and a report note is written next to them saying how many notes and attachments came in and listing the links that found no target — those stay exactly as they were written.
The gesture is in the menu. File → Import from another app... opens the assistant: choose the folder or the .zip you exported (an Evernote .enex works too) and the source app is recognised by the shape of the file names — if it is not, pick it from the list beside it. The whole folder is read, subpages included. The destination comes filled in with a new folder inside the workspace, named after the app, so the archive does not mix with your own notes. Reading and writing happen off the window, and at the end the screen says how many notes and attachments came in and how many links were rewritten.
Five apps. From Notion, the folder or the .zip exported as HTML or as Markdown; from Evernote, the .enex; from Joplin, the .jex (or the MD + Front Matter folder); from Logseq, the graph folder — the one with logseq/config.edn in it; and from Roam Research, the export .json. In all of them notebooks and namespaces become folders, journals go to the daily notes folder named yyyy-MM-dd, a task becomes - [ ], a highlight becomes ==like this==, and a block reference becomes that block's text in quotes plus a link to the page it lives on — no other app's syntax enters your vault. What has no equivalent here, such as a Logseq query or a Roam table, stays as inline code, and the report says how many times.
Source code can join the search by meaning too. Under Workspace → Settings for this folder there is Include source code in the search by meaning: code files get indexed alongside the notes, one chunk per function or class — that is what makes questions like “where do I handle the timeout?” find the whole function instead of a piece cut in the middle of an if. It honors .gitignore. It ships off, and per folder: notes change slowly, code changes all day, and a working repository produces tens of thousands of chunks — each one a call billed by your embeddings provider.
Highlight, marks and Pending
Highlights and marks are different things. The quick find (Ctrl+F) only highlights the matches in amber: it is temporary and disappears when you close the bar or clear the field. Mark all in Edit → Advanced find…, on the other hand, is your decision — it paints the matches red and adds the bookmark (the blue dot in the margin) on the matching lines, which stay until you use Clear marks. The two are independent: closing the quick find does not erase what you marked, and clearing the marks does not erase the find highlight. Both show up in the minimap strip, each in its own colour. Clear marks removes only the dots that Mark all created: a bookmark you placed by hand (Ctrl+F2) on a line that matched the search stays where it was.
The sidebar's Pending items section gathers in one place the
TODO/FIXME markers from code and the tasks
(- [ ]) from the workspace's Markdown notes — click to jump
straight to the line.
Versioning (easy Git)
Clone a repository
To work on a repository that already exists, use File → Clone Git repository... — the item is also on the start screen and in the versioning panel of a folder that has no repository yet. Paste the HTTPS or SSH address the repository page shows; the URL of the page itself works too, and so does a whole git clone ... command copied as it is. Choose the base folder and the folder name: the wizard shows where it will be created and warns when something is already there. Advanced options holds the branch, the shallow clone (only the last commit) and the submodules.
When the server asks for a login, LightNote asks in a window: username and token, the SSH key passphrase, or the confirmation of the key of a server this computer has never seen — in that case the window shows the fingerprint and the link to the list the service publishes, and the default is do not trust. The answer goes straight to Git and LightNote does not store it; what stores it is Git's credential manager, when it is installed (Git for Windows ships the Git Credential Manager). Trusting the key writes it to ~/.ssh/known_hosts, as ssh itself would.
If the clone fails, the screen says what happened and offers the way out: try over HTTPS when the SSH key was refused, use the Windows certificates when the company proxy inspects HTTPS, download only the last commit when the connection drops midway, or use long paths when Windows will not create the file. Technical details carries Git's message, and what is not recognized can go to the AI. When it finishes, the wizard opens the cloned folder in this window or in a new one.
Version the open folder
Versioning is opt-in per workspace. Enable it in Tools → Workspace Settings: LightNote creates the Git repository (if one does not exist yet) and shows the versioning sidebar (Ctrl+Shift+G).
In automatic mode, LightNote saves versions (commits) by itself at the moments chosen in the General Settings (on save, on tab close or on window close). In manual mode, you write the message and save the version in the panel. The status bar indicator shows the state (no changes, X changed…) and, when clicked, opens the workspace settings. You can view each file's diff and restore (discard) unsaved changes.
Automation has 3 levels per folder (in Workspace Settings): Manual (nothing automatic), Auto-commit (saves versions by itself, but does not sync) and Fully automatic (commits and syncs — push after commit + periodic pull; requires prompt-less Git credentials). The panel shows a status line with ↑ to send / ↓ to receive relative to the remote, and the main button changes from commit to Sync when there are versions to send — making it clear that, after saving, you still need to sync.
The Git panel and the tree's Git menu offer Add (git add) and Restore (git restore) per file, plus a single See what changed, which opens the comparison screen.
The comparison screen shows both versions side by side, aligned: identical passages always face each other and each side shows the line number of its own file. A changed line appears in amber, with the part that changed highlighted inside it. The Unified mode button switches to the patch format, Swap sides changes the comparison base, and F8 / Shift+F8 jump from change to change.
History and the change stripe
The History button on the code editor and note toolbars opens the list of versions of the open file (the same sidebar section). It brings together the commits and the local saves LightNote records on every Ctrl+S, so it also works in a folder that is not a repository. Each row shows the subject, the author, when it happened and how many lines came and went; the dot tells apart a commit of yours, a save by LightNote itself and a commit from an AI session. When there are uncommitted changes, they are the first row. Clicking a version shows what changed in it; opening the whole version, comparing with the current one and comparing two selected versions are on the right-click menu.
With versioning active, a coloured strip in the margin marks the lines changed since the last commit — in the code editor and in the note, and it follows what you type: it disappears when you undo back to the original, without waiting for a save. To turn it off use View → Change strip; switched off it is not merely hidden — nothing is computed at all. Clicking the strip shows how the passage used to be, with Revert this chunk (Ctrl+Z undoes it), Copy original and Open in diff, which opens the full comparison already positioned on that line. One caveat about the local history: it is kept by path, so renaming the file loses its local saves — the Git commits, no.
Snapshots and backup
In the ⋯ menu of the versioning panel (or under Tools):
- Create snapshot: marks the current state with a date/time label so you can come back to it later.
- Restore snapshot: pick a snapshot and what to do — bring the files back keeping the history (recommended), rewind the history to that point, or open it as a separate copy.
- Export copy (.zip): compresses the whole workspace into a self-contained file (with the project marker embedded) to send or store elsewhere.
- Move Workspace Folder…: moves the root on disk and adjusts the session and registry paths.
Review changes (checkpoints)
Tools → Review changes… shows, in a single tab, the aggregated diff of everything that changed in the workspace since a base: the list of added/modified/deleted files on the left and the selected file's diff on the right. It was designed to review what an AI CLI session changed before accepting the work.
The base can be the last version (HEAD) or a checkpoint: create one before starting a task (button on the tab itself) and compare against it later. Checkpoints create no commits and never touch your history. Requires versioning enabled for the folder.
Batch comments. When reviewing an AI session, the Comment button (also in the file list context menu) notes a comment about the selected file — anchored to the snippet you pick. Comments pile up in a list and only reach the CLI terminal when you click Send to session, all in a single message. That is deliberate: sending them one at a time makes the agent fix one problem and break another, because each round cannot see the other remarks. After it revises, the comments stay in the list so you can check whether they were addressed; tick the resolved ones and whatever is left goes into the next send. If the agent rewrites the commented region, the comment is dimmed instead of disappearing. The send is confirmed in the status bar, and a hibernated session is resumed automatically to receive the batch.
Compare files (diff)
Tools → Compare Two Files… opens both side by side (two editors) and marks the differences line by line. The comparison is read-only.
The ◀ / ▶ buttons (or F8 / Shift+F8) jump to the previous/next change. From the Git panel you can also compare a file side by side with the saved version (HEAD vs. disk).
Run code (F5)
Tools → Run File (F5) saves the current file and runs it in the
terminal, according to the interpreter registered for the extension. The
defaults cover .py, .sh, .bat,
.cmd and .sql; you can edit/add interpreters in
Settings → Execution.
The command is a template with {file} (file),
{folder} (folder) and {name} (name) — for example, for
Python: python {file}. You can also send just the
selection/current line to the terminal with Ctrl+Shift+Enter. In
Blocks, each cell runs through the same mechanism.
The Run button has a dropdown to choose and remember the target terminal when more than one terminal is open.
Clickable errors. In the output panel (F6), references to file:line become links: Ctrl+click or double-click opens the file at that exact spot. It works with Python tracebacks, Node stacks, compiler errors (gcc/clang/MSVC) and linter output. Only paths that actually exist on disk become links — the rest stays plain text.
Stepping through errors. In the output panel, F8 jumps to the next error and Shift+F8 to the previous one (there are buttons on the panel’s bar as well). The jump wraps around: it scrolls the output to the reference, highlights it and opens the file at the exact spot.
Terminal and AI CLIs
Per-command status dot. A dot appears next to each command you run: blue if it succeeded, red if it failed (the tooltip shows the time, duration and exit code). LightNote enables this automatically in PowerShell and Git Bash, without changing your setup — toggle it in Settings → Terminal → Shell integration. Other shells (cmd, WSL) or custom commands don't show the dot.
Open an integrated terminal (full VT emulator, via ConPTY) with Ctrl+'
(on the US keyboard layout, also Ctrl+`).
It becomes a tab and can be moved between the window areas. The available shells
and the AI CLIs detected on the PATH (e.g. claude) are
configurable in Settings → Terminal and Settings → AI Assistants.
In the New terminal menu, choosing an AI CLI opens that CLI as the
terminal — the TUI/colors show up normally, and quitting it closes the tab.
Schedule a send. In the terminal context menu (right-click), Schedule send… lets you send an Enter (or some text) later — handy to resume an AI CLI when the usage limit resets, without watching for it. Pick a trigger: at a time, after some minutes, every interval (recurring), or when the terminal goes idle. The computer is kept awake until it fires. The schedule lasts while the terminal tab stays open.
You can have several schedules at once. When there is any, the menu item shows Scheduled sends (N)… and opens a manager: a table with the terminal, what will be sent, when, and a live countdown to the next fire, with New, Edit and Remove buttons. While there are schedules, a clock indicator with the count appears in the status bar (click it to open the manager) and a small clock marks the terminal tab that is armed.
AI turn-completion notice. When an AI CLI terminal falls silent — a sign the agent has finished its turn — LightNote lets you know: a toast appears (click it to focus that terminal) and the tab blinks a few times, then keeps a highlight until you open it. If the window is in the background, its taskbar button flashes too. The notice applies only to AI CLI terminals, and only when the tab is not focused. Turn it on/off and tune the silence threshold in Settings → Terminal → AI turn-completion notice.
Terminals come back with the window. When you close and reopen the workspace, plain shell terminals (Command Prompt, PowerShell, Bash) are reopened — and in the folder you were in, not the one the terminal started in. The screen contents do not come back, but the command history belongs to the shell itself and is still there: the ↑ key works as usual. AI assistant sessions are left out and keep being offered separately, because a new terminal is not the same conversation. Environment variables and environments you activated by hand in that session (a venv, for instance) do not come back either: the terminal reopens in the right folder, but it is a fresh shell.
AI assistant on the selection (Ctrl+K / Ctrl+I)
Asking and editing with AI
Default AI. At the top of Settings → AI Assistants, the Default AI chooses the assistant used by Ctrl+K/Ctrl+I, by the AI Chat chat (which you can change per session) and by the automatic tasks (rewrite the question, summarize, audio summary, generate context). It lists both the CLIs and the API providers. Audio transcription and embeddings have their own provider, and LightNote suggests a model based on the chosen provider.
Press Ctrl+K (Ask AI) or Ctrl+I (Edit with AI) in the editor — with or without a selection — to open a floating, inline-chat style popup: the prompt field comes pre-filled with the selection below a blank line; type the instruction above it and send with Ctrl+Enter. In the popup you pick the AI (the default one comes pre-selected) and the result mode: replace the selection through a diff (Original × Suggestion, with Accept / Copy / Reject) or just display the answer as text.
LightNote runs the AI CLI in "one-shot" mode (without opening a terminal). The CLIs and the default AI live in Settings → AI Assistants.
Connecting a model
Models via API. Besides local CLIs, you can register LLM models via an OpenAI-compatible API (OpenAI, Groq, DeepSeek, OpenRouter, Gemini, Anthropic, local instances like Ollama/LM Studio…) under Settings → AI Assistants. Pick a provider from the catalog (base URL ready), paste the key (stored encoded only on this machine), use Fetch models… and Test. The registered models appear in the same Ctrl+K selector, alongside the CLIs.
Connecting in one step. The normal path is not filling in the table: under Settings → AI Assistants, click Connect an AI…, pick the provider (the list flags the ones that have a free plan and the ones that run on your computer, no key), follow the three steps, open the API keys page with the button and paste the key. LightNote fills in the address and the model on its own and tests the connection before saving — a wrong key shows up right there, not in the middle of a conversation. The list above shows what is already connected and, for whatever is incomplete, what is missing (“key not pasted yet”, “model not chosen yet”); a double click reopens the assistant on that provider.
Fine tuning. Address, model, MCP permission, CLI commands, audio transcription and embeddings are all still available under Advanced, at the end of the page — and inside the assistant itself, under Advanced options, you can change the base URL and the model before connecting. Nothing was removed: it just moved out of the way of someone starting out. The embeddings section also has an optional Dimensions field: some models accept returning a smaller vector (512 instead of 1536), which halves the cache with little loss. Leave it at (model default) if you are unsure — not every provider accepts the parameter. Changing the value invalidates the cache: vectors of different dimensions cannot be compared, so it is discarded and rebuilt on the next search, which costs new calls.
Not every failure is the same. LightNote tells the classes apart because they call for opposite gestures. Provider overload and rate limits pass on their own: the app repeats the call by itself, honouring the wait the provider asks for, and you only see the error if that does not work either. Balance or spending limit never passes with repetition — the message says so, to stop you from trying. A conversation that grew too long calls for a new session, not another model. And a model failure — retired, outside your account, outside your plan, or it took the call and never answered — is the only one that changing the model fixes. When the requested wait is too long to sit through, the message tells you how many seconds it asked for, instead of leaving the window frozen.
Changing the model by itself. Tick Switch model automatically when the current one fails and LightNote tries, in the order shown right there, the models recommended for that provider. It comes unticked on purpose: each attempt is a call billed to your account. The alternative never costs more than the model you chose — the list is published from the most expensive to the cheapest and the app only goes down it; a custom model, which is not on the list, falls straight to the cheapest one. Only a definitive failure is written to the provider; when it was the network that failed, the switch holds for that call alone and your choice still stands. The switch is never silent: a notification says which model answered and whether the change was saved.
And the notice that arrives before the failure. The automatic switch only acts after the call has failed — but the model catalog, which LightNote checks on its own, usually knows about the retirement before that. When the model that LightNote itself set up for a provider drops out of the catalog, a notice says so, and under Settings → AI Assistants a button appears to move to the replacement — which, by the same rule, is never more expensive. The notice applies only to the model the app chose and you never touched: a model you typed is your choice, and LightNote does not meddle with it.
When nothing answers. LightNote says what happened and offers to change the model, use another assistant or turn that provider off until you sort it out. A provider turned off (the Active column of the table, under Advanced) disappears from the lists without losing the key or the rest of the settings. In the list of assistants each one says whether it is local or in the cloud — picking one in the cloud makes the text you send leave your machine.
No key: a local LLM
No AI yet? If you press Ctrl+K with no assistant connected, LightNote explains it and offers to connect one right there — and as soon as you do, the action you asked for goes ahead, with no need to press the shortcut again.
Local LLM (no API key). Local providers — Ollama, LM Studio, llama.cpp — need no API key: pick one under Add (the picker shows whether the server is running) and use Fetch models… to choose among the models you have pulled. If Ollama isn't installed, LightNote offers to install it for you. It comes pre-registered on the first run — you only pick the model. Because a local model can take much longer to answer (especially on the first generation, while the model loads), LightNote waits far longer for it than for a cloud service. None of your text leaves the machine.
Accepting, prompts and where the actions live
Accept hunk by hunk. When the result comes as a diff, you don't have to take all of it: each changed block has a checkbox to include it or not, and the final text is rebuilt from just the blocks you keep. The prompt also carries automatic context from the file (path, language and the lines around the selection), so the AI answers more precisely without you pasting anything.
Prompt library. AI → Prompt library… keeps reusable prompts as .md files in a Prompts/ folder of your workspace — an open format, versionable in Git and part of your second brain. The picker offers search, a preview and a button to create a new prompt. When you pick one, the fields {selection}, {file}, {folder}, {name} and {language} are filled with the current editor context (your own variables are preserved), and the text is injected into the Ctrl+K field or sent to the active AI terminal, without submitting.
Not only in the code editor. The AI actions (Ctrl+K / Ctrl+I and the context menu) also work in the Markdown editor, in the embedded task note and in the database SQL query editor — in each one the popup opens over the cursor and applies the result in place.
All AI actions live in the AI menu (in the ☰ button and in the wand button of the activity bar): Ask AI (Ctrl+K), Edit with AI (Ctrl+I), AI sessions, AI Chat, Prompt library, Generate the project context file, Enable AI in this folder and Configure AI assistants.
The window stays open while you write. It does not close when you click in the editor — you can re-read the code or select another passage without losing the instruction you already typed. What closes it: Esc, the window's own ✕ and the result actions (Accept/Reject). When you switch tabs it tucks itself away keeping what was written: go back to the same file, press Ctrl+K and the instruction comes back where you left it.
AI sessions
Sessions and the isolated copy
AI → AI Sessions… opens a cockpit that lists, one card per session, every AI CLI terminal open in any LightNote window — with a coloured status dot, the CLI name, the window and badges for whatever needs attention (scheduled sends, isolated copy). Double-click focuses the terminal; the card's ⋯ menu (or right-click) offers Review that session's changes (opens the review screen with the base set to the checkpoint created when the session started — see Review changes) and Schedule a send. It's the way to keep an eye on several "vibe coding" sessions at once without getting lost between windows.
When you open an AI CLI as a terminal inside a Git repository, LightNote automatically saves a checkpoint (labelled "Session …"), so you can later see and revert exactly what that session changed. The feature can be turned off in Settings → General → Features.
Isolated copy (worktree): in Git folders, LightNote can run the AI assistant in an isolated copy of the folder (its own branch), without touching the files you edit by hand. The first time it asks; after that it is automatic (turn it on/off per folder in Workspace Settings → Integrations). An isolated copy badge marks the session (branch and path are in the tooltip), and the Merge… item (brings the changes into your folder — if you have pending changes it asks first) and Discard… (throws away the copy and the branch) handle the end of the cycle.
Idle, context and hibernate
Idle-session notice. When an AI CLI goes idle (it finished or is waiting for you), LightNote shows a notification; clicking it opens the review of that session's changes. So you can start the task and step away. It can be turned off in Settings → Terminal.
Project context file. When you open an AI CLI in a folder without a context file (CLAUDE.md or AGENTS.md), LightNote offers to generate one — and you can do it anytime from Tools → Generate project context file…. A good context file describes the project's structure and conventions and helps the AI make fewer mistakes, without you re-explaining everything each session. If an AI provider is configured, it generates the content; otherwise you get a skeleton to fill in.
Hibernating idle sessions. An idle AI CLI keeps holding memory (the conversation and the model client). Under Settings → Terminal you can set a silence period after which LightNote ends the process and resumes it by itself when you return to that tab — the terminal history stays on screen. It ships on, at 30 minutes — three idle Claude Code sessions held over 1 GB when measured — and only applies to sessions in an isolated copy whose CLIs know how to resume the folder's conversation (today Claude Code and Antigravity), because otherwise resuming would bring back another session's conversation. A session with a scheduled send never hibernates. And what comes back is the conversation, not the tool's screen: text you typed but did not send is lost.
Activity and search by meaning
Activity tab. The table shows what is running now; the Activity tab keeps the history: every time an agent finished its turn, started in an isolated copy or hibernated, with the date and a snippet of the last reply. Unread entries appear in bold and the count also shows up in the tray menu — so whoever stepped away from the computer sees what they missed, since notifications are fleeting. Opening the tab marks everything as read; a double click takes you back to the session. The end of a session is recorded too — including when the CLI exits on its own — so a session that died while you were away leaves a trace instead of simply vanishing. If the event's session is no longer open, double-clicking says so instead of doing nothing.
Search by meaning. When the search finds no literal match, a Search by meaning option appears next to the result: instead of matching words, LightNote looks for the notes that talk about the same thing — handy when you remember the idea but not the wording you used. There is also a ~ toggle next to the others to go straight there. In this mode, regex, whole word, case, the file filter and Replace disappear: none of them applies to a similarity search. The feature needs semantic boost (embeddings) in Settings → General → Features; without it, the button takes you to the screen that turns it on. The first time in each folder, LightNote tells you how many chunks it will index and asks for confirmation — that indexing is billed by your provider and happens only once; after that, each search costs only the query.
AI Chat
How it works
AI → AI Chat… opens a chat that answers using your own notes as context. Instead of sending everything to the cloud, LightNote retrieves the most relevant snippets from your vault locally (via ripgrep, no embeddings and no external service), builds the question with those snippets and sends it to an API AI provider you have registered. The answer comes with the source notes as clickable citations — click to open the note. Great for "talking to your second brain" and finding what you already wrote down. The conversation history stays in memory only (it is not saved); the feature can be turned off in Settings → General → Features.
The window. The selectors sit in a single bar at the top: the AI, the notes folder and — when a text editor is active — the context; on the right are the two permissions (Tools and Allow changes) and the + button, which starts a new conversation. Before the first question the screen states what the window will answer about and offers one-click shortcuts such as Summarize this folder. In the question box, Enter sends and Shift+Enter breaks the line; while the answer is coming, the send button turns into Stop.
Tools and permissions
Letting the AI use tools. The Allow changes box changes how this works: instead of answering only from the excerpts the keyword search retrieved, the model can look things up itself — read a file, search notes, list tasks — and only then answer. When you turn it on, LightNote tests right away whether the chosen model can call tools: many providers accept the request and simply ignore the tools, which without that check would produce an invented answer that looks researched. The verdict is remembered for seven days per provider+model pair. Requires an API provider (a local CLI has no way to receive tools). The answer ends with the list of what was actually used, so you can judge it instead of trusting it. If the verdict is negative — the provider may simply have been down at that moment — a Check again button appears next to the message and redoes the test, ignoring what was cached.
Letting the AI change your things. The second box, Allow changes, is a separate step and starts off. With it, the AI can also create notes and tasks, change properties and write to today's note — but nothing happens without your confirmation: the change appears in the conversation in plain words ("create the task Buy bread"), with Allow and Deny. Denying does not end the conversation; the model is told and carries on, explaining or proposing something else. Reading never asks — only changing does. Overwriting arbitrary files and reaching the network are deliberately left out: while the AI only reads, hostile text arriving in a note synced from elsewhere has no way to become a change on your disk. When the change is an entry in the daily note, the request also says which folder it will land in — it is the only write whose target file is not part of what the AI asked for.
What it answers about
Notes or the open file. The Context: combo at the top of the window chooses what the conversation is about: Vault notes (the default, described below) or Current editor — which answers about the file open in the editor instead of the vault, using the selection and the surrounding lines (or the whole file, with the Whole file checkbox). So the same chat serves to talk about your notes and about the code you are editing, over several turns. The Current editor scope appears only when a text editor is active. And in the quick assistant (Ctrl+K), the result has a Continue in chat → button that reopens this window already in the Current editor scope, seeded with that round’s question and answer — to dig deeper without starting over.
Which notes? The window is a single one and answers about one folder at a time — the Notes from: combo, next to the AI selector in the top bar, shows and picks which. It opens already pointed at the folder of the window you opened the chat from, and lists the folders open right now, followed by the recent ones; Choose folder… points to any other. Switching folders applies to the next questions — including asking one project's notes while you work in another. Once picked by hand, that folder stays until you change it again (reopening the window does not pull the scope back). While a question is in progress — including while it waits for your confirmation — the AI, context and folder selectors are locked: the answer on its way belongs to the model and the folder you had when you asked.
How to ask. Retrieval is by subject, not by instruction: LightNote takes the words from your question and looks for notes that contain them. Name a topic that appears in the notes ("what did I note about Postgres?") instead of a generic request ("summarize this") — the latter has no content word to search for, so nothing is retrieved and the chat warns that the answer did not use your notes. Only .md/.markdown notes are read; in a folder without any, the chat says so and does not spend an AI call.
Better search, summary and rewrite. Retrieval uses a local index with BM25 ranking that ignores accents ("configuração" finds "configuracao") and also works in languages without spaces between words (Japanese, Chinese, Korean) — ripgrep is the fallback while the index is still being built. The Summarize this folder button — and Summarize with AI… in the context menu of any folder in the explorer — reads the notes in batches and returns a document. And in Settings → General → Features, the Rewrite the question with AI option expands your question into keywords before searching (it costs one API call per question).
Key and conversations
Just one key. On first run, LightNote already registers OpenAI, Google Gemini and Anthropic (Claude) under Settings → AI Assistants — you only need to paste your API key into the provider you use. If no provider has a key, the window shows a Configure now button that opens that screen directly.
Conversations are kept. The clock button at the top opens the list of previous conversations for that folder: click one to go back to it. New conversation archives the current one instead of deleting it, and right-clicking an entry deletes it for good (with confirmation). Conversations are stored per folder — switching the notes folder switches the list.
What to do with the answer
What to do with an answer. Under each answer there is Copy (puts the Markdown text on the clipboard, formatting intact) and Capture to note (sends the answer to today's note, along with links to the cited notes). The Conversation actions menu holds Copy conversation, Save conversation as note… (writes a .md in the queried folder), Regenerate last answer and Edit last question.
Attaching a file. When the search does not find what you had in mind, use the + button to attach a file: it always goes into the question, outside the search ranking. Notes, code, text and PDF all work (PDF text is extracted); a binary file is refused right away instead of becoming noise in the context. The attachment shows up as a pill (click it to detach) and is dropped when you start a new conversation. With providers that support it, the answer also appears gradually, as the model writes.
Assistant memory. In the Conversation actions menu (the ☰ button at the top), Assistant memory… opens — creating it the first time — a Memory.md note at the root of the selected folder. Whatever it holds goes into every question asked about that folder, ahead of the excerpts found: your preferences, the decisions you have already made, what you ruled out and why. It is an ordinary .md — edit it whenever you like, version it with Git, delete it to turn memory off. With write tools enabled, the assistant can also propose storing a fact there, and like every write it waits for your approval.
Summarizing a folder. It works for the whole workspace or for any subfolder: right-click it in the explorer and choose Summarize with AI…. Before spending anything, LightNote tells you how many notes will be read and how many AI calls that will make — each one billed by your provider — and lets you pick the shape: Overview, flowing text, or Consolidate knowledge, with fixed sections (decisions, open items, ideas, contradictions and open questions; an empty section is omitted rather than filled with invention). If the folder holds more notes than the cost cap allows, the answer says how many were left out. At the end, Save as note writes the summary inside the folder it summarized, with the date and the note count in the header, and never overwrites an earlier one.
Test HTTP APIs (.lnh)
Tools → New API Test (.lnh)… opens an HTTP client saved to a
.lnh file. One file represents an endpoint (method, URL, headers
and body) and keeps several tests in the list on the left — each test
with its values for the {name} variables used in the URL, headers
and body, plus the result of the last run (status, time, date, response headers
and body). It also shows the equivalent curl command. The same
one-off operation is available via CLI (http)
and MCP (http_request).
Ctrl+Enter sends the request.
Importing and exporting OpenAPI. The arrows button at the top of the
test list opens Import OpenAPI… and Export OpenAPI…. The import reads a
specification in YAML or JSON across the three generations in use —
Swagger 2.0, OpenAPI 3.0 and 3.1 — and builds the test on its own:
the path {parameters} already use the same syntax as the
{name} variables of the .lnh, the declared examples become the
test values, the security scheme becomes the Authorization header, and each
declared server becomes a test of its own (staging and production side by side). Since a
.lnh holds one endpoint, a specification with several operations asks
which one to import — or writes all of them at once, one .lnh file
per operation.
The export goes the other way and produces an OpenAPI 3.0.3 specification from the
file: servers, parameters and body come from the template, and the example responses come
from the recorded runs. It is a skeleton, not a full contract — the
.lnh describes calls, so types, descriptions and schemas are not
reconstructed. Your tests travel in the x-lightnote-tests field, which is why
they come back intact when you re-import the file.
Importing a curl command. In the same button, Import curl
command… opens a paste box — that is where the command comes from, not from disk,
and the field is pre-filled when there is a curl on the clipboard. It
understands the three dialects the same command travels in: Copy as cURL from
Chrome/Firefox (single quotes), Copy as cURL (cmd) on Windows (with
^) and the documentation example broken with \. The method
comes from -X — or is inferred: POST when there is a body, GET when there
is not.
The import is literal: no value turns into a {name} variable on
its own, because guessing which token is a secret would get it wrong. A few cases warn
instead of lying — a body coming from a file (-d @file) cannot be read, and
a multipart upload (-F) is not faithfully reproduced, so the fields go into
the body as text for you to adjust.
Databases (.lnc)
The connection
A connection is a .lnc file (LightNote Connection) inside the
workspace itself — versionable in Git and portable between machines. Create one
via New → New connection (or open an existing .lnc): this
opens the Database view, with the connection status bar (Connect /
Disconnect / Reconnect / Edit), the Schema tree (schemas → tables →
columns, loaded on demand) and internal .sql tabs. The opened
.sql files and the recent ones are stored inside the
.lnc, so the view reopens in its previous state. If nothing was
open, it starts with an empty (untitled) query where you can type SQL
right away; on save (Ctrl+S) LightNote asks only for a name and
writes the file inside the project folder (no "save anywhere" dialog).
The + Tab button opens a new empty query, lets you open a file
(the picker opens at the project folder) or pick a recent / any
.sql from the project folder.
A .sql opened straight from the tree is code only (SQL
highlighting, no connection).
Drivers: SQLite and DuckDB (file) native; PostgreSQL, MySQL/MariaDB,
SQL Server and generic via ODBC; native Oracle (no ODBC).
SQL Server uses Microsoft's msodbcsql driver (install it on the machine)
and offers Windows Authentication or user/password, plus the channel
encryption options (Encrypt / trust the certificate). For Oracle, set the
Oracle Instant Client folder in General Settings → Database — it
is loaded at runtime, with nothing to install. The Oracle connection has four
modes: Service Name (host/port/service), SID (host/port/SID),
TNS Name (alias from the tnsnames.ora in the client folder)
and Full TNS descriptor (pasted into a text field).
Password: check Store password to encrypt it inside the
.lnc itself (portable crypto, opens on another machine);
unchecked, the password is not saved and is asked on every connection.
Encryption uses a per-workspace Passphrase, set in Help → Configure
Passphrase; keep it safe — without it the password cannot be opened anywhere
else. The Passphrase is cached only on the local machine (it never goes to Git).
Check Connect on open to have the connection open automatically when you
open the .lnc. Auto-connect is silent: if the password must be
typed (ask mode, or encrypted without the Passphrase cached on the machine), the
file opens disconnected, without interrupting.
Running and reading the result
Run: Ctrl+Enter runs the statement under the cursor and Alt+X runs the whole script; results appear paginated, each in a Result tab with an action bar at the bottom: Fetch next block, Freeze the result, Total count, change the row Limit, Refresh (re-runs), View/Copy SQL, Export... and Generate SQL from the selected row.
Freeze the result: reads the whole result from the database in a single pass and keeps it in a local table (on disk, if it does not fit in memory). From then on the grid scrolls without querying the database, the row count becomes exact (no need for Total count), clicking a header sorts (clicking again reverses it; a third click returns to the order the database delivered), and exporting also reads from the local copy. Sorting by the header works up to 100,000 rows; above that it is declined, with the reason in the header tooltip, because every page would have to re-sort the whole copy and walking the grid would take minutes again. A result that already arrived whole in the first page sorts without freezing: the rows are already in memory. What cannot be sorted is the first part of a result still being paged — the header would be claiming an order that only holds for what is on screen. The chart and the pivot table start covering the whole result — including on databases where the chart did not exist. If freezing stops early (you clicked Stop or the cap was reached), the rows stay local but the chart and the pivot table remain on the server: summing over part of the result would give a wrong number — and sorting the grid sorts only the rows fetched, not the whole result. Refresh unfreezes and runs the query again. Whether or not you freeze, the pages that already went through the grid are kept locally: scrolling back to one of them does not query the database again. Only one freeze runs at a time: with two results open, clicking Freeze the result on the other one is refused with the reason, instead of interrupting the one in progress — to stop that one, use Stop in its own tab.
Result grid: a NULL is shown in faded italics, distinct from an empty
string, and numbers are right-aligned; when you select several cells, the footer shows
the selection count and, when they are numeric, their sum and average. The
Value panel button in the footer bar (or Show value in panel from the
context menu) opens a side panel with the full value of the selected cell,
uncut, with a Format button that pretty-prints JSON/XML for display only. In a
cell's context menu, Filter by this value / Exclude this value re-run the
query with a WHERE on the cell, and Go to referenced record follows
the column's foreign key and queries the parent table by the cell's value.
Chart and pivot table: where the maths happens. The grid's footer has a selector between Local data and Whole table (on the server), and the button shows which one is in force. When the result fitted entirely in the first page, the default is local: LightNote aggregates over the result already on screen, without going back to the database on every change of axis, aggregate or bucket — and, because the local engine is DuckDB, the chart also becomes available on Oracle, SQL Server, PostgreSQL and MySQL, where its SQL does not run on the server. When the result came back truncated, the local option is unavailable with the reason: aggregating over a sample would give a wrong number, and warning about the cut would protect nobody, because what you read in a chart is the height of the bar. The server option aggregates over the entire query, with one query per adjustment. Numeric columns that the database delivers as text — the case of Oracle's NUMBER — are recognised as numbers; identifiers with a leading zero, such as 01310, stay text.
Execution plan: the Execution plan toolbar button shows the
EXPLAIN of the statement under the cursor (SQLite, DuckDB, PostgreSQL and
MySQL); on databases that do not expose the plan in a single statement (SQL Server,
Oracle) the button is disabled, with the reason in its tooltip.
The schema
Object properties: double-click a table in the schema tree
(or press F4, or choose Properties from the context menu) to open a tab
with the object's structure, in four sub-tabs: Columns (#, name, type,
nullability, default, and a key icon on primary-key columns), Keys (primary,
foreign, unique and check constraints; double-clicking a foreign key opens the
referenced table), Indexes and DDL — the object's CREATE TABLE,
ready to copy, save as .sql or open in an editable tab. When the
database does not provide ready-made DDL (PostgreSQL and SQL Server have no such
command), LightNote reconstructs it from the metadata — the same happens when the
DDL command is denied for lack of permission — and says so clearly in the tab. If not
even the column catalog can be read (no permission, or the catalog is unavailable),
there is nothing to reconstruct from: the tab says so instead of sitting silently empty. The table's context menu also offers Copy DDL without opening the tab.
Schema tree: the Schema tree separates Tables from Views (each with its own icon) and marks primary-key columns with a key icon. The filter box sifts only the objects already loaded (lazy loading is not forced just to filter).
Exploring the schema: Right-click a table to Insert SELECT into the editor,
Preview data, Count rows, Copy qualified name or open the
Generate SQL submenu → INSERT/UPDATE/MERGE: a screen lists the
table's columns so you can check Include and Key, shows a live
preview and drops the command into the editor (MERGE comes out in ANSI; if the
driver does not support it, a warning appears). Right on the results grid, the
Generate SQL button on the bottom bar builds an
INSERT/UPDATE/DELETE pre-filled with the values of the selected
row (available when the query is a single-table SELECT). The
table and column names you
browse in the tree also start showing up in the autocomplete
(Ctrl+Space) of the connection's .sql editors, with no extra
database queries.
Export, variables and transactions
Export results: right-click the results grid and choose
Export results... to write CSV (delimiter, quote character, always
quote, header row, NULL text), JSON Lines or SQL
(INSERT statements with a table name), with an optional row limit.
The export walks the whole query in streaming mode (paginated re-fetch),
not just what is visible on screen.
Script variables: use @set name = value on a script line
to define a variable — the @ prefix keeps it away from the database
(it does not collide with the real SET of Postgres/DuckDB/SQL
Server). References like :name are substituted before running
(outside strings and comments; the ::type cast and binds like
:1 stay intact); a :name without a value opens a
prompt before running. The Variables button on the toolbar opens the
screen with the defined variables (edit/add/remove).
Query history: the History button opens a window with the last
statements successfully executed on this connection, in
SQL / When / Duration / Rows columns. Select one to Re-run,
Insert into editor or Copy (double-click inserts), or use
Clear history. It is stored only on the local machine
(it goes neither to Git nor to the .lnc).
Transactions: the Autocommit button (on by default) and the Commit/Rollback buttons live on the toolbar. With autocommit off, changes stay pending until you confirm (Commit) or discard (Rollback); disconnecting with an open transaction asks what to do.
SSH connection (.lns)
An SSH connection is a .lns file in the workspace — versionable
and portable, like the .lnc. Create one via New → New SSH
connection: the tab opens an integrated SSH terminal (through
Windows' ssh.exe) and a remote files mini-bar (SFTP).
The file browser shows one folder at a time (MobaXterm/WinSCP style): the
first row is always .. to go up one level, and double-clicking a folder
enters it. The path bar at the top lets you type a remote path and press
Enter to jump there. The Sync with terminal button makes the shown
folder follow the SSH session's current directory (wherever you cd'd in
the terminal). The right-click menu offers Open in editor (downloads the file,
opens it in a tab and re-uploads on save), Download, Upload,
New folder, Rename, Delete and Permissions (chmod). You
can also drag files from Explorer onto the panel to upload them to the current
folder.
The password can be encrypted inside the .lns with the
workspace's Passphrase or asked on every
connection. SSH keys from the Windows agent/profile work normally, since the
connection uses the system's OpenSSH client.
The Connect on open option (in the connection dialog) starts the SSH
session automatically when you open the .lns. If the password is not
stored, the terminal itself asks for it on connect.
Security: Passphrase, PIN and Secure Markdown
The Passphrase is set per workspace in Help → Configure
Passphrase… and is the key to everything LightNote encrypts: connection
passwords (.lnc/.lns), password cells of the
Custom table and .lne files. The
encryption is strong and portable (Argon2id + XChaCha20-Poly1305): an
encrypted file opens on another machine once you re-enter the same Passphrase
there. Keep it safe: without it, the encrypted data cannot be recovered.
The Passphrase is cached only on the local machine (it never goes to Git).
To change the Passphrase, open the same screen and edit the Passphrase
field (it comes filled with the current one). On confirm, LightNote
automatically re-encrypts all the workspace's secure data — passwords in
.lnc/.lns, the contents of .lne files and
the password cells of Custom tables (.lnd) — from the old Passphrase
to the new one. Decryption is all or nothing: if a single item fails to
decrypt, nothing is changed and LightNote tells you which one. During
writing, each file is copied to a backup before being rewritten; if one
fails to write, LightNote asks whether to undo everything (restore the
backups) or skip that file and continue (it keeps the old Phrase, with a
warning at the end). (Passwords in "ask" mode have nothing to re-encrypt.)
The PIN (4–8 digits) is an optional local lock: it guards sensitive UI actions (revealing passwords, opening secure notes) without typing the Passphrase every time. It encrypts nothing and applies only to this machine.
The Secure Markdown file (.lne, under New → Secure
Markdown File) is a note encrypted on disk: on open, LightNote asks for the
PIN (if set) and the Passphrase, decrypts in memory only and re-encrypts
on save (Ctrl+S). For safety, it never reopens by itself when the session is restored. Other than that, it is a note like any other: it has the AI assistant (Ctrl+K/Ctrl+I and the AI button on the bar), Ctrl+click on wikilinks and tags, opens links and shows the address in the status bar. Worth remembering what AI implies: the snippet you send leaves the machine if the chosen assistant is a cloud service; with a local model (Ollama, LM Studio) it does not. And secure notes remain outside Ask your notes — that one reads the workspace's .md files, and on disk an .lne is encrypted text.
Daily notes, quick capture and tray
Today's note is one .md per day in the
Daily Notes folder — a single folder for all of LightNote, set in
Settings → Notes & writing. From the
tray menu: Today's note opens the note for the day; Quick
capture… (Ctrl+Alt+N, a global Windows shortcut — or
middle-click the tray icon) opens a small window where you type and press
Ctrl+Enter: the text becomes a timestamped bullet in today's note,
written straight to disk, without opening an editor window.
The tray menu also lists the open windows and the recent workspaces, and carries the power toggles: Keep computer awake and Keep screen on (handy for long tasks; LightNote already holds power by itself while running one-shot AI, Blocks cells or SQL scripts). The launcher (start window) has search, double-click to open, and a context menu to pin to top, open in Explorer or remove from the list.
Actions that apply to the whole of LightNote — not just to the window you are in — live in the General menu (☰ General, or the button with the app icon in the activity bar), which has exactly the same shape as the tray menu: at the root Today's note, Quick capture and Calendar; then the submenus Capture (quick task, record audio, resurface old notes, sticky notes), Open (launcher, open workspace, open standalone file, standalone files) and Power; and at the end General settings. The rule is simple: whatever is in the tray menu is in the General menu — and only there. Hovering an item shows the note “general feature: applies to the whole of LightNote, in any window”.
Where a capture goes. Daily notes and quick tasks have a single, predictable destination: the folder set in Settings → Notes & writing and the board set in Settings → General, valid in any window. On the first capture, if nothing is set, LightNote asks where to keep it and stores your answer — instead of sending you off to find the setting. A project that needs its own diary (a client under confidentiality, a log that must live in the repository) can claim the captures made in that window under Workspace Settings → Captures; the tray and the global shortcuts keep writing to the general destination. The confirmation always names where the text went.
The tray menu is deliberately short: the root holds the open windows and the three everyday actions — Today's note, Quick capture and Calendar. Everything else lives in the same submenus as the General menu: Capture, Open (which in the tray also carries the list of recent workspaces), AI (AI sessions and ask your notes — in a window that is the full AI menu) and Power. Settings and quit close the menu.
Resurface old notes
What makes a "second brain" fail most is not a missing feature — it is the note that is never re-read. From the tray menu (the Capture section), LightNote brings old notes back: Random note opens a random .md note from the workspace (avoiding the ones shown in the last two weeks), and On this day lists the notes whose creation anniversary is today (same day and month, in earlier years). Both actions are also in the window's General → Capture menu.
The creation date comes from the frontmatter created/date field, if present; otherwise from the file date. The feature never writes to your notes — it only opens them. It can be turned off in Settings → Features (“Resurface old notes”).
Your notes on your phone
Your workspace is plain Markdown in a folder — open formats, with no proprietary database or mandatory cloud. That's why any phone app reads and edits your notes, without LightNote needing an app of its own for the phone: just sync the folder with a file service and open it in a Markdown editor on your phone.
Step by step: sync the workspace folder with OneDrive, Google Drive,
Dropbox or Syncthing and, on the phone, open that folder in a Markdown editor
(for example Obsidian Mobile, iA Writer, GitJournal or
Markor). Since everything is .md in text, both sides see and
write the same notes.
Recommendations: on the phone, edit only .md files —
LightNote's own types (secure .lne, .lnc,
.lnt, .lnb, .lnd…) don't open outside the
app, and .lne in particular is encrypted. If both sides edit offline
and a conflict arises, resolve it through the Inbox folder: drop
the capture (text, audio or photo) there and let LightNote merge it into the
day's note, instead of overwriting. The positioning is deliberate — syncing is
by files/Git, not by plugins: you own your data and choose the transport.
To write straight into today's note, edit the file
Daily Notes/yyyy-mm-dd.md — the folder name changes with the
language.
Record audio (voice, meeting) with AI transcription
From the tray menu, Record audio… opens a floating, draggable window (drag it by the title bar) to record from the microphone, the system audio (what plays on the computer), or both at once — the chosen source is remembered for next time. Use ● Record, ‖ Pause and ■ Stop; the file goes to the Recordings folder of the workspace, compressed to .m4a when you stop.
Two ways to transcribe. In Settings → AI Assistants → Audio transcription, the How to transcribe selector chooses between the dedicated transcription model (Whisper-style: OpenAI whisper-1, Groq whisper-large-v3 — free — or a local Whisper) and the general model with audio in the chat — the audio goes inside a multimodal model's conversation, which is how Google Gemini (gemini-2.0-flash, good free tier) transcribes. Switching the provider pre-selects the right mode and suggests the model; long audio is sliced automatically in either mode. The suggested model can be overridden by hand — LightNote honors the id you type, even for a provider it doesn't yet recognize.
Once recording starts, the window collapses on its own into a compact pill (a blinking red dot, a timer, Pause/Stop) — easy to drag into a corner and keep almost out of sight during a long meeting; the minimize/expand button in the title bar toggles it manually, and stopping expands it back. Ctrl+Alt+R (global shortcut) is the quick voice note: press it to start recording from the microphone right away, press again to stop — no need to open the window with the mouse.
If an API-based AI provider is configured (in Settings → AI Assistants → Audio transcription), the Transcribe and Transcribe + Summarize buttons appear when you stop (disabled while the audio is still being compressed); the On stop combo can fire the transcription on its own as soon as the recording finishes. LightNote sends the audio for transcription (a Whisper-style model) and writes a .md note next to the audio with the text and, optionally, a summary. Turn the feature on/off in Settings → General → Features.
The same window is a mini-player: below the controls, a list of recordings in the folder shows each file with T (open the transcription) and R (open the summary) buttons when they exist, plus a ▶ to play right there (progress bar with seeking); each row's ⋮ menu plays, (re)transcribes or opens the note. Regenerating a transcription does not overwrite the previous one — it creates a new version alongside (note.md, note (2).md…), preserving the history. The capture source is a menu button (Microphone / System audio / Both), with Both as the default. The Open recordings folder link opens the folder in the main window.
Sticky notes
Sticky notes are small colored plain-text boxes that float over the desktop, in the style of the Windows Sticky Notes app. From the tray menu: New sticky note (Ctrl+Alt+S, a global shortcut) creates a box; Show sticky notes (Ctrl+Alt+H) shows or hides them all at once. Each note has a + to create another and a ☰ menu to change the color, Send to today's note (writes the text as a bullet in today's note and discards the box) or Delete. Drag the header to move and the corner grip to resize. Notes are saved automatically and reappear when you reopen LightNote.
Checklist. The list button in the header (next to the +)
turns the cursor's line — or the selected lines — into items with a checkbox, and
undoes it on a second click. You can also type [ ] and a space at the
start of a line ([x] creates the item already checked). Click the
checkbox, or press Ctrl+Shift+Enter, to check and uncheck it: a completed
item is struck through. Enter creates the next item; Enter on an
empty item, or Backspace at its start, goes back to plain text. Remove
completed items, in the note's menu, deletes the checked ones at once
(Ctrl+Z undoes it). Items are saved as Markdown tasks
(- [ ] item), so Send to today's note carries each one as a
task.
Calendar
General → Calendar… opens a single window with a calendar that marks the
days holding tasks from every registered .lnt board. Next to
it, the Of the day list (tasks for the selected day) and the Pending
list; the Day's note button opens the daily note for that date. Clicking a
task opens the corresponding board.
In the grid, each day with tasks gets colored dots in the colors of the Kanban statuses (up to three), today is marked with a ring and the selected day with a filled circle; Today returns to the current month, and the month name opens a menu to jump by month or year. Pending items are grouped by situation — Overdue, Today, Next 7 days, Later and No date —, with the due date shown as a relative badge (“yesterday”, “today”, “3 days ago”). Double-clicking a day opens the quick task already dated.
Tasks written in notes show up here. A - [ ] checkbox in a note is a task like any other, and it now appears under Pending next to the board cards, in the same groups. If the line says when (tomorrow, friday, 2026-08-12), it lands in the right group and on the right day. A double click opens the note at the line of the checkbox — the note stays the place where you edit the task. The scan runs in the background: the window opens right away with the boards, and the note tasks arrive shortly after. On the grid, a day number is underlined when that day already has a daily note, and the day list also shows On this day: your notes from earlier years written on that date.
Command palette
Ctrl+Shift+P opens the command palette (every action with its shortcut, filterable by typing). Ctrl+R opens the quick file picker and Ctrl+Shift+K opens the task picker.
MCP server (AI agents)
LightNote includes a headless MCP (Model Context Protocol) server that
turns your workspace into a tool for AI agents (Claude Desktop, Claude Code,
Cursor, and any MCP-speaking client). The agent can read and write files, search,
query tabular data and databases, work with the tasks, use Git and fire HTTP
requests — everything confined to the folder (directory jail: paths
with .. or outside the root are refused). The transport is
JSON-RPC 2.0 over stdin/stdout; each session spins up a lightweight
lnote.exe process, separate from the editor window.
One-click shortcut: AI → Enable AI in this folder turns on MCP and writes the .mcp.json in one go (the click is the consent). If AI is already active in the folder, the item becomes Configure AI in this folder… and opens Workspace settings.
Two layers of safety: (1) the server only starts if you have opted in for that folder; (2) every tool is locked to the workspace root. On top of that, each tool is announced with annotations (read-only, destructive, idempotent, "touches the outside world") so the AI client can assess the risk before calling it.
Step-by-step setup
- Enable MCP for the folder. In Tools → Workspace Settings, check
Enable MCP for this workspace. Without this opt-in the server refuses to
start (it's the main gate). Alternatively, from the command line:
lnote --mcp-enable "C:\Path\to\workspace"(and--mcp-disableto turn it off). - Find the path to
lnote.exe. It lives in the same folder aslightnote.exe(the app's install folder). It's the "slim" console executable, no UI — this is what the agent runs. - Register the server in your AI client, pointing the command at
lnote.exeand passing--mcpfollowed by the workspace folder. In the format used by Claude Desktop / Cursor and the like:
{
"mcpServers": {
"lightnote": {
"command": "C:\\Path\\to\\lnote.exe",
"args": ["--mcp", "C:\\Path\\to\\workspace"]
}
}
}
Configuration tips:
- Backslashes in JSON must be doubled
(
C:\\Users\\...\\lnote.exe), as in the example. - To expose several workspaces, add one entry per folder, with distinct
names (
"lightnote-projectA","lightnote-projectB"), each pointing at its own root. - After saving the configuration, restart the AI client so it starts the
server. Once connected, the agent should list the
lightnote_*tools; ask it to "list the workspace files" to confirm it works. - For Claude Code (CLI), the same server can be registered with
claude mcp add lightnote -- "C:\Path\to\lnote.exe" --mcp "C:\Path\to\workspace".
Database password (optional). The db_query tool opens a
.lnc connection. If the password is encrypted with the Passphrase,
pass the phrase via the LNOTE_PASSPHRASE environment variable in the
server block (never in command-line arguments) — connections whose password is in
"ask" mode can't be used unattended.
AI queries are opt-in per connection. Enabling MCP in the folder does not expose the connections: each .lnc only answers db_query when “Allow AI queries (MCP)” is checked in the connection dialog. Access is read-only (SELECT).
Exporting from the database via the agent. Besides querying, the agent can materialize a SELECT into a file with db_export (Parquet, CSV, JSON or .xlsx) — useful for results too large to fit in a reply. The same three safeguards apply, in this order: the query must be read-only, the connection needs the «Allow AI queries (MCP)» opt-in (checked before the password is decrypted), and the destination must stay inside the workspace. Large exports use the system temp folder as scratch space, roughly the size of the result — keep disk space free.
Available tools
The agent sees the tools under the client's prefix (e.g.
lightnote_read_file). By category:
- Files:
read_file(with optional line range),write_file,edit_file(replaces an exact snippet, without rewriting the whole file),append_file,list_files,move_file,make_diranddelete_file(goes to the Recycle Bin, not a hard delete). - Search and navigation:
search_files(ripgrep, with subfolder/glob filter and limit),list_symbols(outline of a file's functions/classes) andopen_in_editor(opens/focuses a file in the LightNote window, if it's open). - Data and SQL:
query(DuckDB SQL over Parquet/CSV/JSON, tsv/json/markdown output),describe_table(schema + statistics, without dumping rows),export_query(materializes a SELECT into a file viaCOPY),sqlite_query(SQL on a.sqlite/.db),db_list_connections(lists the workspace's.lncfiles) anddb_query(read-only SQL on a.lncconnection). To send the result to a file instead of the reply,db_export(Parquet/CSV/JSON/.xlsx). - Also:
search_notes(retrieves the most relevant note snippets for a question — the same engine as AI Chat),list_links(a note's outgoing links, resolved or broken),audit_vault_links(broken links and orphan notes across the vault),list_note_templatesand thetemplateparameter ofcreate_note,list_due_tasks(tasks due today or overdue across all projects),xlsx_read(reads an.xlsxsheet as TSV),data_diff(compares two tabular files) and the database catalogdb_list_objects/db_describe(tables/views and a table's columns, keys and DDL — same requirements asdb_query). Andnote_export(exports a note todocx,odt,epub, LaTeX, Typst, HTML, reStructuredText, AsciiDoc, Org, MediaWiki, Notebook or another Markdown dialect — with no window at all, and also fromlnote note-export). Andnote_import(the reverse: adocx,odt,epub,rtf, HTML ortexfile becomes a note next to the original, with headings, lists, tables, emphasis, links, equations and images — also fromlnote note-import). Andfolder_export(a whole folder becomes an HTML site, a set of documents or Markdown, with the links rewritten — also fromlnote folder-export). - Archives:
zip_list(lists the members of a.zip/.isx) andzip_read(reads a member as text) — without extracting the archive to disk. - Tasks:
list_task_projects(lists the workspace's.lnttask projects),list_tasks,list_task_statuses(board columns),create_task,update_task,update_task_status(move between columns),delete_taskandtask_note(read/write the task's.mdnote). A workspace may hold several.lntprojects: pick one with theprojectparameter (thenamereturned bylist_task_projects; optional when there is only one). Theid/status_idare session identifiers — do not read the internal.lntfiles to obtain them; use the task tools. - Notes (PKM):
create_note(create a.mdnote),append_daily_note(append a capture to today's note),remember(stores one durable fact about you in the memory note),list_backlinks(notes pointing to a note),list_note_tagsandsearch_by_tag(the vault#hashtagsand the notes using them) andadd_task(create a task with due date/tags, accepting natural language in the title). - Git:
git_status,git_log,git_diffandgit_restore. - Web and alerts:
http_request(fires an HTTP request and returns status/headers/body) andnotify(shows a tray notification on the open window — handy for the agent to signal it's done). - AI proxy:
list_ai_modelsandask_ai(below).
The server also exposes the workspace files as MCP resources
(resources/list and resources/read), for clients that
prefer to "attach" files instead of calling read_file.
Your Prompt library (the workspace's Prompts/ folder) is exposed as MCP prompts (prompts/list and prompts/get). In Claude Code each prompt becomes a slash command — /mcp__lightnote__<name> — ready to use inside the AI CLI.
Write safety net. Before overwriting (write_file/edit_file) or removing (delete_file) a file, the server saves the previous version to the Local History — the editor's own safety net — so you can undo a change made by an agent even outside a Git repository.
Each tool declares whether it reads or writes: besides the MCP annotations
(readOnlyHint/destructiveHint), the description starts with a
[read-only], [writes] or [destructive] badge —
handy for building allowlists safely.
AI proxy (delegate to another model)
The API providers you registered with the MCP column
checked are exposed to the agent through two tools: list_ai_models
(lists the allowed models, with id, name and model) and ask_ai
({model, prompt}). This lets the main agent delegate a sub-task
to a cheaper or specialized model. The call is brokered by the running
LightNote (the MCP's lnote.exe forwards the request to the app
window over the internal bridge): the API key never leaves your machine and
never reaches the agent. If LightNote isn't open, the tool returns an error asking
you to open it.
Command line (lnote)
The same MCP operations live in a console executable, lnote, for
scripts and automation (also reachable as
lightnote cli <command>). Every action is confined to the
root folder, set by --root (default: the current folder).
Examples:
lnote list --recursive
lnote read --path src/main.cpp --start-line 1 --end-line 40
lnote write --path note.md --content "Hello"
echo content | lnote write --path note.md --content -
lnote search --query TODO --regex
lnote query --sql "SELECT * FROM read_parquet('data.parquet') LIMIT 10"
lnote describe --path data.parquet
lnote search-notes --query "where did I write about the budget"
lnote audit-links
lnote xlsx-read --path spreadsheet.xlsx --sheet 0
lnote data-diff --a before.parquet --b after.parquet --mode changed --keys id
lnote db-describe --connection data.lnc --table customers
lnote db-export --connection dados.lnc --sql "SELECT * FROM clientes" --out clientes.parquet
lnote due-tasks
lnote export --sql "SELECT * FROM read_csv_auto('e.csv') WHERE state='NY'" --out ny.parquet
lnote zip-list --path export.isx
lnote zip-read --path export.isx --entry job/definition.xml
lnote task-projects
lnote tasks --project Backlog
lnote create-task --project Backlog --title "Review the text" --effort 2
lnote move-task --project Backlog --task-id 5 --status-id 2
lnote git-status
lnote http --url https://api.example.com --method GET
lnote notify --message "Processing finished"
Global options: --root <folder>, --json
(structured {ok,data,error} output), --help (or
lnote <command> --help) and --version. Unknown
commands get a suggestion ("did you mean…?").
Bulk-update older data: lnote upgrade <folder>
modernizes files written by earlier LightNote versions in one pass — currently the legacy
.lnsh and .lnsm extensions, which became .lns and
.lne. The app already does this on its own when you open each file;
the command is for when you have dozens and don't want to open them one by one. Use
--dry-run to preview what would change without touching anything. It is a
convenience, not a requirement: your older files keep opening fine without it.
Settings and themes
Where the options are
In Tools → General Settings you adjust, in sections: General options (language, autosave, release idle tabs, tab color palette, window title, daily notes, spell checking), the application Theme, the Editor font and colors, the Markdown style, Execution (interpreters), the Terminal (shells), the AI Assistants (CLIs and the default AI), Versioning and the Database (pagination, Oracle Instant Client).
A search field at the top of the section list filters by the options on each page; and the Features section gathers the toggles for the optional features — connections graph, sticky notes, AI sessions, AI Chat, audio recording, resurface old notes, keep the computer awake and Windows Explorer menu integration. Turning a feature off removes it from the interface, the tray and the shortcuts, and stops consuming resources — but keeps the data already created; the change takes effect on restart.
Themes
The application theme changes the program's appearance (menus, tabs, panels, status bar). There are several ready-made themes — light ones (Light, Solarized Light, Catppuccin Latte, Gruvbox Light, One Light, Rosé Pine Dawn, Everforest Light, Tokyo Night Day) and dark ones (Dark, Tokyo Night, Dracula, Ayu Mirage, Nord, Gruvbox Dark, Everforest Dark, Kanagawa Wave) — plus the Custom mode with an accent color. New themes arrive through the online catalog, without having to update the application.
The code Editor and Markdown colors are chosen separately, in their own sections, independent of the application theme. Each one has a Theme: combo with ready-made color schemes (Default, Dracula, One, Nord, Gruvbox and Tokyo Night, in light and dark variants), a live preview and a Save as… button to store your own colors as a reusable preset.
Per-window theme. Each folder (workspace) can have its own theme, so you can keep two windows open with different looks at the same time. In Workspace Settings → Appearance of this folder there are combos for the theme for this window (the application's look), the code theme and the Markdown theme — each with a Follow general theme/Keep default option to leave it unchanged. Overriding the code and Markdown themes is handy to match the editor colors to a dark theme in that folder only, without touching the general Settings. These choices stay on your machine (they are not committed to Git).
Tools, title and layout
Install guide. When you pick a catalog tool (AI assistant, interpreter,
formatter, linter or database driver) that is not on your computer yet — or you try to
run/format/lint a file whose interpreter is missing — LightNote opens an install
guide. When a safe command exists (via winget), the guide shows the
exact command and runs it in an embedded console with one click; if the tool
depends on another (for example, a CLI that needs Node.js), it offers to install the
prerequisite first. Without an automatic installer, the guide opens the official
download page with step-by-step instructions. When it finishes, it verifies the
install and makes the tool ready to use, without restarting the app.
Formatting and Linters have their own sections (external
formatter/linter per language, with Add from a catalog). To carry your
preferences to another machine, the Settings migration group (General
section) has Export/Import settings (a .lnconf file):
the general options and content themes go, but not the API keys or local
paths (re-enter those on the target).
The window title is a free-form template: the app name always comes at the
end and you compose the rest with the variables {workspace} (workspace root
folder), {file} (open file name) and {path} (full path).
Decorations around an empty variable (e.g. the brackets in [ {workspace} ])
disappear on their own; leave the field blank for the default
[ {workspace} ] {file} — .
Window layout. Under View → Window layout (or General settings → General → Window layout) you pick one of three presets — Modern (the default), Classic and Comfortable — or adjust each option on its own: show the menu bar at the top (with it on the ☰ button disappears, since both open the same menus), show labels next to the icons, put the toolbar and the sidebar on the left or on the right, and the icon size. Choosing a preset only fills in the options: changing any of them afterwards undoes nothing, the list simply starts showing "(custom)". The change takes effect right away, in every open window.
Portable mode: your data next to the program
In the .zip release, LightNote keeps settings, sessions, local history and indexes in a Windows folder (%LOCALAPPDATA%), outside the program folder. Portable mode brings all of that next to the executable, and then the whole folder can live on a USB drive, an external disk or a synced folder.
To turn it on: extract the .zip where the copy is going to live, open Settings → General → Portable mode and click Make this copy portable…. The window shows where the data comes from and goes to, how big it is and what changes; on confirmation LightNote copies (never moves) and asks you to close and open the program. The old copy stays where it was, intact — if anything goes wrong, nothing was lost.
After that the program folder gains two new folders: profile, with what is yours (settings, sessions, history, downloaded dictionaries), and profile-cache, with indexes only, which the program rebuilds on its own. You can delete profile-cache at any time to reclaim space.
To update to a new version: download the new .zip, extract it into a new folder and copy the profile folder from the old version into it. That is all. profile-cache does not need to be copied (it rebuilds itself); copying it also works, it is just unnecessary. Do not go the other way round: a profile written by a newer version makes the program open read-only, so that it does not damage what it cannot yet read.
To turn it off: go back to Settings → General → Portable mode and click Turn off portable mode…. Nothing is deleted: the two folders are only renamed (to profile.desativado and profile-cache.desativado), and LightNote uses the Windows folder again on the next start. You decide later whether to delete them, restore them or copy whatever you want from them.
What does NOT travel with the folder to another computer. Three secrets are protected by Windows per user and machine, so they do not decrypt on another PC: the AI keys, the file passwords you asked to remember and the stored Passphrase. Just enter them again there — nothing is lost, and your secure files still open normally with the Passphrase you type. Besides that: open tabs and folders store the full path, so they move if the drive letter changes; the Explorer integration is turned off when you enable the mode (it writes to the machine's Windows, the opposite of what portable mode promises) and can be turned back on in Settings; and the .mcp.json written into your repositories points to the full path of lnote.exe, so it has to be redone on the new machine.
Taking the AI keys with you (optional). In Settings → General → Portable mode there is Protect the keys with a passphrase…. Turned on, the AI keys and the remembered file passwords stop depending on Windows and travel with the folder. Think twice: today, losing the stick costs nothing — the secrets do not open outside your machine; with a passphrase, whoever gets the folder can try to guess it at their leisure. Use a long passphrase. The workspace Passphrase does not go into this keyring, on purpose: it opens your secure notes, and a single phrase should not unlock everything. Tick Remember on this machine so you are not asked on your own computer — elsewhere, the question comes back.
chaveiro-do-perfilPortable mode is for the .zip release. A copy installed by the installer and the Microsoft Store edition cannot be converted — their folder is read-only or is managed by the uninstaller — and the window says so instead of leaving the button without effect. From the command line, with LightNote closed: lnote portable --status, lnote portable --on (accepts --dry-run) and lnote portable --off.
Keyboard shortcuts
- F1 — this help (at the current screen's section)
- Ctrl+N / Ctrl+O — new file / open file
- Ctrl+S / Ctrl+W — save / close tab
- Ctrl+Alt+Shift+S — save all (every modified tab)
- Ctrl+F / Ctrl+H — find / replace in the file
- Ctrl+Shift+F — global search (ripgrep)
- Ctrl+Shift+G — versioning panel (Git)
- Ctrl+Shift+E / Ctrl+Shift+M — Explorer panel / Pending items panel
- Ctrl+B — show/hide the sidebar
- Ctrl+' — terminal (on the US layout, also Ctrl+`)
- Ctrl+/ — comment/uncomment; Ctrl+Shift+D — duplicate line
- F5 — run file; Ctrl+Shift+Enter — send selection to the terminal
- Ctrl+K / Ctrl+I — ask AI / edit with AI
- Ctrl+B / Ctrl+I / Ctrl+E — in a Markdown note: bold / italic / toggle the view mode
- Ctrl+Shift+X / Ctrl+Shift+C / Ctrl+Shift+H — in the note: strikethrough / inline code / highlight
- Ctrl+1…Ctrl+6 — in the note: heading level (the same level again returns to a paragraph)
- Ctrl+Shift+V — in the note: paste without formatting
- Ctrl+Enter — “run here”: SQL statement, Blocks cell, API request, diagram/formula source in the note
- Ctrl+Shift+R / F4 — macro: record / replay
- Ctrl+R — go to file; Ctrl+Shift+P — command palette
- Ctrl+Shift+K — go to task; Ctrl+Shift+T — reopen closed tab
- Ctrl+Alt+G — connections graph
- Ctrl+Alt+N — quick capture (global, even outside LightNote)
- Ctrl+Alt+D / Ctrl+Alt+T — today's note / quick task
- Ctrl+Alt+R — record/stop audio (global, quick voice note)
- F11 — Zen mode (the tab takes over the whole window)
- Ctrl++ / Ctrl+- / Ctrl+0 — zoom
The same key can do different things depending on the screen in focus: the focused view wins, and outside it the window shortcut applies. With a Database tab in focus, F4 opens the object properties instead of playing the macro; in the Diff and in the output panel, F8/Shift+F8 jump from change to change; and in the Standalone files window, Alt+←/Alt+→ go back and forward between folders. The full, filterable list lives in Help → Keyboard Shortcuts.
License, editions and community
LightNote ships in editions with the same features, differing only in licensing and delivery:
- LightNote (free, from the website): for personal, non-commercial use.
- LightNote Core (Microsoft Store): acquired as a contribution to the project; grants a commercial-use license and receives automatic updates through the Store.
- LightNote Business (future): volume/enterprise licensing, reserved for future availability.
Your copy's edition — and therefore which clauses apply — is shown in Help → About. The full terms are in Help → About → License terms….
Join in and contribute:
- Suggestions and questions: GitHub Discussions —
github.com/nglczr/LightNote-Community/discussions - Found a bug? Report it on GitHub Issues —
github.com/nglczr/LightNote-Community/issues - Support development on Ko-fi —
ko-fi.com/lightnote(or get LightNote Core on the Store) - Contact:
contato@lightnote.com.br· Website:lightnote.com.br