npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jamx-framework/plugins

v2.0.0

Published

JAMX Framework — Plugin system and marketplace

Readme

@jamx-framework/plugins

Descripción

Sistema de plugins para JAMX Framework. Proporciona una arquitectura extensible que permite añadir funcionalidades al framework mediante plugins, con registro automático, gestión de dependencias entre plugins, y un marketplace para descubrir e instalar plugins de la comunidad. Los plugins pueden extender el core, añadir adaptadores, comandos CLI, o integraciones con servicios externos.

Cómo funciona

El sistema de plugins implementa un registro centralizado con dependencias y ciclo de vida:

  1. Plugin Registry: Registra plugins disponibles y gestiona su orden de carga
  2. Plugin Loader: Carga plugins desde archivos o paquetes npm
  3. Marketplace: Catálogo de plugins públicos/privados para descubrimiento
  4. Built-in Plugins: Plugins incluidos por defecto en JAMX

Componentes principales

  • src/plugin-registry.ts: PluginRegistry que gestiona registro y orden de plugins
  • src/plugin-loader.ts: PluginLoader que carga plugins desde disco o npm
  • src/marketplace.ts: Marketplace para buscar y descargar plugins
  • src/built-in-plugins.ts: Lista de plugins incluidos por defecto
  • src/types.ts: Tipos (Plugin, PluginMeta, PluginContext)
  • src/index.ts: Punto de exportación

Uso básico

import { PluginRegistry, Plugin } from '@jamx-framework/plugins';

// Crear registry
const registry = new PluginRegistry();

// Definir un plugin
class MyPlugin implements Plugin {
  meta = {
    name: 'my-plugin',
    version: '1.0.0',
    dependencies: ['@jamx-framework/core'],
  };

  async setup(ctx) {
    console.log('Plugin my-plugin inicializado');
    // Registrar servicios, comandos, etc.
  }

  async teardown(ctx) {
    console.log('Plugin my-plugin limpiando');
  }
}

// Registrar y ejecutar
registry.register(new MyPlugin());
await registry.setupAll(ctx);

Ejemplos

Plugin que añade un comando CLI

import { Plugin, PluginContext } from '@jamx-framework/plugins';

class MyCliPlugin implements Plugin {
  meta = {
    name: 'my-cli-plugin',
    version: '1.0.0',
    dependencies: ['@jamx-framework/cli'],
  };

  async setup(ctx: PluginContext) {
    // Registrar comando en CLI
    ctx.cli.registerCommand({
      name: 'my-command',
      description: 'Mi comando personalizado',
      action: async (options) => {
        console.log('Ejecutando mi comando');
      },
    });
  }
}

Plugin con dependencias

class AnalyticsPlugin implements Plugin {
  meta = {
    name: 'analytics',
    version: '1.0.0',
    dependencies: [
      '@jamx-framework/core',
      '@jamx-framework/events',
      '@jamx-framework/metrics',
    ],
  };

  async setup(ctx) {
    // Usar servicios de otras dependencias
    const events = ctx.container.resolve('eventBus');
    const metrics = ctx.container.resolve('metrics');
    
    events.on('user.created', (data) => {
      metrics.counter('users_created_total').increment();
    });
  }
}

Plugin que extiende el contenedor

class DatabasePlugin implements Plugin {
  meta = {
    name: 'database-extension',
    version: '1.0.0',
    dependencies: ['@jamx-framework/db'],
  };

  async setup(ctx) {
    const { Container } = await import('@jamx-framework/core');
    
    // Registrar servicios adicionales
    Container.registerSingleton('userRepository', () => {
      return new UserRepository(ctx.db);
    });
  }
}

Marketplace: instalar plugin

# Buscar plugins
jamx plugins:search analytics

# Instalar plugin
jamx plugins:install @jamx-plugin/analytics

# Listar plugins instalados
jamx plugins:list

# Actualizar plugins
jamx plugins:update

# Desinstalar plugin
jamx plugins:uninstall @jamx-plugin/analytics

Configuración de plugins en jamx.config.ts

import { defineConfig } from '@jamx-framework/core';

export default defineConfig({
  plugins: [
    '@jamx-plugin/analytics',
    '@jamx-plugin/monitoring',
    // Plugins locales
    './plugins/my-local-plugin.js',
  ],
  
  pluginOptions: {
    analytics: {
      apiKey: process.env.ANALYTICS_KEY,
      endpoint: 'https://analytics.example.com',
    },
    monitoring: {
      enabled: true,
      sampleRate: 0.1,
    },
  },
});

Flujo interno

  1. Discovery: El PluginLoader busca plugins en node_modules, directorio local, o registry npm
  2. Loading: Carga el módulo del plugin (ESM o CommonJS)
  3. Validation: Verifica que el plugin exporte una clase que implemente Plugin interface
  4. Registration: Añade el plugin a PluginRegistry
  5. Dependency resolution: Ordena plugins según dependencias (topological sort)
  6. Setup: Ejecuta setup() de cada plugin en orden, inyectando PluginContext
  7. Teardown: Al cerrar la app, ejecuta teardown() en orden inverso

