npm version node version license
libwiz is a powerful CLI tool designed to help you build JavaScript and TypeScript libraries. It supports output formats like ESM (ECMAScript Module) and CJS (CommonJS), while offering features like type generation, source maps, and more.
- 📦 Multi-format Support: Build libraries in ESM (modern JavaScript) or CJS (CommonJS) formats.
- 📜 TypeScript Type Generation: Automatically generate TypeScript definition files (
*.d.ts). - 🛠 Customizable Build Directories: Specify source and output directories as needed.
- 🔄 Dev Mode: Automatically rebuild when files change.
- 🗺 Source Maps: Generate source maps for easier debugging.
- ⚙️ Config File Support: Customize the build with a configuration file (
libwiz.config.js,libwiz.config.json, or.libwizrc). - 🚀 Quick Setup: Use
npx libwiz initto generate a minimal configuration file and get started instantly. - 🔧 Framework Agnostic: No framework-specific dependencies included by default. Add React, Vue, or any other framework support as needed.
- ✅ Type Checking: Built-in TypeScript type checking without file generation.
# Install globally npm install -g libwiz # Or add as dev dependency npm install --save-dev libwiz
libwiz provides four primary commands: init, build, dev, and types.
- init: Create a sample configuration file to get started quickly.
- build: Build the library in the desired format.
- dev: Run the build in watch mode for faster development.
- types: Generate TypeScript definition files only (without building the library).
# Initialize a new configuration file npx libwiz init # Build library libwiz build # Build with TypeScript types libwiz build --types # Generate TypeScript types only libwiz types # Type check only (no file generation) libwiz types --check # Watch mode for development libwiz dev # Build for specific target format libwiz build --target esm libwiz build --target cjs
The init command creates a minimal libwiz.config.js file to get you started quickly:
# Quick start npx libwiz init # Or if you have libwiz installed globally libwiz init
This will create a libwiz.config.js file with:
- Basic ESM and CJS build configuration
- Source maps enabled
- JSDoc type annotations for better IDE support
The generated config is minimal and ready to use, but you can customize it further based on your needs.
| Option | Description | Default |
|---|---|---|
--target |
Build target format: esm or cjs. |
both |
--src-dir |
Source directory for your library code. | ./src |
--out-dir |
Output directory for build files. | ./dist |
--types |
Generate TypeScript definition files (*.d.ts). |
false |
--source-maps |
Generate source maps for the build. | false |
--progress |
Enable progress bar during build. | false |
--check |
Type check only without generating files (types command only) | false |
--help |
Show help for all commands and options. | |
--version |
Show the installed version of libwiz. |
|
--quiet |
Suppress all logs and output (useful for CI/CD). | false |
libwiz supports configuration files to give you more control over your build process. You can create a config file named libwiz.config.js, libwiz.config.json, or .libwizrc in your project root.
💡 Tip: Use
npx libwiz initto quickly create a minimal configuration file to get started!
The configuration options allow you to customize or override the default flow. By default, libwiz will use sensible values, but you can specify these options as needed to fine-tune the build process.
Note: All build-related configuration is consolidated under the output section.
root(string): Specifies the root directory of the project.workspace(string): Defines a workspace directory within the project.srcPath(string): Path to the source files of the library.output(stringorobject): Output configuration that can be either a simple string path or a detailed object:- As String: Simple output directory path (e.g.,
'./dist') - As Object: Detailed output configuration:
dir(string): Output directory path (defaults to'./dist')target(stringorarray): Build targets, such as"esm","cjs", or an array with bothcomments(boolean): Include comments in output for all targetssourceMap(boolean): Generate source maps for all targets
- Note: If
outputoroutput.diris not defined in your config, it will automatically default to'./dist'folder
- As String: Simple output directory path (e.g.,
tsConfig(string): Path to the TypeScript configuration file, such astsconfig.json.extensions(array of strings): List of file extensions to process, e.g.,['.ts', '.tsx'].ignore(array of strings): Glob patterns to exclude files from the build process. Defaults to:Useful for excluding test files, fixtures, stories, examples and other non-production code from your build output.[ '**/*.test.js', '**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx', '**/*.d.ts', ];
lib(object): Library configuration settings for both ESM and CJS builds (can override output-level settings):esm(object): Settings for ESM (EcmaScript Module) format output.output(object): Configures ESM output settings.path(string): Custom output directory path for ESM format (e.g.,'esm','modern'). Defaults to root of output directory.comments(boolean): Includes comments in the output iftrue.sourceMap(boolean): Generates source maps iftrue.
cjs(object): Settings for CJS (CommonJS) format output.output(object): Configures CJS output settings.path(string): Custom output directory path for CJS format (e.g.,'cjs','legacy'). Defaults to'cjs'in output directory.comments(boolean): Includes comments in the output iftrue.sourceMap(boolean): Generates source maps iftrue.
customTranspiler(function): A custom function to handle transpilation if specific control is required.compiler(objectorfunction, optional): Advanced compiler configuration that can be either a static object or a dynamic function based on build target.- As Object: Static compiler configuration applied to all targets.
presets(array): Array of compiler presets; can be eitherstringor[string, object]for custom options.plugins(array): Array of compiler plugins; can be eitherstringor[string, object]for custom options.browsers(stringorarray): Target browsers for code compilation.overrides(array): Babel overrides configuration for conditional compilation based on file patterns or other criteria.
- As Function: Dynamic compiler configuration that receives build context and returns compiler options.
- Function Signature:
(context: CompilerContext) => CompilerConfig - Context Object:
target('esm' | 'cjs'): Current build targetisESM(boolean): Whether building for ESM formatisCJS(boolean): Whether building for CommonJS format
- Returns: Same
CompilerConfigobject as above
- Function Signature:
- As Object: Static compiler configuration applied to all targets.
assets(string,array, ornull): Specifies additional assets to include in the build, like['**/*.css']. Set tonullto exclude assets.
Here is an example of a configuration file (libwiz.config.js):
// libwiz.config.js module.exports = { root: './', workspace: '../../', srcPath: './src', output: { dir: './dist', target: ['esm', 'cjs'], sourceMap: false, comments: false, }, tsConfig: './tsconfig.json', extensions: ['.ts', '.tsx'], ignore: ['**/__tests__/**'], lib: { esm: { output: { path: 'esm', // custom path for ESM output (defaults to root of output directory) comments: true, sourceMap: true, }, }, cjs: { output: { path: 'cjs', // custom path for CJS output (default cjs inside output directory) comments: true, sourceMap: true, }, }, }, compiler: { presets: [ // you can add your presets ], plugins: [ '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-class-properties', ], browsers: 'last 2 versions', }, assets: '**/*.css', };
The output configuration is the central place for all build-related settings. It provides a clean, unified way to specify build settings while maintaining compatibility with the existing lib configuration.
// Simple string path { output: './dist' } // Object with basic settings { output: { dir: './dist', target: 'esm', sourceMap: true } }
The lib configuration can still override output-level settings for fine-grained control:
{ output: { dir: './dist', target: ['esm', 'cjs'], sourceMap: true, // Applies to all targets comments: true // Applies to all targets }, lib: { esm: { output: { path: 'modern', // Override ESM output path sourceMap: false // Override sourceMap for ESM only } }, cjs: { output: { path: 'legacy', // Override CJS output path comments: false // Override comments for CJS only } } } }
To add React support to your library:
-
Install React preset:
npm install --save-dev @babel/preset-react
-
Add to your
libwiz.config.js:module.exports = { // ... other config compiler: { presets: [['@babel/preset-react', { runtime: 'automatic' }]], plugins: [ '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread', ], }, };
// libwiz.config.js module.exports = { // ... other config compiler: { plugins: [ '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-transform-runtime', ], browsers: ['last 2 versions', 'not dead'], }, };
// libwiz.config.js module.exports = { // ... other config compiler: context => { const { isESM, isCJS } = context; // Different configuration for ESM vs CJS if (isESM) { return { plugins: [ '@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime', ], browsers: ['last 2 versions'], }; } // CommonJS configuration if (isCJS) { return { plugins: ['@babel/plugin-proposal-class-properties'], browsers: ['last 2 versions'], }; } return { plugins: ['@babel/plugin-proposal-class-properties'], }; }, };
// libwiz.config.js module.exports = { // ... other config compiler: context => { const { target } = context; const baseConfig = { plugins: ['@babel/plugin-proposal-class-properties'], }; // Add framework-specific presets based on your needs if (process.env.USE_REACT === 'true') { baseConfig.presets = [['@babel/preset-react', { runtime: 'automatic' }]]; } return baseConfig; }, };
// libwiz.config.js module.exports = { // ... other config compiler: ({ isESM }) => { const baseConfig = { plugins: ['@babel/plugin-proposal-class-properties'], }; // Add tree-shaking optimizations for ESM if (isESM) { return { ...baseConfig, plugins: [ ...baseConfig.plugins, '@babel/plugin-transform-runtime', '@babel/plugin-proposal-export-namespace-from', ], }; } // Add legacy support for CommonJS return { ...baseConfig, plugins: [ ...baseConfig.plugins, '@babel/plugin-proposal-object-rest-spread', ], }; }, };
# Quick start npx libwiz init # Or if you have libwiz installed globally libwiz init
# Build for ESM format only libwiz build --target esm # Build for CommonJS format only libwiz build --target cjs # Build for both formats (default) libwiz build
To create types libwiz needs tsconfig.json or tsconfig.build.json
libwiz build --types
# Type check only (requires tsconfig.json) libwiz types --check # Generate types and type check libwiz types
libwiz dev
libwiz comes with a set of default Babel plugins and presets to simplify your build configuration. If your project doesn't specify these plugins or presets in its configuration, libwiz will automatically use the following versions:
| Plugin/Preset | Default Version |
|---|---|
@babel/core |
7.28.0 |
@babel/preset-env |
7.28.0 |
@babel/preset-typescript |
7.27.1 |
If your project already has any of these plugins or presets installed in either the root node_modules or workspace node_modules, libwiz will automatically use your project's versions. This ensures seamless integration and maintains compatibility with your existing setup.
Note: Framework-specific presets like React, Vue, etc. are not included by default. You can add them to your project dependencies and configure them in your
libwiz.config.jsas needed.
If you need full control over the transpilation process, libwiz offers a customTranspiler option. By using this, you can define a function to handle the transpilation according to your specific requirements. Here's how it works:
- Function Definition:
customTranspilerexpects a function that takes incodeandoptions. - Code Parameter: The
codeparameter is astringcontaining the source code that you want to transpile. - Options Parameter: The
optionsparameter provides useful information for transpilation and includes the following fields:env: Specifies the build environment, such asesmorcjs(from theBundlestype).sourceMaps: Abooleanthat indicates if source maps should be generated.comments: Abooleanthat indicates if comments should be included in the output.
After processing, the customTranspiler function should return an object containing:
code: The transpiled code as astring.map(optional): The source map as astring, if source maps were generated.
If customTranspiler returns nothing, or if it returns invalid data, libwiz will fall back to its default compilation process.
Here's an example of how you might set up customTranspiler in your libwiz.config.js:
module.exports = { // other configurations... customTranspiler: async (code, options) => { const transpiledCode = await myCustomCompile(code, options); // your custom transpile logic const sourceMap = generateSourceMap(transpiledCode); // optional return { code: transpiledCode, map: sourceMap, // return map only if generated }; }, };
When using libwiz build --types to generate TypeScript definition files, libwiz enhances TypeScript's configuration by supporting glob patterns in your tsconfig.json file. This allows you to use modern glob syntax, which TypeScript doesn't support by default.
This feature is specifically for type generation (
--types). For regular builds,libwizalready handles glob patterns through its own configuration system.
Important: libwiz automatically overwrites
outDirandrootDirsettings in your tsconfig.json for optimal type generation. This ensures proper file structure and prevents conflicts with your build configuration.
Brace Expansion:
{ts,tsx}- Multiple extensions in one pattern{test,spec,stories}- Multiple file types{ts,tsx,js,jsx}- Multiple file extensions- Example:
src/**/*.{ts,tsx}matches both .ts and .tsx files
Character Classes:
[jt]s- Match .ts and .js files[jt]sx- Match .tsx and .jsx files- Example:
src/**/*.[tj]smatches .ts and .js files
Negative Patterns:
!- Exclude files (works in include array)!src/**/*.test.{ts,tsx}- Exclude test files using!in include array!src/**/*.spec.{ts,tsx}- Exclude spec files!src/**/*.stories.{ts,tsx}- Exclude story files!src/**/*.{test,spec,stories}.{ts,tsx}- Exclude multiple file types at once
{
"include": [
"src/**/*.[jt]s",
"src/**/*.{ts,js}x",
"!src/**/*.{test,spec}.{ts,tsx}"
],
"exclude": ["src/ignore/**/*.{ts,tsx}", "src/**/*.{doc,example}.{ts,tsx}"]
}Note: If no or empty
excludepatterns are specified in your tsconfig.json, libwiz will automatically use its ownignoreconfiguration as exclude patterns for type generation.
# CLI flag (recommended) libwiz build --quiet # Environment variable LIBWIZ_QUIET=true libwiz build
By default, the progress bar is disabled to keep the output clean. You can enable it using the --progress flag or the LIBWIZ_ENABLE_PROGRESS environment variable.
# CLI flag (recommended) libwiz build --progress # Environment variable LIBWIZ_ENABLE_PROGRESS=true libwiz build