| name | obsidian-bases |
| description | Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
|
Obsidian Bases Skill
Workflow
- Create the file: Create a
.base file in the vault with valid YAML content
- Define scope: Add
filters to select which notes appear (by tag, folder, property, or date)
- Add formulas (optional): Define computed properties in the
formulas section
- Configure views: Add one or more views (
table, cards, list, or map) with order specifying which properties to display
- 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
- Test in Obsidian: Open the
.base file in Obsidian to confirm the view renders correctly. If it shows a YAML error, check quoting rules below
Critical Gotchas
-
SIGPIPE hangs: Never pipe obsidian base:query output through head/tail directly. Use obsidian ... | cat | head or built-in view= filtering instead. See the obsidian-cli skill gotcha #12.
-
Duration syntax: Use duration("45 days") not dur("45d"). The dur() shorthand does not work in Base filter expressions.
-
Empty array filtering: Properties stored as empty YAML arrays ([]) are NOT matched by != "" or != null. Use length(property) > 0 to filter for non-empty arrays.
-
YAML quoting: Formulas with double quotes must be wrapped in single quotes: 'if(done, "Yes", "No")'. Strings with :, {, }, [, ] must be quoted.
-
Duration math: Subtracting dates returns Duration, not number. Always access .days, .hours, etc. before applying .round().
-
Null guards: Use if() to guard properties that may not exist: 'if(due_date, (date(due_date) - today()).days, "")'
Schema
Base files use the .base extension and contain valid YAML.
filters:
and: []
or: []
not: []
formulas:
formula_name: 'expression'
properties:
property_name:
displayName: "Display Name"
formula.formula_name:
displayName: "Formula Display Name"
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
sort:
- property: property_name
direction: ASC | DESC
summaries:
property_name: Average
Querying Bases via CLI
obsidian vault={{VAULT_NAME}} base:query path="02 Areas/Tasks.base" format=json
obsidian vault={{VAULT_NAME}} base:query path="02 Areas/Digests.base" view="Recent" format=json
obsidian vault={{VAULT_NAME}} base:views
Always include the .base extension in the path. Never pipe output through head/tail directly.
Filter Syntax
Filters narrow down results. They can be applied globally or per-view.
Filter Structure
filters: 'status == "done"'
filters:
and:
- 'status == "done"'
- 'priority > 3'
filters:
or:
- 'file.hasTag("book")'
- 'file.hasTag("article")'
filters:
not:
- 'file.hasTag("archived")'
filters:
or:
- file.hasTag("tag")
- and:
- file.hasTag("book")
- file.inFolder("Required Reading")
Filter Operators
| Operator | Description |
|---|
== | equals |
!= | not equal |
> | greater than |
< | less than |
>= | greater than or equal |
<= | less than or equal |
&& | logical and |
|| | logical or |
Common Filter Patterns
- file.inFolder("04 Data")
- type == "task"
- file.hasTag("project")
- period_end >= today() - duration("45 days")
- due <= today()
- length(follow_ups) > 0
- summary != ""
Properties
Three Types
- Note properties — From frontmatter:
author, status, due
- File properties — File metadata:
file.name, file.mtime, file.ctime, file.size, file.folder, file.tags
- Formula properties — Computed values:
formula.my_formula
The this Keyword
- In main content area: refers to the base file itself
- When embedded: refers to the embedding file (useful for daily notes with inline bases)
Formula Syntax
formulas:
status_icon: 'if(done, "Yes", "No")'
created: 'file.ctime.format("YYYY-MM-DD")'
days_old: '(now() - file.ctime).days'
days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
File: |
if(aliases, link(file, aliases), file)
Key Functions
| Function | Signature | Description |
|---|
date() | date(string): date | Parse string to date |
now() | now(): date | Current date and time |
today() | today(): date | Current date (time = 00:00:00) |
duration() | duration(string): duration | Parse duration (e.g., "45 days", "7d", "1M") |
if() | if(cond, true, false?) | Conditional |
link() | link(path, display?): Link | Create a link |
file() | file(path): file | Get file object |
length() | length(list): number | List/array length |
For the complete function reference (Date, String, Number, List, File, Link, Object, RegExp), see FUNCTIONS_REFERENCE.md.
Duration Type
When subtracting two dates, the result is a Duration (not a number).
Fields: .days, .hours, .minutes, .seconds, .milliseconds
"(date(due_date) - today()).days"
"(now() - file.ctime).days.round(0)"
"(now() - file.ctime).round(0)"
Date Arithmetic
"today() + duration(\"7d\")"
"today() - duration(\"45 days\")"
Default Summary Formulas
| Name | Input | Description |
|---|
Sum | Number | Sum of all |
Average | Number | Mean |
Min / Max | Number | Smallest / largest |
Median | Number | Median |
Earliest / Latest | Date | Date range |
Checked / Unchecked | Boolean | Count true/false |
Empty / Filled | Any | Count empty/non-empty |
Unique | Any | Count unique values |
Embedding Bases in Markdown
![[MyBase.base]]
<!-- Specific view -->
![[MyBase.base#View Name]]
Troubleshooting
YAML Errors
displayName: Status: Active
displayName: "Status: Active"
label: "if(done, "Yes", "No")"
label: 'if(done, "Yes", "No")'
Common Formula Errors
"(now() - file.ctime).round(0)"
"(now() - file.ctime).days.round(0)"
"(date(due_date) - today()).days"
'if(due_date, (date(due_date) - today()).days, "")'
order:
- formula.total
References