Managing Document-Level Metadata in Neorg
Explore how Neorg uses document-level metadata blocks to store structured project data and file attributes without cluttering the main content.
12 Dec 2025, 13:54 UTC

The Problem: Document-Specific Context
When organizing a large knowledge base in Neorg, global configuration is often too blunt a tool. You may want specific notes to carry metadata—such as a creation date, a project ID, or a status tag—that doesn't belong in the visible body of the text but needs to be accessible to the editor or external scripts. Without a structured way to store this, users often resort to manual headers or inconsistent tagging, making it difficult to programmatically query files.
The Norg Approach to Metadata
Neorg handles this through a specific structural element within the Norg markup language. Rather than relying on external configuration files or non-standard headers, Neorg allows for the definition of metadata directly within the document. This is typically achieved using a dedicated metadata block, which the Neorg parser identifies as a distinct part of the document's Abstract Syntax Tree (AST).
By separating metadata from the content, Neorg ensures that the structural data used for organization does not interfere with the visual flow of the document. Because this is handled by the Tree-sitter grammar, the editor can provide specific highlighting and folding for these blocks, allowing them to be tucked away when not in use.
Implementing Metadata Blocks
In a .norg file, metadata is generally defined using a specific block syntax. While Neorg is evolving, the standard pattern involves creating a metadata section that stores key-value pairs. This allows the user to assign attributes to the file that can be read by Neorg's internal functions or custom Lua scripts.
Example Configuration
To define metadata for a project note, you would structure the top of your file as follows:
@document.meta
project: "Alpha-Centauri"
status: "in-progress"
created: 2026-10-13
To verify that Neorg is recognizing this metadata, you can use the Neovim command line. While specific command names may vary by Neorg version, the general workflow is:
- Open the
.norgfile in Neovim. - Ensure the
norgfiletype is active. - Use the internal Neorg API via Lua (e.g.,
:lua require('neorg').get_metadata()) to check if the current buffer's metadata table contains the keysprojectandstatus.
Trade-offs and Limitations
Using in-file metadata offers a significant advantage: the metadata travels with the file. If you move a .norg file to another machine or directory, the context remains intact. However, there are practical limitations to consider:
- Parser Dependency: Because metadata relies on the Tree-sitter grammar, files viewed in a plain-text editor will show the metadata blocks as raw text.
- Strict Syntax: If the metadata block is malformed (e.g., missing a colon or using unsupported characters), the parser may fail to recognize the block, treating it as standard text rather than structured data.
- Performance: In extremely large files with massive metadata blocks, there may be a slight overhead during the initial buffer load as the AST is constructed.
Verification and Maintenance
To ensure your metadata is functioning correctly, periodically check that your blocks are correctly folded and highlighted. If the metadata appears as standard text without the expected syntax highlighting, verify that your Neovim version and the norg grammar are up to date. To remove metadata, simply delete the block; since this operation only changes the file content, no complex rollback is required beyond standard file undo (u).
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.