obsidian
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
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.
| name | obsidian |
|---|---|
| description | 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 |
| hash | 881a7930a553c0d8 |
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 globalwindow.app(debugging only) - Prefer Vault API - Use
this.app.vaultover rawAdapterfor 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.isMobilebefore Node.js APIs - Security first - Never use
innerHTMLwith 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
- Plugin Development - Lifecycle, API, commands, settings, events
Editor Integration
- CodeMirror 6 - State, view, decorations, extensions
Styling
- Themes & CSS - CSS variables, theme structure, styling patterns
Advanced APIs
- Bases API - Custom database views (Obsidian 1.10+)
- Canvas API - Visual canvas manipulation
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);