{"id":25110,"library":"complugin","title":"complugin","description":"Unified plugin system for multiple bundlers (Rollup, Vite, Webpack, esbuild) using a common plugin API based on Rollup's hook model. Current stable version 1.1.4. Allows writing one plugin that works across bundlers with bundler-specific adapters. Key differentiator: developers maintain one codebase instead of separate plugins per tool. Ships TypeScript types. Peer dependencies include specific versions of each bundler. Release cadence is irregular; last update August 2022. Note: esbuild requires proxyEsbuild wrapper; Webpack must avoid thread-loader; Rollup disallows as output plugin.","status":"maintenance","version":"1.1.4","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","complugin","bundler-plugin","plugin","rollup","esbuild","vite","webpack","typescript"],"install":[{"cmd":"npm install complugin","lang":"bash","label":"npm"},{"cmd":"yarn add complugin","lang":"bash","label":"yarn"},{"cmd":"pnpm add complugin","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"peer dependency – required for esbuild integration (^0.14.44)","package":"esbuild","optional":true},{"reason":"peer dependency – required for Rollup integration (^2.50.0)","package":"rollup","optional":true},{"reason":"peer dependency – required for Vite integration (^2.3.0 || ^3.0.0-0)","package":"vite","optional":true},{"reason":"peer dependency – required for Webpack integration (4 || 5)","package":"webpack","optional":true}],"imports":[{"note":"ESM-only; no default export, named import required. TypeScript types included.","wrong":"const { createComplugin } = require('complugin')","symbol":"createComplugin","correct":"import { createComplugin } from 'complugin'"},{"note":"Named export; required for esbuild integration when using esbuild plugin.","wrong":"import proxyEsbuild from 'complugin'","symbol":"proxyEsbuild","correct":"import { proxyEsbuild } from 'complugin'"},{"note":"Plugins created with createComplugin export a function that returns an object with .vite, .rollup, .webpack, .esbuild methods. In Webpack CJS, use .default.","wrong":"const MyPlugin = require('./my-plugin').default;","symbol":"default export from plugin","correct":"import MyPlugin from './my-plugin'; MyPlugin.vite(options);"}],"quickstart":{"code":"import { createComplugin } from 'complugin'\n\nconst myPlugin = createComplugin<{ prefix?: string }>({\n  name: 'my-plugin',\n  factory(options, meta) {\n    return {\n      transform(code, id) {\n        if (!id.endsWith('.js')) return null\n        return {\n          code: `${options.prefix || ''}${code}`,\n          map: null\n        }\n      }\n    }\n  }\n})\n\n// Rollup usage\nimport { rollup } from 'rollup'\nconst bundle = await rollup({\n  input: 'src/index.js',\n  plugins: [myPlugin.rollup({ prefix: '// prepended\\n' })]\n})","lang":"typescript","description":"Creates a simple transform plugin that prepends a prefix to JS files, then uses it in Rollup."},"warnings":[{"fix":"Remove thread-loader from webpack configuration or avoid using it with complugin plugins.","message":"In Webpack, thread-loader is incompatible with complugin. Do not use thread-loader in the same compilation.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Place the plugin in the plugins array of the input options, not in output.plugins.","message":"In Rollup, complugin cannot be used as an output plugin. Only input plugins are supported.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"const esbuild = proxyEsbuild(require('esbuild')); esbuild.build({ plugins: [...] })","message":"In esbuild, you must proxy esbuild via proxyEsbuild(originalEsbuild) before using complugin plugins. Using original esbuild.build() will not apply the plugins.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always call the appropriate method: myPlugin.vite(options) or myPlugin(options).vite","message":"Plugin functions created by createComplugin return an object with bundler-specific methods (.vite, .rollup, .webpack, .esbuild). They are not directly passable as plugins without calling the method.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Import and call proxyEsbuild: import { proxyEsbuild } from 'complugin'; const esbuild = proxyEsbuild(originalEsbuild); esbuild.build({ plugins: [...] })","cause":"Using esbuild.build() directly without calling proxyEsbuild first.","error":"Error: [complugin] proxyEsbuild must be called before esbuild.build"},{"fix":"Use named import of the exported function and call it with options: import myPlugin from './my-plugin'; myPlugin.vite({...})","cause":"Importing the plugin incorrectly (e.g., missing .default or using wrong import style).","error":"TypeError: myPlugin.vite is not a function"},{"fix":"Remove thread-loader from webpack configuration.","cause":"Using thread-loader in Webpack together with complugin causes parsing errors.","error":"Module parse failed: Unexpected token (1:0) in webpack with thread-loader"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}