domains / documents / obsidian-bases-authoring / obsidian-bases

obsidian-bases

Skill card

combined

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.

Repositories

RepositoryPath
kepano/obsidian-skillsskills/obsidian-bases/SKILL.md
anbeime/skillskills/obsidian-skills-integrated/obsidian-bases/SKILL.md
davepoon/buildwithclaudeplugins/all-skills/skills/obsidian-bases/SKILL.md
sickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/obsidian-bases/SKILL.md

Other copies

RoleRepositoryPath
peerkepano/obsidian-skillsskills/obsidian-bases/SKILL.md
peeranbeime/skillskills/obsidian-skills-integrated/obsidian-bases/SKILL.md
peerdavepoon/buildwithclaudeplugins/all-skills/skills/obsidian-bases/SKILL.md
peersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/obsidian-bases/SKILL.md
inferiorbrycewang-stanford/Auto-Empirical-Research-Skillsskills/33-Galaxy-Dawn-claude-scholar/skills/obsidian-bases/SKILL.md
adaptersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills/skills/obsidian-bases/SKILL.md
adaptersickn33/agentic-awesome-skillsskills/obsidian-bases/SKILL.md
adapterdavepoon/buildwithclaudeplugins/obsidian-skills/skills/obsidian-bases/SKILL.md

Combined skill

---
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.