Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/kepano/obsidian-skills/llms.txt

Use this file to discover all available pages before exploring further.

The obsidian-bases skill teaches AI coding assistants to create and edit Obsidian Bases — .base files that provide database-like views over the notes in a vault. A base file is valid YAML that defines which notes to include (via filters), how to compute derived values (via formulas), and how to display results (via one or more views: table, cards, list, or map). Load this skill when the user mentions Bases, table views, card views, filters, or formulas in Obsidian, or when you need to create a .base file from scratch.

Workflow

1

Create the file

Create a .base file in the vault with valid YAML content.
2

Define scope

Add filters to select which notes appear — filter by tag, folder, property value, or date.
3

Add formulas

Optionally define computed properties in the formulas section for arithmetic, conditional logic, string formatting, or date math.
4

Configure views

Add one or more views (table, cards, list, or map) with an order list specifying which properties to display.
5

Validate

Verify the file is valid YAML with no syntax errors. Check that all referenced properties and formulas exist. Common issues: unquoted strings containing special YAML characters, mismatched quotes in formula expressions, referencing formula.X without defining X in formulas.
6

Test in Obsidian

Open the .base file in Obsidian to confirm the view renders correctly. If it shows a YAML error, check the quoting rules in the Troubleshooting section below.

Base File Schema

Base files use the .base extension and contain valid YAML. The top-level keys are filters, formulas, properties, summaries, and views.
# Global filters apply to ALL views in the base
filters:
  # Can be a single filter string
  # OR a recursive filter object with exactly ONE key: and, or, or not
  and:
    - 'status == "active"'
    - not:
        - 'file.hasTag("archived")'

# Define formula properties that can be used across all views
formulas:
  formula_name: 'expression'

# Configure display names and settings for properties
properties:
  property_name:
    displayName: "Display Name"
  formula.formula_name:
    displayName: "Formula Display Name"
  file.ext:
    displayName: "Extension"

# Define custom summary formulas
summaries:
  custom_summary_name: 'values.mean().round(3)'

# Define one or more views
views:
  - type: table | cards | list | map
    name: "View Name"
    limit: 10                    # Optional: limit results
    groupBy:                     # Optional: group results
      property: property_name
      direction: ASC | DESC
    filters:                     # View-specific filters follow the same rules
      and:
        - 'status == "active"'
    order:                       # Properties to display in order
      - file.name
      - property_name
      - formula.formula_name
    summaries:                   # Map properties to summary formulas
      property_name: Average
See /reference/bases-schema for the complete schema reference.

Filter Syntax

Filters narrow down which notes appear in the base. They can be applied globally (top-level filters) or per-view. A filter is either a single expression string or a recursive filter object with exactly one key: and, or, or not.
# Single filter
filters: 'status == "done"'

# AND - all conditions must be true
filters:
  and:
    - 'status == "done"'
    - 'priority > 3'

# OR - any condition can be true
filters:
  or:
    - 'file.hasTag("book")'
    - 'file.hasTag("article")'

# NOT - exclude matching items
filters:
  not:
    - 'file.hasTag("archived")'

# Nested filters
filters:
  or:
    - file.hasTag("tag")
    - and:
        - file.hasTag("book")
        - file.hasLink("Textbook")
    - not:
        - file.hasTag("book")
        - file.inFolder("Required Reading")

Filter Operators

OperatorDescription
==equals
!=not equal
>greater than
<less than
>=greater than or equal
<=less than or equal
&&logical and
||logical or
!logical not
See /reference/bases-filters for the complete filter reference.

Properties

There are three types of properties that can appear in a base view’s order list.
  1. Note properties — Values from a note’s frontmatter: note.author or just author
  2. File properties — File system metadata: file.name, file.mtime, etc.
  3. Formula properties — Computed values defined in formulas: formula.my_formula

File Properties Reference

PropertyTypeDescription
file.nameStringFile name
file.basenameStringFile name without extension
file.pathStringFull path to file
file.folderStringParent folder path
file.extStringFile extension
file.sizeNumberFile size in bytes
file.ctimeDateCreated time
file.mtimeDateModified time
file.tagsListAll tags in file
file.linksListInternal links in file
file.backlinksListFiles linking to this file
file.embedsListEmbeds in the note
file.propertiesObjectAll frontmatter properties

The this Keyword

The this keyword refers to a context-dependent file:
  • In main content area: refers to the base file itself
  • When embedded: refers to the embedding file
  • In sidebar: refers to the active file in main content

Formula Syntax

Formulas are defined in the formulas section and compute derived values from note or file properties. Reference them in views as formula.formula_name.
formulas:
  # Simple arithmetic
  total: "price * quantity"

  # Conditional logic
  status_icon: 'if(done, "✅", "⏳")'

  # String formatting
  formatted_price: 'if(price, price.toFixed(2) + " dollars")'

  # Date formatting
  created: 'file.ctime.format("YYYY-MM-DD")'

  # Calculate days since created (use .days for Duration)
  days_old: '(now() - file.ctime).days'

  # Calculate days until due date
  days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
When subtracting two dates, the result is a Duration type — not a number. Always access a numeric field like .days before applying number functions such as .round().
See /reference/bases-formulas for the complete formula reference.

