Skip to content

Create Plugin

DevAll’s plugin system lets you extend functionality by hooking into process events, analyzing logs, and controlling services.

A plugin is a JavaScript file that exports an object:

my-plugin.js
export default {
name: "my-plugin",
version: "1.0.0",
meta: {
description: "What this plugin does",
author: "Your Name",
},
// Called when plugin loads
async init(context) {
console.log("Plugin initialized");
},
// Event hooks
hooks: {
"log:error": async (service, errorMessage, context) => {
// React to error logs
console.log(`Error in ${service.name}:`, errorMessage);
},
"process:start": async (service, context) => {
// React to service start
console.log(`${service.name} started`);
},
},
// Called when plugin stops
async stop() {
console.log("Plugin cleanup");
},
};

Plugins can hook into these events:

  • process:start - Service starts
  • process:stop - Service stops
  • process:crash - Service crashes
  • log:output - stdout output
  • log:error - stderr output

The context object provides access to DevAll APIs:

const context = {
config: {...}, // Project configuration
logger: {...}, // Logger instance
broadcast: (data), // WebSocket broadcast
// Process control
processes: {
start: (serviceId) => Promise,
stop: (serviceId) => Promise,
restart: (serviceId) => Promise,
getStatus: (serviceId) => string,
getAll: () => Array,
},
// File system
fs: {
read: (path) => Promise<string>,
write: (path, content) => Promise<void>,
},
// Plugin storage
storage: {
get: (key) => any,
set: (key, value) => void,
delete: (key) => void,
},
};

Send desktop notifications when services crash:

notify-plugin.js
export default {
name: "notifications",
version: "1.0.0",
hooks: {
"process:crash": async (service, error, context) => {
const { spawn } = await import("child_process");
// macOS notification
spawn("osascript", [
"-e",
`display notification "Service ${service.name} crashed" with title "DevAll"`,
]);
context.logger.log(service.id, "🔔 Crash notification sent", "info");
},
},
};

Add plugins to your devall.yaml:

plugins:
# From npm package
- name: devall-plugin-playwright
enabled: true
options:
autoRun: false
# From local file
- name: ./plugins/my-plugin.js
enabled: true

Plugins are loaded from:

  1. NPM packages - Any package name
  2. Local path - Relative or absolute file paths
  3. Project plugins - ./devall-plugins/ directory
  4. Global plugins - ~/.devall/plugins/ directory

DevAll includes core plugins that load automatically:

  • AutoInstall - Automatically installs missing npm packages

View the source at plugins/autoinstall/index.js to see a real-world example.

Run tests when files change:

export default {
name: "test-runner",
version: "1.0.0",
options: {
autoRun: false,
},
hooks: {
"log:output": async (service, line, context) => {
// Detect test file changes
if (line.includes(".test.") && this.options.autoRun) {
context.logger.log(service.id, "🧪 Running tests...", "info");
const { spawn } = await import("child_process");
spawn("npm", ["test"], {
cwd: service.cwd,
stdio: "inherit",
});
}
},
},
};

Create an npm package:

{
"name": "devall-plugin-myplugin",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"keywords": ["devall", "plugin"]
}

Then publish:

Terminal window
npm publish

Users can install with:

plugins:
- name: devall-plugin-myplugin
enabled: true
  • ✅ Keep hooks lightweight and non-blocking
  • ✅ Handle errors gracefully with try-catch
  • ✅ Use descriptive plugin names
  • ✅ Implement stop() for cleanup
  • ❌ Don’t modify global state
  • ❌ Don’t run CPU-intensive operations in hooks