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

vite-plugin-electron-externals

v0.4.7

Published

Automatically detect and externalize dependencies for Electron apps in Vite

Readme

vite-plugin-electron-externals

Automatically detect and externalize dependencies for Electron apps in Vite, such as:

  • Native modules (better-sqlite3, serialport, etc.)
  • Electron itself
  • Packages with dynamic requires or ESM/CJS incompatibilities
  • Node.js built-in modules

Features

Smart Detection

  • Auto-detects native modules with compiled bindings
  • Recognizes packages with ESM/CJS incompatibilities
  • Identifies Electron-specific modules
  • Scans for binary files (.node, .dll, .so)
  • Checks for native build scripts (node-gyp, prebuild)

Flexible Configuration

  • Multiple presets (minimal, recommended, aggressive, safe, debug)
  • Configuration file support (.externalrc, package.json)
  • Custom rules with regex patterns
  • Per-module overrides

Performance

  • Built-in caching for fast repeated builds
  • Configurable cache TTL
  • Efficient file system scanning

Installation

npm install vite-plugin-electron-externals --save-dev

Usage

With vite-plugin-doubleshot

const { autoExternals } = require('vite-plugin-electron-externals');
const { VitePluginDoubleshot } = require('vite-plugin-doubleshot');

module.exports = defineConfig({
  plugins: [
    VitePluginDoubleshot({
      type: 'electron',
      main: 'dist/main/index.js',
      entry: 'src/main/index.ts',
      external: await autoExternals(), // ✨
    }),
  ],
});

As a standalone Vite plugin

const { VitePluginElectronExternals } = require('vite-plugin-electron-externals');

module.exports = defineConfig({
  plugins: [
    VitePluginElectronExternals(),
  ],
});

Using presets

external: await autoExternals({ 
  preset: 'aggressive' // minimal | recommended | aggressive | safe | debug
})

Options

await autoExternals({
  // Use a preset
  preset: 'recommended', // minimal | recommended | aggressive | safe | debug
  
  // Additional modules to mark as external
  include: ['my-weird-module'],
  
  // Modules to force bundle (not external)
  exclude: ['some-native-module-i-want-bundled'],
  
  // Custom project root (defaults to process.cwd())
  projectRoot: '/path/to/project',
  
  // Detection options
  detectNative: true,           // Detect native modules
  scanNodeModules: true,         // Scan node_modules for indicators
  checkPostinstall: true,        // Check for postinstall scripts
  checkBinaryField: true,        // Check for .node files
  
  // Custom patterns
  patterns: [
    /^@mycompany\//,             // Externalize scoped packages
  ],
  
  // Custom rules
  rules: [
    {
      pattern: /native/i,
      reason: 'Contains "native" in name',
    },
  ],
  
  // Logging
  verbose: false,                // Detailed output
  logLevel: 'info',              // silent | error | warn | info | debug
  
  // Cache
  cache: {
    enabled: true,               // Enable caching
    ttl: 1000 * 60 * 60,        // Cache TTL (1 hour)
    directory: '/custom/cache',  // Custom cache directory
  },
})

Configuration File

Create .externalrc or .externalrc.json:

{
  "preset": "recommended",
  "include": ["my-custom-module"],
  "exclude": ["electron"],
  "verbose": true
}

Or use .externalrc.js:

