When to Use
- Use when creating or editing
.basefiles in an Obsidian vault. - Use for database-like note views with filters, formulas, summaries, or cards/tables.
- Use when the user asks about Obsidian Bases specifically, or mentions
.basefiles, table views, card views, list views, map views, filters, or formulas. - Use when the user wants to embed a Base in a Markdown note (
![[MyBase.base]]).
Prerequisites
- Obsidian installed with Bases support (Obsidian 1.9+ or a build that includes the Bases feature).
- The target vault must be open and accessible on the Windows host (PowerShell).
- For map views, the Maps community plugin must be installed and latitude/longitude properties must exist on the target notes.
Procedure
1. Create the .base file
Create a .base file in the vault using valid YAML. On Windows (PowerShell):
New-Item -Path "C:\path\to\vault\MyBase.base" -ItemType File -Force
Then write YAML content into the file. The entire file must be valid YAML.
2. Define global filters
Add a top-level filters key to select which notes appear across ALL views. Filters can be a single string or a recursive object with and / or / not.
# Single filter string
filters: 'status == "done"'
# Recursive object
filters:
and:
- 'status == "done"'
- 'priority > 3'
or:
- 'file.hasTag("book")'
- 'file.hasTag("article")'
not:
- 'file.hasTag("archived")'
3. Define formulas (optional)
Add a formulas section to compute values from properties. Formula expressions are strings.
formulas:
total: "price * quantity"
status_icon: 'if(done, "✅", "⏳")'
days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
4. Configure property display names (optional)
Use the properties section to set displayName for note properties, file properties, or formula properties.
properties:
status:
displayName: "Status"
formula.days_until_due:
displayName: "Days Until Due"
file.ext:
displayName: "Extension"
5. Define custom summaries (optional)
summaries:
custom_summary_name: 'values.mean().round(3)'
6. Configure views
Add one or more views under views. Each view has a type (table, cards, list, or map), a name, and an order list specifying which properties to display.
views:
- type: table
name: "My Table"
limit: 10
groupBy:
property: status
direction: ASC
filters:
and:
- 'status != "done"'
order:
- file.name
- status
- due_date
- formula.days_until_due
summaries:
price: Sum
formula.days_until_due: Average
7. Validate the YAML
Verify the file is valid YAML with no syntax errors. Check that:
- All referenced
formula.Xentries inorderorpropertieshave a matching definition informulas. - All strings containing special YAML characters (
:,{,},[,],,,&,*,#,?,|,-,<,>,=,!,%,@,`) are quoted. - Formulas containing double quotes are wrapped in single quotes.
On Windows (PowerShell), you can do a quick YAML lint if Python is available:
python -c "import yaml,sys; yaml.safe_load(open(r'C:\path\to\vault\MyBase.base',encoding='utf-8')); print('YAML OK')"
8. Test in Obsidian
Open the .base file in Obsidian to confirm the view renders correctly. If Obsidian shows a YAML error, re-check quoting rules and formula syntax.
Schema Reference
filters:
and: []
or: []
not: []
formulas:
formula_name: 'expression'
properties:
property_name:
displayName: "Display Name"
formula.formula_name:
displayName: "Formula Display Name"
file.ext:
displayName: "Extension"
summaries:
custom_summary_name: 'values.mean().round(3)'
views:
- type: table | cards | list | map
name: "View Name"
limit: 10
groupBy:
property: property_name
direction: ASC | DESC
filters:
and: []
order:
- file.name
- property_name
- formula.formula_name
summaries:
property_name: Average
Filter Operators
| Operator | Description |
|---|---|
== |
equals |
!= |
not equal |
> |
greater than |
< |
less than |
>= |
greater than or equal |
<= |
less than or equal |
&& |
logical and |
|| |
logical or |
! |
logical not |
Property Types
- Note properties — From frontmatter:
note.authoror justauthor. - File properties — File metadata:
file.name,file.mtime, etc. - Formula properties — Computed values:
formula.my_formula.
File Properties Reference
| Property | Type | Description |
|---|---|---|
file.name |
String | File name |
file.basename |
String | File name without extension |
file.path |
String | Full path to file |
file.folder |
String | Parent folder path |
file.ext |
String | File extension |
file.size |
Number | File size in bytes |
file.ctime |
Date | Created time |
file.mtime |
Date | Modified time |
file.tags |
List | All tags in file |
file.links |
List | Internal links in file |
file.backlinks |
List | Files linking to this file |
file.embeds |
List | Embeds in the note |
file.properties |
Object | All frontmatter properties |
The this Keyword
- In the main content area: refers to the base file itself.
- When embedded: refers to the embedding file.
- In the sidebar: refers to the active file in main content.
Key Functions
Most commonly used functions. Load references/FUNCTIONS_REFERENCE.md when you need the complete reference for all types (Date, String, Number, List, File, Link, Object, RegExp).
| Function | Signature | Description |
|---|---|---|
date() |
date(string): date |
Parse string to date (YYYY-MM-DD HH:mm:ss) |
now() |
now(): date |
Current date and time |
today() |
today(): date |
Current date (time = 00:00:00) |
if() |
if(condition, trueResult, falseResult?) |
Conditional |
duration() |
duration(string): duration |
Parse duration string |
file() |
file(path): file |
Get file object |
link() |
link(path, display?): Link |
Create a link |
Duration Type
When subtracting two dates, the result is a Duration type (not a number).
Duration Fields: duration.days, duration.hours, duration.minutes, duration.seconds, duration.milliseconds
HARD RULE: Duration does NOT support .round(), .floor(), .ceil() directly. Access a numeric field first (like .days), then apply number functions.
# CORRECT
"(date(due_date) - today()).days"
"(now() - file.ctime).days"
"(date(due_date) - today()).days.round(0)"
# WRONG — will cause error
# "((date(due) - today()) / 86400000).round(0)"
# "(now() - file.ctime).round(0)"
Date Arithmetic
Duration units: y/year/years, M/month/months, d/day/days, w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds.
"now() + \"1 day\""
"today() + \"7d\""
"now() - file.ctime"
"(now() - file.ctime).days"
Default Summary Formulas
| Name | Input Type | Description |
|---|---|---|
Average |
Number | Mathematical mean |
Min |
Number | Smallest number |
Max |
Number | Largest number |
Sum |
Number | Sum of all numbers |
Range |
Number | Max - Min |
Median |
Number | Mathematical median |
Stddev |
Number | Standard deviation |
Earliest |
Date | Earliest date |
Latest |
Date | Latest date |
Range |
Date | Latest - Earliest |
Checked |
Boolean | Count of true values |
Unchecked |
Boolean | Count of false values |
Empty |
Any | Count of empty values |
Filled |
Any | Count of non-empty values |
Unique |
Any | Count of unique values |
Examples
Task Tracker Base
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 Base
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 in Markdown
![[MyBase.base]]
<!-- Specific view -->
![[MyBase.base#View Name]]
Pitfalls
YAML Syntax Errors
Unquoted special characters: Strings containing :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, ` 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")'
Common Formula Errors
Duration math without field access: Subtracting 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.
# 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: Ensure every formula.X in order or properties has a matching entry in formulas. Undefined formula references fail silently.
# This will fail silently if 'total' is not defined in formulas
order:
- formula.total
# Fix: define it
formulas:
total: "price * quantity"
Verification
- YAML validity — Run a YAML parse check (if Python is available):
python -c "import yaml; yaml.safe_load(open(r'C:\path\to\vault\MyBase.base',encoding='utf-8')); print('YAML OK')"
Expected output: YAML OK
Formula references — Confirm every
formula.Xreferenced inorder,properties, orsummarieshas a matching key in theformulassection.Render check — Open the
.basefile in Obsidian. The view should render without a YAML error banner. If an error appears, check quoting rules and formula syntax.Embed check — Embed the base in a Markdown note with
![[MyBase.base]]and confirm the view appears inline.
References
- Bases Syntax
- Functions
- Views
- Formulas
- Load
references/FUNCTIONS_REFERENCE.mdwhen you need the complete function reference for all types (Date, String, Number, List, File, Link, Object, RegExp).
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.