
Security News
Feross on TBPN: How North Korea Hijacked Axios
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.
@libria/plugin-loader
Advanced tools
A simple, type-safe plugin loader for Node.js applications. Supports both ESM and CommonJS plugins with glob pattern discovery.
npm install @libria/plugin-loader
Create a plugin.json manifest in your plugin directory:
{
"name": "my-plugin",
"pluginType": "greeting",
"module": "./dist/index.mjs"
}
Create the plugin module:
// src/index.ts
import { definePlugin } from '@libria/plugin-loader';
export default definePlugin('greeting', {
sayHello(name: string) {
return `Hello, ${name}!`;
}
});
import { findPlugins, loadPlugin, loadAllPlugins } from '@libria/plugin-loader';
// Load all plugins from a directory
const plugins = await loadAllPlugins('./plugins', 'greeting');
for (const plugin of plugins) {
console.log(plugin.api.sayHello('World'));
}
definePlugin<T>(pluginType, api, name?)Helper function to create a type-safe plugin export.
import { definePlugin } from '@libria/plugin-loader';
export default definePlugin('my-type', {
myMethod() {
return 'Hello!';
}
});
findPlugins(pattern, pluginType?)Discovers plugins by scanning directories for plugin.json manifests.
import { findPlugins } from '@libria/plugin-loader';
// Simple directory path (scans one level deep)
const manifests = await findPlugins('./plugins');
// Glob pattern
const manifests = await findPlugins('./plugins/*-plugin');
// Recursive glob
const manifests = await findPlugins('./plugins/**/dist');
// Filter by plugin type
const manifests = await findPlugins('./plugins', 'greeting');
loadPlugin<T>(manifest)Loads a single plugin from its manifest. Supports both ESM (module) and CommonJS (main) entry points.
import { findPlugins, loadPlugin } from '@libria/plugin-loader';
const [manifest] = await findPlugins('./plugins/my-plugin');
const plugin = await loadPlugin<{ sayHello: (name: string) => string }>(manifest);
console.log(plugin.api.sayHello('World'));
loadAllPlugins<T>(pattern, pluginType?)Convenience function that combines findPlugins and loadPlugin. Discovers and loads all matching plugins.
import { loadAllPlugins } from '@libria/plugin-loader';
const plugins = await loadAllPlugins<{ greet: () => string }>(
'./plugins/*-plugin',
'greeting'
);
for (const plugin of plugins) {
console.log(plugin.api.greet());
}
The plugin.json file defines plugin metadata:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique plugin identifier |
pluginType | string | Yes | Plugin category/type for filtering |
module | string | No | ESM entry point (relative path) |
main | string | No | CommonJS entry point (relative path) |
types | string | No | TypeScript declaration file |
At least one of module or main must be specified.
my-plugin/
plugin.json
dist/
index.mjs
{
"name": "my-plugin",
"pluginType": "feature",
"module": "./dist/index.mjs"
}
my-plugin/
plugin.json
dist/
index.cjs
{
"name": "my-plugin",
"pluginType": "feature",
"main": "./dist/index.cjs"
}
You can place plugin.json inside the dist folder and use glob patterns to discover it:
my-plugin/
dist/
plugin.json
index.mjs
// Discover plugins with manifest in dist/
const plugins = await loadAllPlugins('./plugins/*/dist');
LibriaPlugin<T>interface LibriaPlugin<T = unknown> {
readonly pluginType: string;
readonly name?: string;
readonly api: T;
}
PluginManifestinterface PluginManifest {
readonly name: string;
readonly pluginType: string;
readonly main?: string;
readonly module?: string;
readonly types?: string;
readonly __dir: string; // Resolved absolute path
}
The library throws specific errors for common issues:
PluginLoadError - Failed to load the plugin modulePluginInvalidExportError - Plugin export is not a valid objectPluginTypeMismatchError - Plugin type doesn't match manifestimport { loadPlugin, PluginTypeMismatchError } from '@libria/plugin-loader';
try {
const plugin = await loadPlugin(manifest);
} catch (error) {
if (error instanceof PluginTypeMismatchError) {
console.error(`Type mismatch: expected ${error.expected}, got ${error.actual}`);
}
}
MIT
FAQs
Simple plugin loader for Node.js applications
The npm package @libria/plugin-loader receives a total of 24 weekly downloads. As such, @libria/plugin-loader popularity was classified as not popular.
We found that @libria/plugin-loader demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.

Security News
OpenSSF has issued a high-severity advisory warning open source developers of an active Slack-based campaign using impersonation to deliver malware.

Research
/Security News
Malicious packages published to npm, PyPI, Go Modules, crates.io, and Packagist impersonate developer tooling to fetch staged malware, steal credentials and wallets, and enable remote access.