| name | obsidian-upgrade-migration |
| description | Migrate Obsidian plugins between API versions and handle breaking changes.
Use when upgrading to new Obsidian versions, handling API deprecations,
or migrating plugin code to new patterns.
Trigger with phrases like "obsidian upgrade", "obsidian migration",
"obsidian API changes", "update obsidian plugin".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Obsidian Upgrade Migration
Overview
Guide for migrating Obsidian plugins to new API versions and handling breaking changes.
Prerequisites
- Existing Obsidian plugin
- Understanding of current plugin code
- Access to Obsidian changelog
Common Migration Scenarios
API Version Changes
| From | To | Common Changes |
|---|
| 0.x | 1.0 | Event API, Settings API |
| 1.0 | 1.1 | Editor API (CodeMirror 6) |
| 1.1 | 1.2 | Canvas API, Properties |
| 1.2+ | 1.4+ | Link resolution, Metadata |
Instructions
Step 1: Check Current Compatibility
cat manifest.json | jq '.minAppVersion'
npm update obsidian
Step 2: Common Migration: CodeMirror 5 to 6
import { MarkdownView } from 'obsidian';
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
const cm5 = view.sourceMode.cmEditor;
import { MarkdownView, EditorView } from 'obsidian';
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
const editor = view.editor;
const cm6: EditorView = view.editor.cm;
Step 3: Settings Migration
interface PluginSettingsV1 {
option1: string;
option2: number;
}
interface PluginSettingsV2 {
option1: string;
option2: number;
option3: boolean;
settingsVersion: number;
}
const DEFAULT_SETTINGS_V2: PluginSettingsV2 = {
option1: 'default',
option2: 10,
option3: true,
settingsVersion: 2,
};
async loadSettings() {
const data = await this.loadData();
if (!data) {
this.settings = { ...DEFAULT_SETTINGS_V2 };
} else if (!data.settingsVersion || data.settingsVersion < 2) {
this.settings = this.migrateSettingsV1toV2(data);
.();
} {
. = .({}, , data);
}
}
(: ): {
.();
{
...v1Settings,
: .,
: ,
};
}
Step 4: Event API Migration
this.app.workspace.on('file-open', callback);
this.registerEvent(
this.app.workspace.on('file-open', callback)
);
const interval = setInterval(() => {}, 1000);
this.registerInterval(
window.setInterval(() => {}, 1000)
);
document.addEventListener('click', handler);
this.registerDomEvent(document, 'click', handler);
Step 5: Vault API Changes
this.app.vault.read(file, (content) => {
});
const content = await this.app.vault.read(file);
const file = this.app.vault.getAbstractFileByPath(path);
const file = this.app.vault.getAbstractFileByPath(path);
if (file instanceof TFile) {
}
const cache = this.app.metadataCache.getFileCache(file);
const frontmatter = cache?.frontmatter;
Step 6: Editor API Migration
const sourceView = view.sourceMode;
const editor = view.editor;
const selection = cm5.getSelection();
const selection = editor.getSelection();
cm5.replaceSelection(text);
editor.replaceSelection(text);
const cursor = cm5.getCursor();
const cursor = editor.getCursor();
cm5.setCursor(line, ch);
editor.setCursor({ line, ch });
Step 7: Update Dependencies
npm install obsidian@latest --save-dev
npm update esbuild typescript
npx tsc --noEmit 2>&1 | grep -i deprecat
{
"minAppVersion": "1.4.0"
}
{
"1.0.0": "0.15.0",
"2.0.0": "1.4.0" // New version requires Obsidian 1.4+
}
Output
- Updated plugin code for new API version
- Migrated settings with version tracking
- Replaced deprecated event patterns
- Updated editor API calls
- Updated manifest and versions.json
Error Handling
| Error | Cause | Solution |
|---|
| Property not found | API removed | Check changelog for replacement |
| Type errors | Type definitions changed | Update obsidian package |
| Runtime errors | API behavior changed | Add version checks |
| Settings lost | Migration not implemented | Add migration logic |
Examples
Version-Specific Code
function supportsNewFeature(): boolean {
const version = this.app.version;
const [major, minor] = version.split('.').map(Number);
return major >= 1 && minor >= 4;
}
if (supportsNewFeature()) {
await this.app.fileManager.processFrontMatter(file, (fm) => {
fm['key'] = 'value';
});
} else {
const content = await this.app.vault.read(file);
}
Gradual Deprecation
function getEditor(view: MarkdownView): Editor {
if (view.editor) {
return view.editor;
}
if (view.sourceMode?.cmEditor) {
console.warn('Using deprecated CM5 editor access');
return wrapCM5Editor(view.sourceMode.cmEditor);
}
throw new Error('Could not get editor');
}
Resources
Next Steps
For CI/CD setup, see obsidian-ci-integration.