Overview of Inkdown’s plugin architecture, capabilities, lifecycle, and API
Inkdown features a powerful plugin system that allows developers to extend functionality, customize behavior, and integrate with external services. Plugins are first-class citizens in the architecture, with access to the same APIs used by built-in features.
Plugins in Inkdown are built on a foundation of platform-agnostic APIs, ensuring that plugins work seamlessly across Desktop, Web, and Mobile platforms without modification.
Called when the plugin is being disabled or unloaded. Handle custom cleanup here:
Close open dialogs
Cancel pending operations
Save final state
async onunload(): Promise<void> { // Save any pending data await this.savePendingChanges(); // Close custom UI this.closeCustomDialogs();}
Commands, event listeners, status bar items, and other resources registered through plugin methods are automatically cleaned up. You only need to handle custom cleanup.
_cleanup() (Internal)
Automatically called by the plugin manager to clean up registered resources:
The PluginManager handles plugin registration, loading, and lifecycle:
// Check if a plugin is enabledif (app.pluginManager.isPluginEnabled('live-preview')) { // Do something}// Enable a pluginawait app.pluginManager.enablePlugin('word-count');// Disable a pluginawait app.pluginManager.disablePlugin('word-count');// Get all pluginsconst allPlugins = app.pluginManager.getAllPlugins();// Get plugin instanceconst plugin = app.pluginManager.getPlugin('live-preview');// Listen for plugin changesapp.pluginManager.onPluginChange((pluginId, changeType) => { console.log(`Plugin ${pluginId} was ${changeType}`);});
Plugins remain platform-agnostic by using bridge patterns:
import { native } from '@inkdown/core';// Access file system (works on Desktop, Web, Mobile)const content = await native.fs.readFile('/path/to/file.md');// Show dialog (if platform supports it)if (native.dialog) { const result = await native.dialog.showSaveDialog({ defaultPath: 'export.md' });}// Check platform capabilitiesif (native.supports('nativeDialog')) { // Use native dialog} else { // Use fallback dialog}
Avoid using platform-specific APIs directly (like window, document, or Tauri APIs) in plugin code. Always use the provided bridge APIs for maximum compatibility.
Community plugins are installed from GitHub repositories:
// Install a community pluginawait app.communityPluginManager.installPlugin( 'username/repo-name');// Update a pluginawait app.communityPluginManager.updatePlugin('plugin-id');// Uninstall a pluginawait app.communityPluginManager.uninstallPlugin('plugin-id');
Community plugins are loaded dynamically and have the same capabilities as built-in plugins.