obsidian-dev-rules
Authoritative reference and rules for developing for Obsidian — building TypeScript plugins (Plugin lifecycle, manifest.json, commands, settings, modals, views, ribbon/status bar), the Vault and Editor APIs, the event system, Markdown post-processing & code-block processors, CodeMirror 6 editor extensions, building CSS themes (CSS variables, theme.css/manifest), and submitting plugins/themes to the community directory. Use whenever the user asks to build, debug, or review an Obsidian plugin or theme, work with the Obsidian API (Vault/Editor/Workspace/Plugin), register commands/views/events, process Markdown, or release/submit to the Obsidian community.
How do I install this agent skill?
npx skills add https://github.com/agents365-ai/365-skills --skill obsidian-dev-rulesIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill provides a safe and authoritative reference for developing Obsidian plugins and themes. It contains no malicious code, obfuscation, or unauthorized data access patterns, and focuses on educational rules and developer best practices.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Obsidian Dev Rules
Obsidian is extended two ways: plugins (TypeScript against the Obsidian API) and themes/snippets
(CSS). This skill mirrors the official developer docs at https://docs.obsidian.md so you can build and
review Obsidian plugins/themes without re-fetching. The API ships as the obsidian npm package; the
canonical starting point is the obsidian-sample-plugin.
When to use this skill
- Building, debugging, or reviewing an Obsidian plugin (lifecycle, commands, settings, UI, views).
- Reading/writing notes via the Vault API; manipulating the active note via the Editor API.
- Subscribing to events, registering Markdown post-processors / code-block processors, or CodeMirror 6 editor extensions.
- Building a theme (CSS variables,
theme.css, manifest) or snippets. - Releasing/submitting a plugin or theme to the community directory.
Reference index — load the file you need
| File | Covers |
|---|---|
references/plugin-basics.md | Project setup, manifest.json, Plugin lifecycle (onload/onunload), resource registration & cleanup, events, dev workflow / hot reload, debugging |
references/vault-and-editor.md | Vault API (read/cachedRead/create/modify/process/delete, TFile/TFolder, adapter, normalizePath), Editor API, Markdown post-processing & code-block processors, CodeMirror 6 editor extensions |
references/ui.md | Commands (callback variants, hotkeys), Settings (PluginSettingTab, load/saveData, Setting controls), Modals (Modal/SuggestModal/FuzzySuggestModal), Views (ItemView, registerView, workspace leaves), ribbon/status bar |
references/themes-and-release.md | Themes (CSS variables, theme.css/manifest, body classes, snippets), submitting plugins & themes, developer policies & guidelines |
Cheat sheet
import { Plugin, Notice, MarkdownView, TFile, normalizePath } from 'obsidian';
export default class MyPlugin extends Plugin {
async onload() {
await this.loadSettings();
this.addRibbonIcon('dice', 'Greet', () => new Notice('Hello!'));
this.addCommand({ id: 'do-x', name: 'Do X', callback: () => {/* ... */} });
this.addSettingTab(new MySettingTab(this.app, this));
// Auto-cleaned on unload — always register through these:
this.registerEvent(this.app.vault.on('modify', (f) => {/* ... */}));
this.registerInterval(window.setInterval(() => {/* ... */}, 1000));
this.registerDomEvent(document, 'click', () => {/* ... */});
}
onunload() { /* release anything NOT registered via register*/ }
}
// Vault: prefer process() over read()+modify(); use cachedRead() for display only.
const file = this.app.vault.getFileByPath('Notes/x.md');
await this.app.vault.process(file, (data) => data.replace('foo', 'bar'));
// Editor of the active note (preserves cursor/selection):
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
view?.editor.replaceSelection(view.editor.getSelection().toUpperCase());
Plugin files: manifest.json + main.js (+ optional styles.css) in <vault>/.obsidian/plugins/<id>/.
Theme files: manifest.json + theme.css in <vault>/.obsidian/themes/<name>/.
Hard rules
- Use
this.app, never the globalapp(global exists for debugging only and may be removed). - Register everything that needs teardown via
registerEvent/registerInterval/registerDomEvent/addCommand/registerView/registerMarkdownPostProcessor— Obsidian auto-cleans those on unload. Manually release anything else inonunload(). Leaked listeners/ intervals degrade Obsidian after the plugin is disabled. - Never use
innerHTML/outerHTML/insertAdjacentHTMLwith dynamic content — build DOM withcreateEl()/createDiv()/createSpan(). - Prefer the Vault API over the Adapter API; use
getFileByPath()(not iterate-all); alwaysnormalizePath()user-supplied paths. Useprocess()(atomic) instead of sequentialread()+modify()to avoid data loss;cachedRead()only when you won't write it back. - For the active note, edit via the Editor interface, not
Vault.modify— it preserves the cursor and selection. - Don't store references to view instances; Obsidian may recreate them — fetch with
getLeavesOfType()/getActiveViewOfType(). - Don't set default hotkeys for distributed plugins (OS-dependent, conflict-prone). UI text is sentence case. Use CSS classes + Obsidian CSS variables, not hardcoded inline styles.
manifest.jsonrequired fields:id,name,version(semverx.y.z),minAppVersion,description,author,isDesktopOnly.idmust not contain "obsidian";nameis Basic-Latin, no emoji/punctuation except hyphens.- Release: GitHub release whose tag equals the manifest
version, withmain.js,manifest.json, and optionalstyles.cssattached as individual binary assets (not zipped). - Use
async/await(not Promise chains);const/let(notvar).
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/agents365-ai/365-skills/obsidian-dev-rules">View obsidian-dev-rules on skillZs</a>