Create and Publish Component Library to npm : ReactJS (Step by Step Guide)
A complete guide for beginners on creating and sharing reusable React components with RollUp.
Creating a React component library offers a powerful way to reuse code, maintain consistency across projects, and accelerate development. This article provides a step-by-step guide to building and publishing your own React component library to NPM, empowering you to share and reuse your custom components efficiently.
1. Project Creation
Create a folder inside which you want to create your library.
Inside that, run npm init
and provide details about your library, like name, description version etc.
2. Setting Up Your Project
Directory Structure:
π src
π components
π Text
ποΈ index.jsx
π Button
ποΈ index.jsx
ποΈ index.js
This structure organizes your components within the src
directory, with each component residing in its own folder containing an index.jsx
file. The main index.js
file acts as the entry point for your library, exporting all the individual components.
From src/index.js
export all of your components like this:
export {default as Toast} from "src/components/toast";
export * as Text from "src/components/text"; //for named export
3. Essential Packages:
The following packages are crucial for building a modern React component library:
- Babel: A JavaScript transpiler that converts modern JavaScript (ES6+, JSX) into browser-compatible code (ES5).
@babel/core
: The core Babel compiler.@babel/preset-env
: A Babel preset that configures Babel to transpile code based on the target environment.@babel/preset-react
: A Babel preset for transforming JSX syntax into JavaScript.- Rollup: A module bundler that efficiently bundles your code into optimized output files.
rollup
: The core Rollup bundler.@rollup/plugin-babel
: Integrates Babel with Rollup.@rollup/plugin-commonjs
: Allows Rollup to handle CommonJS modules (used by some libraries).@rollup/plugin-node-resolve
: Enables Rollup to locate and resolve dependencies fromnode_modules
.@rollup/plugin-image
: Handles image imports.rollup-plugin-postcss
: Processes CSS files, including CSS Modules.- Optional Packages:
@rollup/plugin-terser
: Minifies the bundled code for production.
4. Configuring package.json
Modify your package.json
file to prepare it for library creation:
"type": "module",
- Setting
"type": "module"
enables ES module syntax (import
/export
) in your project, allowing for better tree-shaking and optimization by bundlers. It also simplifies working with modern JavaScript features. - Main and Module Entry Points:
"main": "dist/index.js", // For CommonJS
"module": "dist/index.esm.js", // For ESM
"files": ["dist" ],
main
: Specifies the entry point for CommonJS consumers of your library.module
: Specifies the entry point for ES module consumers.files
: Defines which files/folders are included in the published npm package (crucially, this should only be thedist
folder).
5 . Build Script:
scripts": {
"build": "rollup -c",
"prepare": "npm run build"
}
- The
build
script runs Rollup to bundle your library, and theprepare
script ensures the build process runs before publishing to NPM.
6 . Peer Dependencies:
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
},
peerDependencies
lists the dependencies that your library expects the consuming project to have. This avoids bundling React and React DOM within your library, preventing conflicts and reducing bundle size.
7 . Rollup Configuration (rollup.config.js
)
Create a rollup.config.js
file in the root of your project to configure Rollup:
import babel from "@rollup/plugin-babel";
import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import postcss from "rollup-plugin-postcss";
import terser from "@rollup/plugin-terser";
import image from "@rollup/plugin-image";
export default {
input: "src/index.js",
output: [
{
file: "dist/index.js",
format: "cjs",
plugins: [terser()], // Minify CJS output
},
{
file: "dist/index.esm.js",
format: "esm",
plugins: [terser()], // Minify ESM output
},
],
plugins: [
resolve({
extensions: ['.js', '.jsx', '.ts', '.tsx'],
}),
commonjs(),
image(),
babel({
exclude: "node_modules/**",
babelHelpers: "bundled",
presets: ["@babel/preset-react"], // Babel preset for JSX
}),
postcss(),
],
external: ["react", "react-dom"], // Don't bundle React and React DOM
};
This configuration defines the input file, output formats (CJS and ESM), plugins (Babel, CommonJS, Node Resolve, PostCSS, Terser, Image), and external dependencies (React, React DOM). The order of plugins is crucial; resolve
should usually come before babel
.
8. Babel Configuration (babel.config.cjs
)
Rename babel.config.js
to babel.config.cjs
and configure Babel:
JavaScript
module.exports = {
presets: ["@babel/preset-env", ["@babel/preset-react", {runtime:'automatic'}],
};
This configuration specifies the presets for Babel to use: @babel/preset-env
for environment-based transpilation and @babel/preset-react
for JSX transformation.
9. Building and Publishing
- Run
npm run build
to create the bundled files in thedist
directory. - Run
npm publish
to publish your component library to NPM.
Do let me know in the comments if you have any suggestions.