domains / documents / obsidian-bases-authoring / obsidian-bases
The copies overlap heavily on the .base YAML schema, filter syntax, property types, and formula examples, but each adds material steps or constraints the others lack. kepano/obsidian-skills provides the only explicit authoring workflow and validation checklist, including common YAML quoting and formula-reference errors. anbeime/skill and davepoon/buildwithclaude include a broader inline functions reference, while davepoon adds a 'When to Use' section. sickn33/agentic-awesome-skills adds complete worked examples and a limitations section, but delegates the detailed procedure to an external reference file. Crowning one copy would hide the workflow/validation steps in kepano, the broader function tables in the other two, and the examples/limitations in sickn33.
| Repository | Path |
|---|---|
| kepano/obsidian-skills | skills/obsidian-bases/SKILL.md |
| anbeime/skill | skills/obsidian-skills-integrated/obsidian-bases/SKILL.md |
| davepoon/buildwithclaude | plugins/all-skills/skills/obsidian-bases/SKILL.md |
| sickn33/agentic-awesome-skills | plugins/agentic-awesome-skills-claude/skills/obsidian-bases/SKILL.md |
| Role | Repository | Path |
|---|---|---|
| peer | kepano/obsidian-skills | skills/obsidian-bases/SKILL.md |
| peer | anbeime/skill | skills/obsidian-skills-integrated/obsidian-bases/SKILL.md |
| peer | davepoon/buildwithclaude | plugins/all-skills/skills/obsidian-bases/SKILL.md |
| peer | sickn33/agentic-awesome-skills | plugins/agentic-awesome-skills-claude/skills/obsidian-bases/SKILL.md |
| inferior | brycewang-stanford/Auto-Empirical-Research-Skills | skills/33-Galaxy-Dawn-claude-scholar/skills/obsidian-bases/SKILL.md |
| adapter | sickn33/agentic-awesome-skills | plugins/agentic-awesome-skills/skills/obsidian-bases/SKILL.md |
| adapter | sickn33/agentic-awesome-skills | skills/obsidian-bases/SKILL.md |
| adapter | davepoon/buildwithclaude | plugins/obsidian-skills/skills/obsidian-bases/SKILL.md |
---
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
## When to Use
- Creating database-like views of notes in Obsidian
- Building task trackers, reading lists, or project dashboards
- Filtering and organizing notes by properties or tags
- Creating calculated/formula fields
- Setting up table, card, list, or map views
- Working with .base files in an Obsidian vault
## 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 (by tag, folder, property, or date)
3. Add formulas (optional): Define computed properties in the formulas section
4. Configure views: Add one or more views (table, cards, list, or map) with order 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 quoting rules below
## File Format
Base files use the .base extension and contain valid YAML. They can also be embedded in Markdown code blocks.
## Complete Schema
```yaml
# Global filters apply to ALL views in the base
filters:
# Can be a single filter string
# OR a recursive filter object with and/or/not
and: []
or: []
not: []
# 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
and: []
order: # Properties to display in order
- file.name
- property_name
- formula.formula_name
summaries: # Map properties to summary formulas
property_name: Average
```
## Filter Syntax
Filters narrow down results. They can be applied globally or per-view.
### Filter Structure
```yaml
# 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
| Operator | Description |
|----------|-------------|
| == | equals |
| != | not equal |
| > | greater than |
| < | less than |
| >= | greater than or equal |
| <= | less than or equal |
| && | logical and |
| \|\| | logical or |
| ! | logical not |
## Properties
### Three Types of Properties
1. Note properties - From frontmatter: note.author or just author
2. File properties - File metadata: file.name, file.mtime, etc.
3. 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 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 compute values from properties. Defined in the formulas section.
```yaml
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, "")'
```
## Functions Reference
### Global Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| date() | date(string): date | Parse string to date. Format: YYYY-MM-DD HH:mm:ss |
| duration() | duration(string): duration | Parse duration string |
| now() | now(): date | Current date and time |
| today() | today(): date | Current date (time = 00:00:00) |
| if() | if(condition, trueResult, falseResult?) | Conditional |
| min() | min(n1, n2, ...): number | Smallest number |
| max() | max(n1, n2, ...): number | Largest number |
| number() | number(any): number | Convert to number |
| link() | link(path, display?): Link | Create a link |
| list() | list(element): List | Wrap in list if not already |
| file() | file(path): file | Get file object |
| image() | image(path): image | Create image for rendering |
| icon() | icon(name): icon | Lucide icon by name |
| html() | html(string): html | Render as HTML |
| escapeHTML() | escapeHTML(string): string | Escape HTML characters |
### Any Type Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| isTruthy() | any.isTruthy(): boolean | Coerce to boolean |
| isType() | any.isType(type): boolean | Check type |
| toString() | any.toString(): string | Convert to string |
## Complete Examples
### Task Tracker Base
```yaml
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
```yaml
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
```yaml
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
```
## 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.
## Conflicts
- davepoon/buildwithclaude uses a different days_old formula example: '((now() - file.ctime) / 86400000).round(0)' versus kepano/obsidian-skills and anbeime/skill using '(now() - file.ctime).days'.
- kepano/obsidian-skills references an external FUNCTIONS_REFERENCE.md for the complete function list; anbeime/skill and davepoon/buildwithclaude include a broader inline functions reference instead.
- sickn33/agentic-awesome-skills delegates the detailed procedure to references/detailed-guide.md and adds a limitations section; the other copies do not include this delegation or limitations block.