Typed links and the case for a unified property architecture
This post is both a feature request and a proposal for how three related capabilities might fit together. The request itself – typed links, or semantic links – is not new. There’s a thread from 2020 with 177 votes and years of discussion. But the problem remains unsolved, and I want to reframe it as part of something larger: an architectural vision for how Obsidian’s property system could evolve to match the actual structure of knowledge work.
The core request is simple: links should be able to carry semantic information. Not just “Note A links to Note B,” but “Note A contradicts Note B,” or “Note A depends on Note B,” or “Note A follows from Note B.” The relationship has a type, and that type matters.
This matters because knowledge isn’t a flat network of associations. Ideas stand in specific relationships to each other: support, contradiction, causation, sequence, instantiation, generalization. A link that can only say “related somehow” loses this information. The graph shows connections but not their nature. Queries can find links but not filter by what they mean. The backlinks pane lists everything that points here, but not why.
The epistemological problem
Consider what happens when you build a body of notes over years. Thousands of links accumulate. The graph becomes a dense web where everything connects to everything else, and the visualization tells you almost nothing. You hover over an edge and learn only that two notes are linked. You can’t see which links represent agreement and which represent disagreement. You can’t distinguish a causal relationship from a mere association. You can’t tell whether one note extends another or contradicts it.
This is not a minor inconvenience. It’s a fundamental loss of information. When I link two notes, I know why I’m linking them. That knowledge exists in my head at the moment of linking. But the system captures only the fact of connection, not its meaning. The semantics evaporate. Later, when I return to these notes, I have to reconstruct from context what the link was supposed to signify.
Worse, the loss is invisible. The graph looks rich and interconnected. It suggests that structure exists. But the structure it shows – raw connectivity – isn’t the structure that matters. What matters is how things connect, not just that they connect. A web of contradictions looks identical to a web of supporting arguments. A chain of reasoning looks identical to a collection of associations.
This is why many people find Obsidian’s graph view beautiful but useless. It visualizes the wrong thing. Not because the developers made poor choices, but because the underlying data model can’t express what would need to be visualized.
Three features, one architecture
I’ve recently posted two other feature requests that turn out to be deeply related:
Property inheritance addresses how properties flow between notes – from folders, tags, and MOCs to their children. When a folder represents a project, notes within that folder should inherit project-level properties without manual duplication. When a tag represents a category, tagged notes should inherit category-level defaults. This extends the property system horizontally, across the note hierarchy.
Block-level properties addresses how properties apply below the note level – to sections, paragraphs, and blocks within a note. A long document might contain sections in different states of completion, passages written from different perspectives, claims with different confidence levels. Currently, properties attach only to the note as a whole; everything below that boundary is invisible to the property system. This extends the property system vertically, into the internal structure of notes.
Typed links addresses how properties apply to relationships between notes – not “what is this note?” but “what is the connection between these notes?” A link is an entity in its own right, and like any entity, it can have properties. The most fundamental property is its type: what kind of relationship does this link represent? This extends the property system relationally, into the connections between notes.
Together, these three capabilities form a coherent vision: properties that work in all dimensions. Notes have properties. Blocks within notes have properties. Links between notes have properties. And all of these can be inherited, queried, and visualized in consistent ways.
This isn’t three separate features awkwardly bundled together. It’s one architectural principle – that metadata should be attachable at every level of the knowledge structure – applied consistently across the three dimensions that matter: hierarchy (inheritance), granularity (blocks), and relationship (links).
Use cases in depth
The abstract argument matters less than concrete application. Here’s where typed links would change how I work:
Fiction writing
A novel is a network of elements: scenes, characters, locations, themes, plot points, timeline events, narrative arcs. The relationships between these elements aren’t uniform – they have types that determine how the elements function together.
Consider the relationships a single scene might have:
- It features certain characters (but not others)
- It takes place in a location
- It advances a plot thread
- It foreshadows a later development
- It echoes an earlier scene thematically
- It follows another scene chronologically
- It manifests a theme
- It reveals information the reader didn’t have
- It complicates a relationship between characters
Currently, I can link a scene note to all the relevant character notes, location notes, theme notes. But the links are undifferentiated. The graph shows that the scene connects to many things; it doesn’t show how. To understand the structure, I have to open the note and read the prose where I’ve described these relationships in natural language.
With typed links, the structure becomes queryable:
- Show me all scenes that foreshadow the climax
- Show me all scenes where these two characters appear together (features both)
- Show me the chronological sequence (follows chain) of Act Two
- Show me which themes manifest most frequently in which locations
- Show me all scenes that complicate the central relationship
This isn’t just convenient; it changes what’s possible. A novel is too complex to hold entirely in memory. The relationships between hundreds of scenes, dozens of characters, multiple interwoven plot threads – this exceeds what I can track mentally. Typed links would make the narrative structure navigable as structure, not just as a pile of connected documents.
Technical documentation
Software documentation describes systems with explicit, formal relationships. These aren’t vague associations; they’re typed connections that determine how information should be used.
Consider a component in a software system:
- It requires certain dependencies
- It implements an interface
- It extends a base class
- It deprecates an older approach
- It replaces a previous component (as of a version)
- It conflicts with certain configurations
- It integrates with external services
- It configures behavior through specific settings
- It throws certain errors under specific conditions
- It logs certain events
When I document a system, these relationships exist and matter. Currently, I can link between component documentation, but the links lose their type. A link from Component A to Component B could mean “requires,” “replaces,” “conflicts with,” or “integrates with” – fundamentally different relationships with different implications.
The practical consequence: when I update Component B, I need to find everything affected by the change. But “everything linked to Component B” includes notes that require it (definitely affected), notes that it replaced (historical context, not affected), notes that describe how to integrate with it (potentially affected), and notes that document conflicts (need to verify if conflict persists). Without link types, I can’t filter. I have to open every linked note and determine the relationship from context.
With typed links:
- Show me everything that requires this component
- Show me the deprecation chain leading to the current approach
- Show me all conflicts with relationships to check after an update
- Show me what this component replaced for historical context
The documentation becomes a queryable model of the system, not just a pile of interconnected descriptions.
Zettelkasten and argumentation
The Zettelkasten method is fundamentally about ideas developing through relationship. A note doesn’t just exist; it exists in conversation with other notes. It responds to, extends, contradicts, synthesizes, or applies other notes. This dialogical structure is the whole point.
Consider the relationships in an evolving argument:
- Note A proposes a thesis
- Note B provides evidence for the thesis
- Note C offers a counterexample to the thesis
- Note D refines the thesis to accommodate the counterexample
- Note E contradicts the refined thesis entirely
- Note F synthesizes the contradiction into a higher-level understanding
- Note G applies the synthesis to a concrete case
- Note H questions the assumptions underlying the whole line of reasoning
This is the structure of thinking. It’s not a flat network of “related ideas.” It’s a directed, typed network of intellectual moves. Each link represents a specific argumentative relationship.
Currently, I can gesture at this structure in prose: “This note contradicts [[Note E]].” But the relationship type is buried in natural language. The graph shows that notes are connected; it doesn’t show the argumentative structure. I can’t query for all notes that contradict a position. I can’t visualize the flow of argument from thesis through counterexample to synthesis.
With typed links:
- Show me all notes that contradict this position
- Show me the evidence for chain supporting a thesis
- Show me all applications of a theoretical framework
- Show me refinement sequences showing how ideas evolved
- Visualize the argumentative structure: thesis → objections → responses → synthesis
The Zettelkasten becomes what it’s supposed to be: a thinking partner that shows you the structure of your own thought. Not just “here are related notes,” but “here’s how your ideas connect, where they conflict, and where they might develop next.”
Syntax considerations
The 2020 thread contains multiple syntax proposals. Each has trade-offs. Rather than add another proposal to the pile, I want to consolidate what’s been suggested and analyze the options.
Option 1: Prefix syntax (Semantic MediaWiki style)
[[contradicts::Other Note]]
[[depends-on::Component B]]
[[foreshadows::Climax Scene]]
[[extends::Previous Argument|see this development]]
The link type comes first, then the target, with optional alias. This reads naturally as “contradicts Other Note” – the relationship is primary. It’s familiar to anyone who’s used Semantic MediaWiki or Dataview inline fields. The double colon distinguishes it from other uses.
Advantages: Readable, relationship-first, consistent with existing conventions.
Disadvantages: Differs from standard wikilink syntax where the note name comes first. Might require significant parser changes.
Option 2: Suffix syntax (extended alias)
[[Other Note|contradicts]]
[[Component B|depends-on|display text]]
[[Climax Scene||foreshadows]]
This extends the existing alias syntax. The link target comes first, then the relationship type, then optional display text. The empty field in the third example means “use default display but specify type.”
Advantages: Builds on existing syntax. Note name remains primary.
Disadvantages: Less readable. Relationship type is buried at the end. Order of type and display text might be confusing.
Option 3: Inline property syntax
contradicts:: [[Other Note]]
depends-on:: [[Component B]]
foreshadows:: [[Climax Scene]]
This treats the typed link as a property that happens to contain a link value. Already works with Dataview for querying. The relationship is expressed as a property name.
Advantages: Already functional with existing tools. Clear semantics.
Disadvantages: Doesn’t feel like a “link with a type” – it feels like a “property with a link value.” The link isn’t first-class; it’s subordinate to the property. Multiple relationship types to the same note require multiple lines. Doesn’t appear in graph or backlinks in a typed way.
Option 4: Property syntax with extended link
relationship:: [[contradicts::Other Note]]
Combines property and prefix syntax. The property name is generic (“relationship” or similar), and the link itself carries the type.
Advantages: Explicit about what’s happening. Works with existing property system.
Disadvantages: Verbose. Redundant structure.
My preference
I favor Option 1, the prefix syntax. It makes the relationship type primary, which matches how I think about typed links. When I create a link, the why often matters more than the what. “This note contradicts something” is the cognitive move; which note it contradicts is the detail.
But the syntax matters less than the capability. Any of these could work. The important thing is that link types become first-class entities that the system understands – recognized by the parser, visible in the graph, queryable in Dataview, preserved in backlinks.
What typed links enable
Beyond the immediate use cases, typed links unlock capabilities that don’t currently exist:
Filtered and semantic graph views
The graph could show only specific relationship types. Display only contradicts relationships to see the structure of disagreement in my notes. Display only depends-on relationships to see dependency chains. Display only follows relationships to see temporal or logical sequences.
Edges could be colored by type: red for contradiction, green for support, blue for extension. The graph would become interpretable – not just “here’s a web of connections” but “here’s how different kinds of connections distribute across your notes.”
Edge direction could become meaningful. Currently, the graph shows undirected connections (or treats direction as incidental). With typed links, direction matters: A contradicts B is different from B contradicts A. The graph could show directed edges where the relationship is asymmetric.
Semantic queries
Dataview already queries properties; extending this to link types is natural:
LIST FROM [[]] WHERE link-type = "contradicts"
Find all notes that contradict this one.
TABLE file.name, link-target
WHERE link-type = "depends-on" AND link-target.status = "deprecated"
Find all dependency links pointing to deprecated components.
LIST WHERE any(file.outlinks, (l) => l.type = "foreshadows" AND l.target = [[Climax]])
Find all notes that foreshadow the climax.
The query language would need extension to handle link types, but the conceptual model is straightforward: links have properties, properties can be queried.
Bidirectional type inference
If A contradicts B, then B is contradicted-by A. The inverse relationship could be inferred automatically, just as backlinks are inferred now. This is how the 2020 thread discussed symmetric vs. asymmetric relationships.
Some relationships are symmetric: relates-to, co-occurs-with, conflicts-with (in some uses). If A relates to B, then B relates to A. The same link type applies in both directions.
Other relationships are asymmetric with named inverses: extends / extended-by, contradicts / contradicted-by, requires / required-by, causes / caused-by. The relationship type differs depending on which direction you’re looking from.
The system could understand these inverse pairs. When I create a contradicts link from A to B, the backlinks pane in B would show this as a contradicted-by link from A. The semantics would be preserved in both directions.
Link type vocabularies and schemas
Different domains use different relationship types. Fiction writing needs foreshadows, features, echoes. Technical documentation needs requires, implements, deprecates. Zettelkasten work needs contradicts, extends, synthesizes.
Link type vocabularies could be domain-specific. A vocabulary file could define the valid link types for a project, their inverses, whether they’re symmetric or asymmetric, and perhaps even their visual representation in the graph.
Combined with property inheritance, a project-level MOC could specify which link types are valid for its children. Notes in the fiction project would autocomplete fiction-relevant relationship types. Notes in the technical documentation would autocomplete technical relationship types. The system would guide users toward consistent vocabulary.
Block-to-block typed links
Combined with block-level properties, links could connect not just notes but specific blocks within notes. This paragraph contradicts that paragraph in another note. This section depends-on that section.
This matters because the unit of meaning is often smaller than a note. A long note might contain multiple claims, each with different relationships to other ideas. Currently, I can only link at the note level, which flattens the structure. Block references exist but don’t carry types.
With block-level typed links:
[[contradicts::Other Note#^block-id]]
This links to a specific block and specifies the relationship. The granularity matches how thinking actually works: specific claims relate to specific claims, not just documents to documents.
Transitive relationship tracking
Some relationships are transitive: if A requires B, and B requires C, then A transitively requires C. The system could compute transitive closures for relevant relationship types.
This matters for dependency analysis. If I update Component C, I need to know not just what directly requires C, but what transitively requires it through chains of dependencies. Currently, this requires manual traversal. With typed links and transitivity, it becomes a query:
LIST WHERE transitive-closure(file, "requires", [[Component C]])
What exists now
The current workarounds are inadequate:
Inline fields with link values – contradicts:: [[Note]] – work with Dataview but aren’t treated as first-class links. They don’t appear in the graph. They don’t generate proper backlinks. The backlink in the target note doesn’t know the relationship type. They’re properties that happen to contain links, not links that carry properties. The semantic information exists but isn’t integrated into core functionality.
Prose description – writing “This note contradicts [[Other Note]]” – preserves the semantics for human readers but not for queries or visualization. The relationship type is buried in natural language. I can’t filter for all contradiction relationships. I can’t visualize them in the graph. The structure is implicit in text, not explicit in data.
Tags on links – hacks like [[Note#:contradicts]] using the heading syntax – sort of work but feel like exploits rather than features. They abuse the heading-link syntax for an unintended purpose. They don’t integrate with the property system. They’re fragile to syntax changes. They’re not semantically meaningful to the system.
Frontmatter lists – putting links in typed property fields in the YAML, like contradicts: [[Note A]], [[Note B]] – works for some purposes but separates the link from its context in the note body. The relationship is declared at the top of the note rather than where it’s relevant in the text. This works for some use cases (listing all dependencies at the top of a component doc) but not for inline argumentation (noting a contradiction in the flow of writing).
Plugins – Breadcrumbs, Juggl, and others have explored this space. Breadcrumbs implements hierarchy relationships (parent, child, sibling) using properties. Juggl visualizes different link types with different edge styles. These are valuable explorations, but they’re building on top of a system that doesn’t natively support what they need. The solutions are partial, don’t integrate with core features like the graph and backlinks pane, and require plugin-specific workflows.
The 2024 thread asking “have we finally figured out semantic links?” received this reply: “In short; No. A link is still just a link, and you can’t automatically attach any information to the link itself.”
Four years of discussion, 177 votes on the original request, and this remains true.
The architectural argument
Obsidian’s power comes from treating notes as data. The introduction of properties was a significant step: notes became queryable, filterable, sortable by their metadata. But the property system stops at the note boundary – it doesn’t reach down into blocks or out into relationships.
The three features I’ve described – property inheritance, block-level properties, and typed links – are different expressions of the same architectural principle: metadata should be attachable wherever it’s meaningful. Notes are one unit of meaning, but not the only one. Blocks within notes carry meaning. Relationships between notes carry meaning. A complete property architecture would acknowledge all three.
This isn’t about adding complexity for its own sake. It’s about matching the tool’s capabilities to the structure of knowledge work.
Knowledge has internal structure – claims within arguments within notes. Properties that can only attach to notes miss this structure. Block-level properties recover it.
Knowledge has relational structure – ideas connect in typed ways, not just generic association. Links that can only say “connected” miss this structure. Typed links recover it.
Knowledge has hierarchical structure – individual notes inherit characteristics from their context, their categories, their containing projects. Properties that must be duplicated across notes miss this structure. Property inheritance recovers it.
A tool that can’t express these things forces its users to work around them. The workarounds exist – that’s what the plugins and hacks demonstrate. But workarounds are friction. They require extra effort, they don’t integrate cleanly, they break when the underlying system changes. Native support would make explicit what users are already trying to do implicitly.
A vision for the property system
Imagine Obsidian where:
- Properties attach at any level: note, block, or link
- Properties inherit from containing contexts: folders, tags, MOCs
- Properties on links specify relationship types
- The graph visualizes relationship types with edge colors, directions, and filtering
- Queries filter by relationship type just as they filter by note properties
- Backlinks show the relationship type from the linking note
- Vocabularies define valid link types for a project
- Transitive relationships can be computed across chains of typed links
This is the same property system Obsidian already has, extended consistently into the dimensions where it’s currently missing. The conceptual model doesn’t change – properties are key-value pairs attached to entities. What changes is which entities can have properties: not just notes, but blocks and links too.
Related requests
The original typed links thread: Add support for link types (2020, 177 votes)
Recent discussion on the state of semantic links: Have we finally figured out semantic links? (2024)