libwiz
v1.0.0
Published
A powerful CLI tool for building modern JavaScript and TypeScript libraries
Readme
libwiz
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.
Features
- 📦 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.
Installation
# Install globally
npm install -g libwiz
# Or add as dev dependency
npm install --save-dev libwizUsage
Commands
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).
Basic Usage
# 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 cjsQuick Start with init
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 initThis 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.
Options
| 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 |
Configuration
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!
Config Schema Overview
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.
Example Configuration
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',
};Output Configuration Examples
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 Output Configuration
// Simple string path
{
output: './dist'
}
// Object with basic settings
{
output: {
dir: './dist',
target: 'esm',
sourceMap: true
}
}Advanced Configuration with Lib Overrides
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
}
}
}
}Adding React Support
To add React support to your library:
Install React preset:
npm install --save-dev @babel/preset-reactAdd 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', ], }, };
Advanced Compiler Configuration Examples
Static Compiler Configuration (Object)
// 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'],
},
};Dynamic Compiler Configuration (Function)
// 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'],
};
},
};Conditional Configuration Based on Environment
// 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;
},
};Conditional Plugin Loading
// 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',
],
};
},
};Examples
Getting started with a new project
# Quick start
npx libwiz init
# Or if you have libwiz installed globally
libwiz initBuilding for specific formats
# Build for ESM format only
libwiz build --target esm
# Build for CommonJS format only
libwiz build --target cjs
# Build for both formats (default)
libwiz buildGenerating build with TypeScript definition files
To create types libwiz needs tsconfig.json or tsconfig.build.json
libwiz build --typesType checking without file generation
# Type check only (requires tsconfig.json)
libwiz types --check
# Generate types and type check
libwiz typesRunning in watch mode
libwiz devDefault Babel Plugins and Presets
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.
Using customTranspiler for Custom Transpilation
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.
Example Usage
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
};
},
};TypeScript Configuration for Type Generation
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.
Glob Pattern Examples
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
Usage in tsconfig.json
{
"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.
How to Suppress All Logs (Helpful for CI/CD)?
# CLI flag (recommended)
libwiz build --quiet
# Environment variable
LIBWIZ_QUIET=true libwiz buildHow to Enable Progress Bar?
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