Skip to main content
The ref() function connects documents together. It fetches content from another document while registering a dependency edge in Colin’s compilation graph. Colin uses these dependency edges to compile documents in the correct order and rebuild only what changes.

Basic Usage

Call ref() with a document’s URI to get its compiled content:
models/product-brief.md
---
name: Product Brief
---

# About Us

{{ ref('company').content }}

# Our Products

{{ ref('products/main').content }}
When this document compiles, Colin ensures company and products/main compile first. The .content property contains each document’s full compiled output.

What ref() Returns

The ref() function returns a RefResult object, not a raw string. This object carries metadata alongside the content:
PropertyTypeDescription
contentstrThe compiled document output
namestrDocument name from frontmatter (or filename)
descriptionstr | NoneDescription from frontmatter
templatestrRaw source template before compilation
updateddatetimeWhen the document was last compiled
uristrThe document’s URI
sourceobject | NoneOriginal domain object (for provider resources)
Access these properties when you need more than just content:
models/index.md
---
name: Document Index
---

# Available Documents

{% for doc_uri in ['company', 'products/main', 'team/overview'] %}
{% set doc = ref(doc_uri) %}
## {{ doc.name }}

{{ doc.description or 'No description available.' }}

{% endfor %}

String Conversion

When you use a RefResult directly in a string context (like {{ ref('doc') }}), it returns a placeholder rather than the full content. This prevents accidentally dumping large documents:
{{ ref('company') }}
Outputs: Ref('company') Always use .content to get the actual content:
{{ ref('company').content }}

Dependency Registration

Every ref() call registers a dependency edge. Colin tracks these edges to:
  1. Order compilation - Referenced documents compile before their dependents
  2. Detect changes - When a document changes, Colin recompiles all dependents
  3. Build lineage - The manifest records the full dependency graph
Consider this chain:
company.md

product-brief.md (refs company)

sales-deck.md (refs product-brief)
If company.md changes, Colin recompiles all three. If only sales-deck.md changes, only it recompiles.

Using with Filters

Combine ref() with filters to transform referenced content:
models/summary.md
---
name: Executive Summary
---

# Key Points

{{ ref('full-report') | llm_extract('the 3 most important findings') }}
The extract() filter passes the RefResult through an LLM with your prompt. Since RefResult knows its content, the filter can access what it needs. Other useful patterns:
{# Extract specific information #}
{{ ref('customer-calls') | llm_extract('top customer complaints') }}

{# Chain multiple refs in an LLM block #}
{% llm %}
Compare these two analyses:

Analysis A: {{ ref('q1-report').content }}
Analysis B: {{ ref('q2-report').content }}

Identify trends and changes.
{% endllm %}

URI Resolution

URIs are relative paths from your models/ directory, without the .md extension:
FileURI to Reference
models/overview.mdref('overview')
models/team/leads.mdref('team/leads')
models/reports/2024/q1.mdref('reports/2024/q1')
Colin validates that referenced documents are compiled before they’re used. A reference to a document that hasn’t been compiled yet fails with a clear error:
RefNotCompiledError: ref('missing-doc') failed - document not compiled.
Add 'depends_on: [missing-doc]' to ensure compilation order,
or use ref('missing-doc', allow_stale=True) to accept stale/missing data.

Referencing Provider Objects

Beyond URI strings, ref() can also accept objects from providers like MCP. Provider functions return domain objects that can be passed directly to ref() for dependency tracking:
models/sources/project-data.md
---
name: Project Data
---

{# Fetch MCP resource and track it as a dependency #}
{{ ref(colin.mcp.linear.resource('projects?team=engineering')).content }}
This is equivalent to calling the provider function and having Colin track the dependency. The ref() function:
  1. Calls the object’s to_ref_result() method to convert it
  2. Records the dependency in the manifest
  3. Returns a standard RefResult

When to Use ref() with Provider Objects

Use ref() when you want Colin to track the resource as a dependency:
{# Tracked dependency - appears in refs_evaluated #}
{{ ref(colin.mcp.github.resource('repo://owner/repo/README.md')).content }}
Skip ref() when you just want the content without tracking:
{# Not tracked - just fetches the content #}
{{ colin.mcp.github.resource('repo://owner/repo/README.md').content }}

Accessing the Original Object

When you use ref() with a provider object, the original domain object is preserved in the .source property:
models/analysis.md
---
name: Resource Analysis
---

{% set resource = ref(colin.mcp.github.resource('repo://owner/repo/README.md')) %}

Content: {{ resource.content }}
Name: {{ resource.name }}

{# Access provider-specific fields via .source #}
URI: {{ resource.source.uri }}
The .source property is the escape hatch for accessing any custom fields the provider adds to its domain objects.