Create an Obsidian plugin from scratch with full project scaffolding.
Covers Plugin class, ribbon icons, commands, settings tab, esbuild config,
manifest.json, and building/testing. Use when starting a new plugin,
scaffolding a project, or learning the plugin lifecycle.
Trigger with "create obsidian plugin", "scaffold obsidian plugin",
"new obsidian plugin", "obsidian plugin from scratch".
Create an Obsidian plugin from scratch with full project scaffolding.
Covers Plugin class, ribbon icons, commands, settings tab, esbuild config,
manifest.json, and building/testing. Use when starting a new plugin,
scaffolding a project, or learning the plugin lifecycle.
Trigger with "create obsidian plugin", "scaffold obsidian plugin",
"new obsidian plugin", "obsidian plugin from scratch".
Designed for Claude Code, also compatible with Codex and OpenClaw
Obsidian Core Workflow A: Create a Plugin from Scratch
Overview
Build a complete Obsidian plugin from an empty directory. By the end you will have a
working plugin with a ribbon icon, command palette entries, a settings tab, and a
production esbuild build. Every file is shown in full -- no stubs.
Prerequisites
Node.js 18+ installed
Obsidian desktop app installed
A vault to test in (create a fresh vault at ~/ObsidianDev if needed)
set -euo pipefail
npm run build
# Output: main.js at project rootls -la main.js manifest.json
Step 6: Install into your vault and test
set -euo pipefail
VAULT="$HOME/ObsidianDev"
PLUGIN_ID="my-obsidian-plugin"# Create plugin directory in vaultmkdir -p "$VAULT/.obsidian/plugins/$PLUGIN_ID"# Copy build artifactscp main.js manifest.json "$VAULT/.obsidian/plugins/$PLUGIN_ID/"echo"Plugin installed. Open Obsidian, enable it in Settings > Community plugins."
In Obsidian:
Settings > Community plugins > Enable community plugins
Find "My Obsidian Plugin" in the list, toggle it on
Click the sparkles icon in the left ribbon
Open command palette (Ctrl/Cmd+P), search "Show greeting"
Open Settings > My Obsidian Plugin to change the greeting text
Output
A complete plugin directory containing:
manifest.json -- plugin metadata Obsidian reads
src/main.ts -- Plugin subclass with commands, ribbon icon, settings tab
esbuild.config.mjs -- bundler with watch mode support
main.js -- production build output
package.json + tsconfig.json -- standard Node/TS project files
Error Handling
Error
Cause
Fix
Cannot find module 'obsidian'
Missing dev dependency
npm install --save-dev obsidian
Plugin not in list
manifest.json missing or invalid
Verify id field matches folder name
Ribbon icon missing
Invalid icon name
Use a Lucide icon name (sparkles, file-text, search, etc.)
Settings not persisting
Forgot await this.saveData()
Always await saveData in onChange
editorCallback command greyed out
No active editor
Open a markdown note first
Build fails with external error
Forgot to externalize obsidian
Check external array in esbuild config
Examples
Minimal manifest.json for community submission:
{"id":"my-obsidian-plugin","name":"My Obsidian Plugin","version":"1.0.0","minAppVersion":"1.0.0","description":"Does one useful thing.","author":"Your Name","authorUrl":"https://github.com/yourname","isDesktopOnly":false}
Adding a hotkey-enabled command:
this.addCommand({
id: "toggle-sidebar",
name: "Toggle custom sidebar",
// Users can assign a hotkey in Settings > Hotkeyscallback: () =>this.toggleSidebar(),
});