Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.5 KiB
5.5 KiB
Shims
Add compatibility between ESM and CommonJS module systems.
Overview
Shims provide small pieces of code that bridge the gap between CommonJS (CJS) and ECMAScript Modules (ESM), enabling cross-module-system compatibility.
What Shims Provide
ESM Output (when enabled)
With shims: true, adds CommonJS variables to ESM:
__dirname- Current directory path__filename- Current file path
ESM Output (automatic)
Always added when using require in ESM on Node.js:
requirefunction viacreateRequire(import.meta.url)
CJS Output (automatic)
Always added to CommonJS output:
import.meta.urlimport.meta.dirnameimport.meta.filename
Usage
CLI
tsdown --shims
Config File
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
shims: true,
})
Generated Code
ESM with Shims
Source:
console.log(__dirname)
console.log(__filename)
Output (shims: true):
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
console.log(__dirname)
console.log(__filename)
ESM with require
Source:
const mod = require('some-module')
Output (automatic on Node.js):
import { createRequire } from 'node:module'
const require = createRequire(import.meta.url)
const mod = require('some-module')
CJS with import.meta
Source:
console.log(import.meta.url)
console.log(import.meta.dirname)
Output (automatic):
const import_meta = {
url: require('url').pathToFileURL(__filename).toString(),
dirname: __dirname,
filename: __filename
}
console.log(import_meta.url)
console.log(import_meta.dirname)
Common Patterns
Node.js CLI Tool
export default defineConfig({
entry: ['src/cli.ts'],
format: ['esm'],
platform: 'node',
shims: true, // Add __dirname, __filename
})
Dual Format Library
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
platform: 'node',
shims: true, // ESM gets __dirname/__filename
// CJS gets import.meta.* (automatic)
})
Server-Side Code
export default defineConfig({
entry: ['src/server.ts'],
format: ['esm'],
platform: 'node',
shims: true,
external: [/.*/], // External all deps
})
File System Operations
// Source code
import { readFileSync } from 'fs'
import { join } from 'path'
// Read file relative to current module
const content = readFileSync(join(__dirname, 'data.json'), 'utf-8')
// tsdown config
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
shims: true, // Enables __dirname
})
When to Use Shims
Use shims: true when:
- ✅ Building Node.js tools/CLIs
- ✅ Code uses
__dirnameor__filename - ✅ Need file system operations relative to module
- ✅ Migrating from CommonJS to ESM
- ✅ Need cross-format compatibility
Don't need shims when:
- ❌ Browser-only code
- ❌ No file system operations
- ❌ Using only
import.meta.url - ❌ Pure ESM without CJS variables
Performance Impact
Runtime Overhead
Shims add minimal runtime overhead:
// Added to output when shims enabled
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
Tree Shaking
If __dirname or __filename are not used, they're automatically removed during bundling (no overhead).
Platform Considerations
Node.js Platform
export default defineConfig({
platform: 'node',
format: ['esm'],
shims: true, // Recommended for Node.js
})
requireshim added automatically__dirnameand__filenameavailable withshims: true
Browser Platform
export default defineConfig({
platform: 'browser',
format: ['esm'],
shims: false, // Not needed for browser
})
- Shims not needed (no Node.js variables)
- Will cause warnings if Node.js APIs used
Neutral Platform
export default defineConfig({
platform: 'neutral',
format: ['esm'],
shims: false, // Avoid platform-specific code
})
- Avoid shims for maximum portability
CLI Examples
# Enable shims
tsdown --shims
# ESM with shims for Node.js
tsdown --format esm --platform node --shims
# Dual format with shims
tsdown --format esm --format cjs --shims
Troubleshooting
__dirname is not defined
Enable shims:
export default defineConfig({
shims: true,
})
require is not defined in ESM
Automatic on Node.js platform. If not working:
export default defineConfig({
platform: 'node', // Ensure Node.js platform
})
Import.meta not working in CJS
Automatic - no configuration needed. If still failing, check output format:
export default defineConfig({
format: ['cjs'], // Shims added automatically
})
Tips
- Enable for Node.js tools - Use
shims: truefor CLIs and servers - Skip for browsers - Not needed for browser code
- No overhead if unused - Automatically tree-shaken
- Automatic require shim - No config needed for
requirein ESM - CJS shims automatic -
import.meta.*always available in CJS
Related Options
- Platform - Runtime environment
- Output Format - Module formats
- Target - Syntax transformations