Plugin structure
This page describes where the plugins are stored, how are they structured, and how they work.
#Location
Plugins are stored in each app's {appData}/plugins
directory. Comfy list of all paths used by Drovp and their exact locations for your installation (along with Open folder buttons) is available in app's About page.
Here are some generic locations for each system:
OS | Path |
---|---|
Windows | C:\Users\{USERNAME}\AppData\Roaming\Drovp\plugins |
Windows Portable | {DROVP_DIRECTORY}\userData\plugins |
Linux | ~/.config/Drovp/plugins |
macOS | ~/Library/Application Support/Drovp/plugins |
#Installed plugins
All plugins installed from registry are stored inside the node_modules
directory, and Drovp keeps track of them with package.json
file. Unless you know what you're doing, don't touch these.
#Local plugins
Local development plugins are node modules, each in their own folder in the root of the plugins directory.
Note: You can't install 2 modules with the same package.json:name
. In other words, you can't have your plugin both installed from registry, and also loaded as a local development version, as they would overwrite each other's extensions. In this case, Drovp will load the local plugin, ignore the installed one, and display a warning about it.
#Example directory tree
{appData}/plugins/
├ foo/ // local development plugin
│ ├ index.js
│ ├ package.json
│ └ processor.js
├ node_modules/ // stuff installed and managed by drovp
└ package.json // record of installed stuff
#Module structure
For node module to become a valid Drovp plugin it has to fulfill these requirements:
- Name prefixed with
drovp-
.* - Has to have
drovpplugin
ordrovpdependency
inpackge.json:keywords
array.- Using
drovpdependency
instead ofdrovpplugin
makes the module be recognized and loaded by Drovp, but it'll not show up in registry searches. This is for plugins that are only meant to provide dependencies to other plugins, and not be installed by users directly. Example:@drovp/ffmpeg
.
- Using
- Use CommonJS module exports. The ESModule (
import from
) syntax is not supported yet (drovp/drovp#2).
If this module is published to npm, it'll be discoverable and installable in the app's Registry section, as well as this website's Plugins page.
- If you don't prefix your plugin names with
drovp-
they'll still be installable, but there will be a warning icon next to the name, as breaking this convention is sketchy because it might be used to impersonate other plugins. If you're publishing your plugin under an@org
, you still have to use the prefix in the name portion, like this:@org/drovp-plugin-name
.
#Node environments and caveats
Main and processor files are executed in different environments with different things to look out for.
#Main file
The main plugin file (package.json:main
) is the module responsible for extending Drovp, and is loaded inside the Electron's renderer process.
Current Electron version: 15.3.3
This also comes with a pretty big limitation that it has to be a CommonJS module, and CAN'T even use dynamic import()
calls to load pure ES modules. This limitation is due to Electron being quite behind the curve regarding node ES modules. The import()
we have access to in the renderer process is the basic front-end browser version of the import()
that can't resolve node module identifiers. This will hopefully get resolved soon (you can track the progress here: drovp/drovp#2).
Alternatively, you can write your code as ES modules, and use a bundler such as esbuild to bundle the whole main file and its dependencies into a single file, just don't forget to set the native modules such as fs
as external, so that esbuild leaves require calls for them.
Example:
// package.json:main file
module.exports = (plugin) => {
plugin.registerProcessor('name', {
main: 'processor.js',
...
});
};
#Processor files
The processor.js
from the example above will then run in its own raw Node.js process, which is spun and reused depending on processor's and app's configuration.
Processor files CAN be ES modules, or use import()
calls to load ESM only npm modules.
If the processor requires a min Node.js version to be used, declare it in package.json:engines
(details below) and Drovp will ensure it's satisfied before using the processor.
#package.json
config
Below is a list of all package.json
properties that Drovp looks for and is utilizing in some way.
#engines.node
While main plugin file will always run in Drovp's Electron renderer thread, engines.node
can be used to require a min Node.js version the plugin's processor(s) need to function properly. Drovp will then make sure it's installed before processor can be used.
All processors use the same Node.js binary, so the only possible change is update to the newest, thus max limits are not allowed/supported.
Example:
{
"engines": {
"node": ">=14"
}
}
#os
Plugins should support all systems, but in cases that's not possible or doesn't make sense, you can use this to limit which operating systems your plugin is allowed to run on. The plugin will still be installable on all systems, as npm's registry search API doesn't share manifest properties in results so Drovp can't see this before installation, but it will at least prevent the plugin to be used on an unsupported platform with an appropriate explanation.
os
is an array of platform keywords:
Platform | Keyword |
---|---|
Windows | win32 |
Linux | linux |
macOS | darwin |
Examples:
{
"os": ["darwin", "linux"]
}
Only macOS and linux.
{
"os": ["!win32"]
}
Same as above.
#cpu
Tells Drovp that plugin's processor(s) will only run on specific CPUs.
Possible values: arm
, arm64
, ia32
, mips
,mipsel
, ppc
, ppc64
, s390
, s390x
, x32
, x64
Drovp is currently only built for x64
, so this is at the moment quite redundant.
#drovp.origin
Informs the app of the intended install origin for your local external plugins (plugins you're developing that will not be published to npm), as the app has no other way of knowing. If someone installs your plugin, the origin is inferred from the origin used to install the package, but that is not available for in-development plugins.
The only purpose of this is for the developers to be able to generate profile import codes with correct install origin for external plugins they're working on.
Valid origins are: <git-host>:<git-user>/<repo-name>
, <git repo url>
, <tarball url>
Supported git host shorthands are: github
, gitlab
, bitbucket
Example:
{
"drovp": {
"origin": "github:account/repo"
}
}