Key Functions

FunctionSignatureDescription
date()date(string): dateParse string to date (YYYY-MM-DD HH:mm:ss)
now()now(): dateCurrent date and time
today()today(): dateCurrent date (time = 00:00:00)
if()if(condition, trueResult, falseResult?)Conditional
duration()duration(string): durationParse duration string
file()file(path): fileGet file object
link()link(path, display?): LinkCreate a link
See /reference/bases-functions for all types: Date, String, Number, List, File, Link, Object, RegExp.

View Types

The table view displays notes in rows with configurable columns. Supports summaries for column-level aggregations and groupBy for row grouping.
views:
  - type: table
    name: "My Table"
    order:
      - file.name
      - status
      - due_date
    summaries:
      price: Sum
      count: Average

Summary Formulas

Summaries aggregate a column’s values into a single result, displayed at the bottom of the column in a table view.
NameInput TypeDescription
AverageNumberMathematical mean
MinNumberSmallest number
MaxNumberLargest number
SumNumberSum of all numbers
RangeNumberMax - Min
MedianNumberMathematical median
StddevNumberStandard deviation
EarliestDateEarliest date
LatestDateLatest date
RangeDateLatest - Earliest
CheckedBooleanCount of true values
UncheckedBooleanCount of false values
EmptyAnyCount of empty values
FilledAnyCount of non-empty values
UniqueAnyCount of unique values

Complete Examples

Task Tracker

filters:
  and:
    - file.hasTag("task")
    - 'file.ext == "md"'

formulas:
  days_until_due: 'if(due, (date(due) - today()).days, "")'
  is_overdue: 'if(due, date(due) < today() && status != "done", false)'
  priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'

properties:
  status:
    displayName: Status
  formula.days_until_due:
    displayName: "Days Until Due"
  formula.priority_label:
    displayName: Priority

views:
  - type: table
    name: "Active Tasks"
    filters:
      and:
        - 'status != "done"'
    order:
      - file.name
      - status
      - formula.priority_label
      - due
      - formula.days_until_due
    groupBy:
      property: status
      direction: ASC
    summaries:
      formula.days_until_due: Average

  - type: table
    name: "Completed"
    filters:
      and:
        - 'status == "done"'
    order:
      - file.name
      - completed_date

Reading List

filters:
  or:
    - file.hasTag("book")
    - file.hasTag("article")

formulas:
  reading_time: 'if(pages, (pages * 2).toString() + " min", "")'
  status_icon: 'if(status == "reading", "📖", if(status == "done", "✅", "📚"))'
  year_read: 'if(finished_date, date(finished_date).year, "")'

properties:
  author:
    displayName: Author
  formula.status_icon:
    displayName: ""
  formula.reading_time:
    displayName: "Est. Time"

views:
  - type: cards
    name: "Library"
    order:
      - cover
      - file.name
      - author
      - formula.status_icon
    filters:
      not:
        - 'status == "dropped"'

  - type: table
    name: "Reading List"
    filters:
      and:
        - 'status == "to-read"'
    order:
      - file.name
      - author
      - pages
      - formula.reading_time

Daily Notes Index

filters:
  and:
    - file.inFolder("Daily Notes")
    - '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'

formulas:
  word_estimate: '(file.size / 5).round(0)'
  day_of_week: 'date(file.basename).format("dddd")'

properties:
  formula.day_of_week:
    displayName: "Day"
  formula.word_estimate:
    displayName: "~Words"

views:
  - type: table
    name: "Recent Notes"
    limit: 30
    order:
      - file.name
      - formula.day_of_week
      - formula.word_estimate
      - file.mtime

Embedding Bases

A .base file can be embedded inside any Markdown note using the standard embed syntax. You can embed the entire base or target a specific named view.
![[MyBase.base]]

![[MyBase.base#View Name]]

Troubleshooting

Unquoted special characters in YAML: Strings containing :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, or ` must be quoted.
# WRONG - colon in unquoted string
displayName: Status: Active

# CORRECT
displayName: "Status: Active"
Mismatched quotes in formulas: When a formula contains double quotes, wrap the entire formula in single quotes.
# WRONG - double quotes inside double quotes
formulas:
  label: "if(done, "Yes", "No")"

# CORRECT - single quotes wrapping double quotes
formulas:
  label: 'if(done, "Yes", "No")'
Duration math without field access: Subtracting two dates returns a Duration, not a number. Always access .days, .hours, etc. before calling number functions.
# WRONG - Duration is not a number
"(now() - file.ctime).round(0)"

# CORRECT - access .days first, then round
"(now() - file.ctime).days.round(0)"
Missing null checks: Properties may not exist on all notes. Use if() to guard against empty values.
# WRONG - crashes if due_date is empty
"(date(due_date) - today()).days"

# CORRECT - guard with if()
'if(due_date, (date(due_date) - today()).days, "")'
Referencing undefined formulas: Every formula.X used in order or properties must have a matching entry in the formulas block.
# This will fail silently if 'total' is not defined in formulas
order:
  - formula.total

# Fix: define it
formulas:
  total: "price * quantity"

Build docs developers (and LLMs) love