MediaProc uses a dynamic plugin system that allows extending the CLI with specialized media processing capabilities. Each plugin is an independent npm package that can be installed globally or locally.
When MediaProc starts, it scans for all installed @mediaproc/* packages:
// Core discovers plugins automatically
const plugins = await discoverPlugins();The plugin manager checks:
- Global npm/pnpm directories
- Local
node_modules/@mediaproc/ - Workspace packages (development mode)
Each plugin exports a register() function that adds commands to the CLI:
export function register(program: Command): void {
const imageCmd = program
.command('image')
.description('Image processing commands');
imageCmd
.command('resize <input>')
.option('-w, --width <width>', 'Width')
.option('-h, --height <height>', 'Height')
.action(async (input, options) => {
await resize(input, options);
});
}Every plugin follows this structure:
@mediaproc/plugin-name/
├── package.json
├── tsconfig.json
├── bin/
│ └── cli.js # Standalone executable
├── src/
│ ├── index.ts # Public exports
│ ├── register.ts # CLI registration
│ ├── types.ts # TypeScript types
│ └── commands/
│ ├── command1.ts
│ └── command2.ts
The core package maintains a registry that maps short names to full package names:
const PLUGIN_REGISTRY = {
'image': '@mediaproc/image',
'video': '@mediaproc/video',
'audio': '@mediaproc/audio',
// ... more plugins
};This allows users to install plugins with simple names:
mediaproc add image
# Installs @mediaproc/imagemkdir -p plugins/myplugin
cd plugins/myplugin
pnpm init{
"name": "@mediaproc/myplugin",
"version": "1.0.0",
"type": "module",
"main": "./dist/index.js",
"dependencies": {
"@mediaproc/cli": "workspace:*",
"chalk": "^5.3.0",
"commander": "^11.1.0"
}
}// src/register.ts
import { Command } from 'commander';
import chalk from 'chalk';
export const name = 'myplugin';
export const version = '1.0.0';
export function register(program: Command): void {
const cmd = program
.command('myplugin')
.description('My custom plugin');
cmd
.command('process <input>')
.description('Process a file')
.action(async (input) => {
console.log(chalk.blue('Processing:'), input);
// Your logic here
});
}// src/index.ts
export { register, name, version } from './register.js';
export type * from './types.js';Update src/plugin-registry.ts in core:
export const PLUGIN_REGISTRY: PluginRegistryEntry[] = [
// ... existing plugins
{
name: 'myplugin',
package: '@mediaproc/myplugin',
description: 'My custom media processor',
category: 'core'
}
];Each plugin can work in two modes:
mediaproc myplugin process file.txtThe plugin is loaded dynamically by the core CLI.
npx @mediaproc/myplugin process file.txt
# or
mediaproc-myplugin process file.txtThe plugin runs independently without the core CLI.
Plugins automatically detect and match the core CLI's installation scope:
- Global Installation: Plugins install globally
- Local Installation: Plugins install in project's
node_modules
Override with flags:
mediaproc add image --global
mediaproc add video --localKeep plugins up-to-date with the update command:
# Update all plugins to latest
mediaproc update
# Update specific plugin to latest
mediaproc update image
mediaproc update video
# Update to specific version
mediaproc update image --version 1.2.3
mediaproc update video --version 2.0.0-beta.1
# With installation scope
mediaproc update --global # Update globally installed plugins
mediaproc update image --local # Update locally installed plugin
# Verbose output
mediaproc update --verbose # Shows detailed information
mediaproc update image --verbose # Shows package manager, versions, etc.Plugin Type Detection:
The update command automatically detects and handles three types of plugins:
-
Official Plugins (
@mediaproc/*) - Displays as ★ OFFICIALmediaproc update image # Short name mediaproc update @mediaproc/image # Full name
-
Community Plugins (
mediaproc-*) - Displays as ◆ COMMUNITYmediaproc update mediaproc-custom-filter # Full name required -
Third-Party Plugins - Displays as ◇ THIRD-PARTY
mediaproc update @company/plugin-name # Full package name
What happens during update:
- Detects plugin type (official/community/third-party)
- Detects plugin installation location (global/local)
- Checks npm registry for latest version (or uses specified version)
- Uses appropriate package manager (npm/pnpm/yarn/bun/deno)
- Shows version changes (old → new) with plugin type badge
- Automatically reloads updated plugins
Examples:
# Update official plugin to latest
$ mediaproc update image
✓ Detecting plugin type for image...
✓ image ★ OFFICIAL updated successfully (1.2.0 → 1.2.2)
# Update to specific version
$ mediaproc update image --version 1.2.1
✓ image ★ OFFICIAL updated successfully (1.2.0 → 1.2.1)
# Update community plugin
$ mediaproc update mediaproc-watermark
✓ mediaproc-watermark ◆ COMMUNITY updated successfully (0.5.0 → 0.6.1)
# Update third-party plugin
$ mediaproc update @mycompany/media-tools
✓ @mycompany/media-tools ◇ THIRD-PARTY updated successfully
# Update with verbose output
$ mediaproc update image --verbose
ℹ Package manager: pnpm
ℹ Plugin type: ★ OFFICIAL
ℹ Package name: @mediaproc/image
ℹ Current version: 1.2.0
ℹ Running: pnpm add @mediaproc/image
✓ image ★ OFFICIAL updated successfully (1.2.0 → 1.2.2)
# Update all plugins
$ mediaproc update
✓ Finding all installed MediaProc plugins...
✓ All MediaProc plugins updated successfullyVersion Flags:
--version <version>: Update to specific version (e.g.,1.2.3,2.0.0-beta.1)- Omit
--version: Updates tolatestversion - Supports semantic versioning and pre-release versions
Plugins are organized into categories:
- core: Essential media types (image, video, audio, document)
- advanced: Specialized processing (3d, stream, pipeline)
- future-proof: AI and emerging technologies
- Type Safety: Use TypeScript for all plugin code
- Error Handling: Provide clear error messages with chalk
- Progress Indicators: Use ora spinners for long operations
- Options Validation: Validate user inputs before processing
- Documentation: Document all commands and options
- Testing: Write tests for each command
- Dependencies: Minimize external dependencies
- Performance: Handle large files efficiently
Core provides utilities for plugin developers:
import { createCommand, validateFile, showProgress } from '@mediaproc/cli';
// Create command with standard options
const cmd = createCommand('process')
.withInput()
.withOutput()
.withQuality();
// Validate input file
await validateFile(input, ['jpg', 'png', 'webp']);
// Show progress
const spinner = showProgress('Processing...');
// ... processing
spinner.succeed('Done!');Plugins can specify system dependencies:
export const metadata = {
systemRequirements: [
'FFmpeg',
'ImageMagick',
'Node.js >= 18.0.0'
]
};The core CLI checks these before plugin installation.
- Plugin Marketplace: Browse and discover plugins
- Plugin Templates: Scaffolding for new plugins
- Plugin Testing Framework: Standardized testing utilities
- Plugin Versioning: Compatibility checks
- Plugin Dependencies: Plugins depending on other plugins
MediaProc welcomes third-party plugins! Anyone can create and publish plugins that extend MediaProc's capabilities.
Official Plugins (maintained by core team):
@mediaproc/<plugin-name>
Third-Party Plugins (community):
mediaproc-plugin-<plugin-name>
or
@yourscope/mediaproc-plugin-<plugin-name>
Examples:
mediaproc-plugin-instagram- Instagram image filters@acme/mediaproc-plugin-custom- Custom company processormediaproc-plugin-ascii- ASCII art generator
{
"name": "mediaproc-plugin-yourname",
"version": "1.0.0",
"description": "Clear description of what your plugin does",
"keywords": ["mediaproc", "mediaproc-plugin", "your", "keywords"],
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"engines": {
"node": ">=18.0.0"
},
"mediaproc": {
"pluginName": "yourname",
"pluginVersion": "1.0.0",
"category": "community"
}
}Your plugin MUST export these from src/index.ts:
// src/index.ts
import type { Command } from 'commander';
// Required exports
export const name: string = 'yourplugin';
export const version: string = '1.0.0';
export const description: string = 'What your plugin does';
// Required: Registration function
export function register(program: Command): void {
const cmd = program
.command('yourplugin')
.description(description);
// Add your commands here
cmd
.command('process <input>')
.description('Process a file')
.action(async (input, options) => {
// Your implementation
});
}
// Optional: Plugin metadata
export const metadata = {
author: 'Your Name',
homepage: 'https://github.com/yourname/mediaproc-plugin-yourname',
repository: 'https://github.com/yourname/mediaproc-plugin-yourname',
license: 'MIT',
systemRequirements: ['Optional', 'system', 'dependencies'],
category: 'community'
};
// Export types for TypeScript users
export type * from './types.js';MediaProc discovers plugins in two ways:
A. Automatic Discovery (Official plugins)
# Official plugins are auto-loaded when installed:
npm install -g @mediaproc/image
mediaproc image resize input.jpg --width 1920B. Environment Variable (Optional)
export MEDIAPROC_PLUGINS="mediaproc-plugin-one,mediaproc-plugin-two"mkdir mediaproc-plugin-myprocessor
cd mediaproc-plugin-myprocessor
npm init -ynpm install --save-dev typescript @types/node
npm install chalk commander ora execa{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}mediaproc-plugin-myprocessor/
├── src/
│ ├── index.ts # Main entry, exports
│ ├── types.ts # TypeScript types
│ └── commands/
│ └── process.ts # Command implementations
├── package.json
├── tsconfig.json
├── README.md
└── LICENSE
// src/index.ts
import { Command } from 'commander';
import { processCommand } from './commands/process.js';
export const name = 'myprocessor';
export const version = '1.0.0';
export const description = 'My custom media processor';
export function register(program: Command): void {
const cmd = program
.command(name)
.description(description);
processCommand(cmd);
}
export type * from './types.js';// src/commands/process.ts
import { Command } from 'commander';
import chalk from 'chalk';
import ora from 'ora';
export function processCommand(parent: Command): void {
parent
.command('process <input>')
.description('Process a media file')
.option('-o, --output <path>', 'Output path')
.option('-q, --quality <number>', 'Quality (1-100)', '80')
.action(async (input: string, options: any) => {
const spinner = ora('Processing...').start();
try {
// Your processing logic here
await processFile(input, options);
spinner.succeed(chalk.green('Done!'));
} catch (error) {
spinner.fail(chalk.red('Error:'));
console.error(error);
process.exit(1);
}
});
}
async function processFile(input: string, options: any): Promise<void> {
// Implementation
}# Build
npm run build
# Test locally
npm link
mediaproc myprocessor process test.jpg
# Unlink after testing
npm unlink -g# Make sure you're logged in
npm login
# Publish
npm publish
# Or for scoped packages
npm publish --access publicTo be featured in the community plugins list, your plugin should:
- TypeScript - Use TypeScript with strict mode
- Documentation - Clear README with usage examples
- License - Open source license (MIT, Apache, GPL, etc.)
- Error Handling - Graceful error handling with clear messages
- Type Exports - Export TypeScript types for users
- Versioning - Follow semantic versioning
- Testing - Basic tests for critical functionality
- Performance - Handle large files efficiently
- Progress Indicators - Use ora for long operations
- Memory Management - Stream large files
- Cross-Platform - Work on Windows, macOS, Linux
- Dependencies - Minimize external dependencies
- Examples - Provide example code and files
- CI/CD - Automated testing and publishing
- Comprehensive Tests - High test coverage
- Benchmarks - Performance benchmarks
- Documentation Site - Dedicated docs website
- Examples Repository - Separate repo with examples
- Video Tutorials - Screen recordings or YouTube
- Community Support - Active issue responses
- Internationalization - Multi-language support
Want your plugin featured in the official plugin directory?
- Published to npm
- Meets quality standards
- Has clear documentation
- Open source with license
- Follows naming convention
- No security vulnerabilities
Create an issue in the MediaProc repository:
Title: [Plugin Submission] mediaproc-plugin-yourname
**Plugin Name:** mediaproc-plugin-yourname
**npm Package:** https://www.npmjs.com/package/mediaproc-plugin-yourname
**Repository:** https://github.com/yourname/mediaproc-plugin-yourname
**Description:** Brief description
**Category:** Choose one
- [ ] Image Processing
- [ ] Video Processing
- [ ] Audio Processing
- [ ] Document Processing
- [ ] Utilities
- [ ] Other: _______
**Checklist:**
- [ ] Published to npm
- [ ] Open source (MIT/Apache/GPL)
- [ ] TypeScript with types
- [ ] Documentation (README)
- [ ] Tests included
- [ ] No security issues
- [ ] Works with latest MediaProc
**Additional Info:**
Any other relevant information- Automated Checks - CI runs basic validation
- Code Review - Maintainer reviews code quality
- Security Scan - Check for vulnerabilities
- Testing - Test with current MediaProc version
- Approval - Added to community plugins list
Once approved, your plugin will be:
- Listed in
mediaproc plugins --community - Added to website plugin directory (coming soon)
- Featured in monthly plugin spotlight
- Added to this documentation
Organize your plugin under the appropriate category:
- image - Image manipulation and conversion
- video - Video processing and encoding
- audio - Audio processing and conversion
- document - Document processing (PDF, DOCX, etc.)
- animation - GIF, WebP, Lottie animations
- 3d - 3D models and spatial media
- metadata - EXIF, XMP, IPTC metadata
- streaming - HLS, DASH, adaptive streaming
- compression - File size optimization
- conversion - Format conversions
- analysis - Media analysis tools
- automation - Workflow automation
- filters - Creative filters and effects
- social - Social media optimizations
- accessibility - Accessibility features
- ai - AI/ML powered features
- other - Miscellaneous tools
Here are some example plugin ideas to inspire you:
mediaproc-plugin-ascii- Convert images to ASCII artmediaproc-plugin-qrcode- Generate/read QR codesmediaproc-plugin-palette- Extract color palettesmediaproc-plugin-hash- Generate media hashes
mediaproc-plugin-instagram- Instagram-style filtersmediaproc-plugin-meme- Meme generatormediaproc-plugin-subtitle- Subtitle generation/editingmediaproc-plugin-slideshow- Create video slideshows
mediaproc-plugin-upscale- AI image upscalingmediaproc-plugin-deepfake- Deepfake detectionmediaproc-plugin-transcribe- Audio transcriptionmediaproc-plugin-realtime- Real-time processing server
// src/__tests__/plugin.test.ts
import { describe, it, expect } from 'vitest';
import { register, name, version } from '../index.js';
describe('Plugin', () => {
it('should export required properties', () => {
expect(name).toBeDefined();
expect(version).toBeDefined();
expect(register).toBeTypeOf('function');
});
it('should register commands', () => {
const mockProgram = {
command: vi.fn().mockReturnThis(),
description: vi.fn().mockReturnThis(),
};
register(mockProgram as any);
expect(mockProgram.command).toHaveBeenCalled();
});
});// src/__tests__/integration.test.ts
import { describe, it, expect } from 'vitest';
import { execa } from 'execa';
import { readFile } from 'fs/promises';
describe('Integration', () => {
it('should process file successfully', async () => {
await execa('mediaproc', ['yourplugin', 'process', 'test.jpg']);
const output = await readFile('output.jpg');
expect(output).toBeDefined();
});
});- Documentation: https://docs.mediaproc.dev (coming soon)
- Examples: https://github.com/0xshariq/mediaproc-examples (coming soon)
- Plugin Template: https://github.com/0xshariq/mediaproc-plugin-template (coming soon)
- Discord: Join our community (coming soon)
- GitHub Discussions: Ask questions
We're building a plugin marketplace where users can:
- Browse all available plugins
- See ratings and reviews
- Install with one click
- Support plugin developers
- Report issues
- Request features
Ready to build your plugin? Start with our Plugin Template (coming soon) or check out Example Plugins (coming soon).