obsidian

yankeeinlondon's avatarfrom yankeeinlondon

Expert knowledge for developing Obsidian plugins and themes using TypeScript, CodeMirror 6, and CSS variables - covers plugin lifecycle, Vault API, Workspace API, editor extensions, and styling patterns

⭐1stars🔀0forks📁View on GitHub🕐Updated Dec 22, 2025

When & Why to Use This Skill

This Claude skill acts as a specialized technical consultant for Obsidian plugin and theme development. It provides expert-level guidance on using TypeScript, CodeMirror 6, and CSS variables, focusing on the Obsidian API (Vault, Workspace, and FileManager) to build high-performance, secure, and mobile-compatible extensions for the Obsidian ecosystem.

Use Cases

  • Plugin Architecture Design: Scaffolding robust plugins by correctly implementing the lifecycle methods (onload/onunload) and registering events for automatic cleanup.
  • Advanced Editor Customization: Developing sophisticated editor extensions using CodeMirror 6 state, view plugins, and decorations to enhance the markdown writing experience.
  • File System Operations: Utilizing the Vault API and FileManager to safely perform file operations and manipulate frontmatter metadata without bypassing Obsidian's internal safety checks.
  • Theme and UI Styling: Creating visually consistent themes and UI components by leveraging Obsidian's native CSS variables and ensuring compatibility across desktop and mobile platforms.
  • API Integration and Debugging: Troubleshooting complex interactions with the Workspace API, such as managing leaf views, handling layout changes, and integrating with the Canvas or Bases API.
nameobsidian
descriptionExpert knowledge for developing Obsidian plugins and themes using TypeScript, CodeMirror 6, and CSS variables - covers plugin lifecycle, Vault API, Workspace API, editor extensions, and styling patterns
hash881a7930a553c0d8

Obsidian Plugin & Theme Development

Build plugins and themes for Obsidian using TypeScript, CodeMirror 6, and CSS variables.

Core Principles

  • Extend Plugin class - Use onload() for setup, onunload() for cleanup
  • Access app via this.app - Never use global window.app (debugging only)
  • Prefer Vault API - Use this.app.vault over raw Adapter for file ops
  • Wait for layout ready - Use app.workspace.onLayoutReady() for startup logic
  • Register events properly - Use this.registerEvent() for auto-cleanup
  • Mark external CM6 deps - Never bundle @codemirror/*, use Obsidian's copy
  • Use CSS variables - Override theme variables, not hardcoded colors
  • Avoid !important - Let users override with snippets
  • Mobile compatibility - Check Platform.isMobile before Node.js APIs
  • Security first - Never use innerHTML with user input

Quick Reference

// Basic plugin structure
import { Plugin, Notice } from 'obsidian';

export default class MyPlugin extends Plugin {
  async onload() {
    // Add command
    this.addCommand({
      id: 'my-command',
      name: 'My Command',
      callback: () => new Notice('Hello!')
    });

    // Add ribbon icon
    this.addRibbonIcon('dice', 'My Plugin', () => {});

    // Register events (auto-cleanup on unload)
    this.registerEvent(
      this.app.vault.on('modify', (file) => {})
    );

    // Register CM6 extension
    this.registerEditorExtension(myExtension);
  }
}

Topics

Plugin Development

Editor Integration

Styling

  • Themes & CSS - CSS variables, theme structure, styling patterns

Advanced APIs

Common Patterns

Wait for Vault Ready

async onload() {
  this.app.workspace.onLayoutReady(() => {
    // Safe to access vault files here
    const files = this.app.vault.getMarkdownFiles();
  });
}

Process Frontmatter Safely

await this.app.fileManager.processFrontMatter(file, (fm) => {
  fm.status = 'done';
});

Register Editor Extension

import { ViewPlugin, DecorationSet } from '@codemirror/view';

const myPlugin = ViewPlugin.fromClass(class {
  decorations: DecorationSet;
  // ... implementation
}, { decorations: v => v.decorations });

this.registerEditorExtension(myPlugin);

Resources