madmod
v0.1.0
Published
Auto-generate and maintain TypeScript re-export index files
Maintainers
Readme
madmod
Auto-generate and maintain TypeScript re-export index files.
- Install
- Quick Start
- Config
- Generated Output
- CLI Commands
- Extension Auto-Detection
- Formatter Auto-Detection
- Programmatic API
- License
Install
pnpm add -D madmodQuick Start
# Create a starter config
madmod init
# Generate index files
madmod generate
# Check for drift (CI mode)
madmod check
# Watch for changes
madmod watchThe xm alias is available for all commands:
xm generate
xm checkConfig
Create madmod.config.ts in your project root:
import { defineConfig } from 'madmod'
export default defineConfig({
rules: [
{
dirs: 'src/lib/**',
modules: [{ include: './*.ts', style: 'star' }],
},
{
dirs: 'src/utils',
modules: [{ include: './*.ts', style: 'namespace' }],
},
],
})Config files are loaded with jiti, so .ts, .js, and .mjs extensions all work.
Options
| Option | Type | Default | Description |
| ------------ | ----------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------- |
| rules | BarrelRule[] | [] | Rules defining which dirs to manage |
| extensions | 'auto' \| 'none' \| '.js' \| '.ts' | 'auto' | Import specifier extension mode |
| exclude | string[] | ['*.test.*', '*.spec.*', '*.stories.*', '*.d.ts'] | Glob patterns to exclude from barrels |
| barrelFile | string | 'index.ts' | Name of the generated barrel file |
| formatter | 'auto' \| 'biome' \| 'dprint' \| 'prettier' \| 'oxfmt' \| false | 'auto' | Formatter to run on generated files |
Rule Options
| Option | Type | Default | Description |
| -------------- | -------------------------- | ------------------------------------- | ---------------------------------------- |
| dirs | string | required | Glob pattern matching directories |
| modules | (string \| ModuleGlob)[] | [{ include: './*', style: 'star' }] | Module patterns to include |
| defaultStyle | 'star' \| 'namespace' | 'star' | Default export style for string patterns |
Module Pattern
Each module pattern has:
| Field | Type | Description |
| --------- | ----------------------- | ----------------------------------------------------- |
| include | string | Glob pattern matching files in the dir |
| style | 'star' \| 'namespace' | star = export *, namespace = export * as Name |
When a pattern is a plain string, it uses the rule's defaultStyle.
Generated Output
Generated files include a header marker so madmod can distinguish them from hand-written files:
// @generated by madmod — DO NOT EDIT
export * from './auth.js'
export * from './billing.js'Namespace style:
// @generated by madmod — DO NOT EDIT
export * as Auth from './auth.js'
export * as Billing from './billing.js'Namespace names are derived from filenames via PascalCase conversion (my-service.ts becomes MyService).
Hand-written index files without the @generated header are never overwritten. They show as conflicts in the output.
CLI Commands
generate
Generate index files from config rules.
madmod generate [--config <path>] [--dry-run] [--no-cache]--dry-runpreviews changes without writing--config/-cspecifies a custom config path--no-cachebypasses the scan cache
check
Check index files for drift. Exits with code 1 if any files are stale. Intended for CI.
madmod check [--config <path>]init
Create a starter madmod.config.ts.
madmod initwatch
Watch for file changes and regenerate affected index files. Reloads config automatically when madmod.config.* changes.
madmod watch [--config <path>]Uses @parcel/watcher for native filesystem events. Filters out self-writes to avoid infinite loops.
doctor
Diagnose setup, validate config, and lint index files.
madmod doctor [--config <path>] [--fix]Checks:
- Config file exists and parses
- Rule glob patterns match directories
- tsconfig extension mode detection
- Formatter detection
- Index file staleness
- Namespace collisions
- Unmanaged directories (suggestions)
--fix auto-regenerates stale index files.
daemon
Background daemon management. Runs watch in a detached process.
madmod daemon start [--config <path>]
madmod daemon stop
madmod daemon statusLogs to node_modules/.cache/madmod/daemon.log.
Extension Auto-Detection
When extensions is 'auto' (the default), madmod reads your tsconfig.json to determine the right import specifier style:
| moduleResolution | allowImportingTsExtensions | Result |
| --------------------- | --------------------------------------- | ------ |
| bundler | any | none |
| node16 / nodenext | false or absent | .js |
| node16 / nodenext | true + noEmit/emitDeclarationOnly | .ts |
| other / missing | any | none |
Override with extensions: '.js', extensions: '.ts', or extensions: 'none' in your config.
Formatter Auto-Detection
When formatter is 'auto', madmod looks for config files in this order:
- biome --
biome.json,biome.jsonc - dprint --
dprint.json,.dprint.json - prettier --
.prettierrc,.prettierrc.json,.prettierrc.yml,prettier.config.*
Falls back to checking devDependencies in package.json. Set formatter: false to disable.
Programmatic API
import { NodeContext } from '@effect/platform-node'
import {
defineConfig,
execute,
loadConfig,
plan,
resolveDefaults,
} from 'madmod'
import { Effect } from 'effect'
const config = resolveDefaults({
extensions: '.js',
rules: [{ dirs: 'src/lib/**' }],
})
const program = Effect.gen(function*() {
const result = yield* plan(config, process.cwd())
const written = yield* execute(result)
console.log(`Wrote ${written.length} files`)
})
program.pipe(Effect.provide(NodeContext.layer), Effect.runPromise)Exports:
| Export | Description |
| --------------------- | ----------------------------------- |
| defineConfig | Type-safe config helper |
| resolveDefaults | Apply defaults to a raw config |
| loadConfig | Load and validate config from disk |
| plan | Scan dirs and compute actions |
| execute | Write planned actions to disk |
| detectExtensionMode | Detect extension mode from tsconfig |
Types: Config, ResolvedConfig, BarrelRule, ResolvedRule, ModuleGlob, ExportStyle, Action, PlanResult, ExtensionMode.
License
MIT
