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 🙏

© 2025 – Pkg Stats / Ryan Hefner

inop

v0.8.2

Published

SWC based tool, helps to compile TypeScript modules to Interoperable ESM and CommonJS modules

Readme

Interoperability

Fast SWC-powered build tool that compiles TypeScript/JavaScript to dual ESM/CommonJS packages. Solve the dual package hazard and ship modern packages with ease.

Build Status NPM version Downloads

Why inop?

Publishing JavaScript packages that work in both CommonJS and ESM environments is complicated:

  • Dual Package Hazard: Risk of loading the same module twice in different formats
  • Extension Hell: Managing .js, .cjs, .mjs extensions correctly
  • Import Rewriting: Adjusting import paths for each module system
  • Package.json Exports: Complex configuration for dual module support

inop handles all of this automatically - just write TypeScript, get both formats.

Installation

npm install --save-dev inop
# or
pnpm add -D inop
# or
yarn add -D inop

Quick Start

Transform your TypeScript source to dual modules:

npx inop src build

This creates both ESM (.js) and CommonJS (.cjs) versions of your code with proper source maps.

Example

Given this source structure:

src/
├── index.ts
├── utils.ts
└── constants.ts

Running npx inop src build produces:

build/
├── index.js        # ESM version
├── index.cjs       # CommonJS version  
├── index.js.map    # Source map for ESM
├── index.cjs.map   # Source map for CommonJS
├── utils.js
├── utils.cjs
├── constants.js
└── constants.cjs

Common Use Cases

Publishing npm packages

Use the -p flag to automatically configure package.json for dual module publishing:

npx inop src build -p

This updates your package.json with:

{
  "type": "module",
  "main": "build/index.cjs",       // CommonJS entry
  "module": "build/index.js",       // ESM entry
  "types": "build/index.d.ts",      // TypeScript types
  "exports": {
    "require": "./build/index.cjs", // Node.js require()
    "import": "./build/index.js"    // ESM import
  },
  "files": ["build", "src"]         // Include source for source maps
}

Monorepo packages

Exclude test files and mocks when building:

npx inop src build -i __tests__ -i __mocks__

Custom extensions

Use different file extensions for your output:

# Use .mjs for ESM and .js for CommonJS
npx inop src dist --esm-ext .mjs --commonjs-ext .js

# Generate only ESM
npx inop src dist --skip-commonjs

# Generate only CommonJS  
npx inop src dist --skip-esm

Optimized packages

Create a standalone package with only used dependencies:

npx inop src dist -p --copy

This creates a dist/package.json with only the dependencies actually imported in your code.

TypeScript Configuration

Since SWC doesn't generate type declarations, combine inop with TypeScript:

# Build modules and generate types
npx inop src build && tsc --declaration --emitDeclarationOnly

Or in your package.json:

{
  "scripts": {
    "build": "inop src build && tsc --declaration --emitDeclarationOnly"
  }
}

Recommended tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "NodeNext",
    "declaration": true,
    "esModuleInterop": true,
    "moduleResolution": "NodeNext",
    "rootDir": "src",
    "outDir": "build"
  }
}

Jest Configuration

For testing with Jest and SWC:

export default {
  coverageProvider: 'v8',
  extensionsToTreatAsEsm: ['.ts'],
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',  // Handle .js extensions in imports
  },
  transform: {
    '^.+\\.ts$': '@swc/jest',      // Use SWC for fast transpilation
  },
};

CLI Reference

npx inop <source> <build> [options]

Arguments

  • source - Source directory containing TypeScript/JavaScript files
  • build - Output directory for compiled modules

Options

  • -p, --package - Update package.json with dual module configuration
  • -c, --copy - Copy package.json to build directory with optimized dependencies
  • -i, --ignore [patterns...] - Ignore file patterns (e.g., __tests__, *.spec.ts)
  • -t, --type <type> - Source file type: js or ts (default: ts)
  • -m, --match <pattern> - Override file matching pattern (default: **/*.ts)
  • -s, --swcrc <path> - Custom .swcrc config path (default: .swcrc)
  • --commonjs-ext <ext> - CommonJS file extension (default: .cjs)
  • --esm-ext <ext> - ESM file extension (default: .js)
  • --skip-commonjs - Generate only ESM output
  • --skip-esm - Generate only CommonJS output
  • -V, --version - Show version number
  • -h, --help - Show help

Troubleshooting

Import paths not working?

Ensure your TypeScript uses .js extensions in imports:

// ✅ Correct - will be transformed appropriately
import { utils } from './utils.js';

// ❌ Wrong - missing extension
import { utils } from './utils';

Types not generated?

inop focuses on fast transpilation. Run TypeScript separately for declarations:

tsc --declaration --emitDeclarationOnly

Source maps not resolving?

Make sure source files are included in your npm package by using the -p flag or manually adding them to files in package.json.

License

License The MIT License Copyright (c) 2023-2024 Ivan Zakharchanka