API Reference (Resumen)

Plugin (interface)

interface Plugin<TContext extends PluginContext = PluginContext> {
  meta: PluginMeta;
  setup(ctx: TContext): Promise<void> | void;
  teardown?(ctx: TContext): Promise<void> | void;
}

PluginMeta

  • name: string
  • version: string
  • description?: string
  • dependencies?: string[] (otros plugins o paquetes)
  • peerDependencies?: string[]
  • optionalDependencies?: string[]

PluginContext

  • container: Container
  • config: Record<string, any>
  • logger: Logger
  • cli?: CLI
  • server?: Server
  • db?: Database
  • etc. (todos los servicios disponibles)

PluginRegistry

  • register(plugin: Plugin): this
  • registerAll(plugins: Plugin[]): this
  • setupAll(ctx: PluginContext): Promise<void>
  • teardownAll(ctx: PluginContext): Promise<void>
  • has(name: string): boolean
  • list(): Plugin[]
  • resolveOrder(): Plugin[] (topological sort)

PluginLoader

  • loadFromPath(path: string): Promise<Plugin>
  • loadFromPackage(name: string): Promise<Plugin>
  • loadAllFromDir(dir: string): Promise<Plugin[]>

Marketplace

  • search(query: string): Promise<PluginInfo[]>
  • install(name: string, version?: string): Promise<void>
  • uninstall(name: string): Promise<void>
  • listInstalled(): Promise<InstalledPlugin[]>
  • update(name?: string): Promise<void>

Performance Considerations

  • Lazy loading: Los plugins se cargan solo cuando se necesitan
  • Dependency caching: Las dependencias se resuelven una vez y se cachean
  • Parallel setup: Los plugins sin dependencias cruzadas pueden inicializarse en paralelo
  • Tree-shaking: Solo se incluyen plugins usados en el build final

Configuration Options

// jamx.config.ts
export default defineConfig({
  plugins: [
    // Plugins desde npm
    '@jamx-plugin/analytics@^2.0.0',
    '@jamx-plugin/cache@latest',
    
    // Plugins locales (desarrollo)
    './plugins/local-plugin.js',
  ],
  
  // Opciones específicas por plugin
  pluginOptions: {
    analytics: {
      apiKey: 'xxx',
      endpoint: 'https://api.example.com',
      sampleRate: 0.1,
    },
    cache: {
      driver: 'redis',
      ttl: 3600,
    },
  },
  
  // Habilitar/deshabilitar plugins
  disabledPlugins: ['@jamx-plugin/experimental'],
});

Testing

Tests en packages/plugins/tests/unit/:

pnpm test

Cubre:

  • Registro de plugins
  • Resolución de dependencias
  • Orden de setup/teardown
  • Carga desde archivos
  • Marketplace (mock)

Compatibility

  • Compatible con Node.js 18+
  • Funciona con ESM y CommonJS
  • Plugins pueden ser paquetes npm o archivos locales
  • Soporta versionado semántico

CLI Integration

  • jamx plugins:search <query>: Busca plugins en marketplace
  • jamx plugins:install <name>: Instala plugin desde npm
  • jamx plugins:list: Lista plugins instalados
  • jamx plugins:uninstall <name>: Desinstala plugin
  • jamx plugins:update [name]: Actualiza plugins
  • jamx plugins:create <name>: Scaffold de plugin nuevo

Best Practices

  1. Mantener plugins pequeños: Un plugin = una funcionalidad
  2. Declarar dependencias: Especificar dependencies en meta
  3. Implementar teardown: Limpiar recursos al desinstalar
  4. Usar context: Acceder a servicios a través de ctx.container.resolve()
  5. Versionado semántico: Seguir semver para compatibilidad
  6. Documentar: Incluir README en cada plugin
  7. Testing: Escribir tests para el plugin

Publishing Plugins

Para publicar un plugin en el marketplace:

  1. Crear paquete npm con @jamx-plugin/ prefix
  2. Exportar clase que implemente Plugin
  3. Incluir jamx.plugin.json con metadatos
  4. Publicar en npm: npm publish --access public
  5. Enviar PR al marketplace para listado

Ejemplo de jamx.plugin.json:

{
  "name": "@jamx-plugin/analytics",
  "version": "1.0.0",
  "description": "Analytics plugin for JAMX",
  "author": "Your Name",
  "license": "MIT",
  "keywords": ["jamx", "plugin", "analytics"],
  "jamx": {
    "type": "plugin",
    "entry": "./dist/index.js",
    "dependencies": ["@jamx-framework/core"],
  }
}

This plugin system provides a powerful extension mechanism for JAMX Framework, enabling developers to create, share, and consume plugins that enhance the framework's capabilities in a modular, dependency-aware manner.