Skip to main content
After indexing, smolbren builds a directed property graph from your vault: note types (the type frontmatter key) become node labels, and frontmatter keys that contain wikilinks become relationship types. The node ID is the note’s vault-relative path without the .md extension — for example, blogs/context-engineering. You query this graph with Cypher, the same query language used by Neo4j and other graph databases. Every smolbren query call prints a single line of JSON to stdout:

Discover your schema first

Before writing queries, inspect what node labels and relationship types exist in your vault. List node types and counts:
List relationship types and counts:
These names are what you put inside (:NodeLabel) and -[:EDGE_TYPE]-> in your Cypher queries.

Basic patterns

Match every note with a given node label and return their IDs and titles.
Follow a specific edge type from a source label to any target. This returns every blog note and the notes it mentions:
Use a $-prefixed parameter to target a single note by ID. Pass the parameter with --param:
Aggregate to find the most-mentioned notes across all blogs:
Note is a catch-all label that matches every note in the vault, regardless of its type value. Use it to query across multiple types or when you don’t know the exact label:
Traverse from one specific label to any note (using Note) along a known relationship type. This returns every blog that was merged from another blog:

Using parameters

Pass runtime values into queries with --param key=value. The flag is repeatable:
smolbren JSON-parses the value first, so: If JSON parsing fails, the value is passed as a plain string. This means you almost never need to add quotes — just write --param id=blogs/context-engineering, not --param id='"blogs/context-engineering"'.

Output format

Every smolbren query result has the same shape:
  • columns — ordered array of projection names, matching the aliases or expressions in your RETURN clause.
  • rows — array of row objects. Each object’s keys are the column names from columns, and values are the corresponding projected values.
To reshape this in jq:
Note is a catch-all label that matches every note in the vault — typed or not. Use (n:Note) when you want to reach nodes of any type or when the target label of a relationship is unknown. It is always registered automatically, even if no note has type: Note in its frontmatter.
Body text and raw frontmatter JSON are not projected in query results. The graph engine loads only id, path, type, and title per node for performance. If you need the body or arbitrary frontmatter scalars like status, use smolbren get <id> (or smolbren get <id> --body) to fetch the full note record after your query identifies the relevant IDs.