module.exports = {
  preset: 'aggressive',
  patterns: [/^@mycompany\//],
  rules: [
    {
      pattern: /native/i,
      reason: 'Package name suggests native code',
    },
  ],
};

Or in package.json:

{
  "electronExternals": {
    "preset": "recommended",
    "verbose": true
  }
}

CLI Tool

Test detection without modifying your config:

# Basic detection
npx vite-plugin-electron-externals

# Verbose output with reasons
npx vite-plugin-electron-externals --verbose

# Use a preset
npx vite-plugin-electron-externals --preset aggressive

# JSON output for CI/CD
npx vite-plugin-electron-externals --json

# List available presets
npx vite-plugin-electron-externals --list-presets

# Clear detection cache
npx vite-plugin-electron-externals --clear-cache

# With custom options
npx vite-plugin-electron-externals \
  --verbose \
  --include my-module \
  --exclude electron \
  --project /path/to/project

Presets

minimal

Only externalizes Node.js built-ins and Electron modules. Fastest, but may miss native modules.

recommended (default)

Balanced approach. Detects native modules and known problematic packages.

aggressive

Externalizes everything that could potentially be problematic. Includes extra patterns and rules.

safe

Conservative approach. Only uses known lists, doesn't scan node_modules.

debug

Verbose logging for troubleshooting detection issues.

API Reference

autoExternals(options)

Returns a Promise resolving to an array of module names to externalize.

const externals = await autoExternals({ preset: 'recommended' });
// ['fs', 'path', 'electron', 'better-sqlite3', ...]

detectExternals(options)

Returns a Promise resolving to detailed detection results.

const results = await detectExternals({ verbose: true });
// {
//   externals: ['fs', 'electron', ...],
//   reasons: {
//     'fs': 'Node.js built-in module',
//     'electron': 'Electron-specific module',
//     'better-sqlite3': 'Known native module with compiled bindings'
//   },
//   timestamp: 1234567890
// }

createPreset(name)

Returns the configuration for a preset.

const config = createPreset('aggressive');
// { detectNative: true, scanNodeModules: true, ... }

VitePluginElectronExternals(options)

Vite plugin for automatic detection.

export default defineConfig({
  plugins: [
    VitePluginElectronExternals({
      preset: 'recommended',
      verbose: true,
    }),
  ],
});

Module detection

The plugin uses multiple detection strategies:

1. Node.js Built-ins

Always externalized: fs, path, crypto, http, https, stream, etc. Includes subpath imports: fs/promises, stream/promises, etc.

2. Electron Modules

  • electron
  • electron-updater
  • electron-store
  • electron-log

3. Native Modules

Detected by:

  • Checking for known native packages (better-sqlite3, sqlite3, canvas, sharp, serialport, etc.)
  • Scanning package.json for gypfile, binary fields
  • Checking for postinstall scripts with node-gyp
  • Looking for dependencies on native build tools
  • Scanning for .node, .dll, .so binary files

4. Problematic Packages

Known packages with bundling issues:

  • dockerode, sql.js, tar-fs
  • express, fastify, koa
  • ws, socket.io
  • puppeteer, playwright
  • prisma, sequelize, typeorm
  • And many more...

5. Pattern Matches

Scoped packages often need externalization:

  • @grpc/*
  • @nestjs/*
  • @tensorflow/*
  • @serialport/*
  • Custom patterns you define

Examples

Basic Electron + Vue

// vite.config.js
const { defineConfig } = require('vite');
const { autoExternals } = require('vite-plugin-electron-externals');

export default defineConfig({
  plugins: [
    // ... other plugins
  ],
  build: {
    rollupOptions: {
      external: await autoExternals(),
    },
  },
});

With Custom Rules

external: await autoExternals({
  preset: 'recommended',
  
  // Your company's internal native modules
  patterns: [/^@mycompany\/native-/],
  
  // Specific detection rules
  rules: [
    {
      pattern: /binding/i,
      reason: 'Likely contains native bindings',
    },
  ],
  
  // Always externalize these
  include: ['my-special-module'],
  
  // Force bundle these (override detection)
  exclude: ['some-false-positive'],
})

Debugging Issues

// Use debug preset to see what's being detected
external: await autoExternals({ 
  preset: 'debug' 
})

// Or run the CLI
// npx vite-plugin-electron-externals --verbose

CI/CD Integration

# In your CI pipeline, verify externals
npx vite-plugin-electron-externals --json > externals.json

# Parse and validate in your scripts
node scripts/validate-externals.js

Troubleshooting

Module not detected

Run with verbose output:

npx vite-plugin-electron-externals --verbose

If a module isn't detected, add it manually:

external: await autoExternals({
  include: ['missing-module'],
})

False positives

If a module is incorrectly externalized:

external: await autoExternals({
  exclude: ['false-positive-module'],
})

Performance issues

Disable expensive scans:

external: await autoExternals({
  scanNodeModules: false,  // Don't scan node_modules
  checkBinaryField: false, // Don't look for .node files
})

Or use the safe preset:

external: await autoExternals({ preset: 'safe' })

Cache issues

Clear the cache:

npx vite-plugin-electron-externals --clear-cache

Or disable caching:

external: await autoExternals({
  cache: { enabled: false },
})

License

MIT