In this guide, I’ll walk you through exactly how I created a shareable React component library from setup to publishing, complete with real code examples, clear explanations, and practical tips. Everything you need is right here in one place.
Use Case
Maintaining multiple React projects with variations of the same UI components presented significant challenges for our team. We encountered frequent issues such as inconsistent styling, duplicated bug fixes, and difficulties in propagating enhancements across codebases. This approach led to inefficiencies, unnecessary overhead, and a lack of coherence in user experience.
To address these challenges, we developed a centralizedReusable Component Library, a standardized collection of UI components designed for use across all our React projects. By consolidating our shared components into a single, well-maintained package, we significantly reduced development redundancy and ensured visual and behavioral consistency throughout our applications. Updates or improvements made to the component library are seamlessly integrated wherever the library is used, streamlining maintenance and accelerating development cycles.
1. Set Up Your Project Folder
First, create a new folder for your component library and initialize it:
mkdir my-react-component-library
cd my-react-component-library
npm init -y
With your project folder in place, you have established a solid foundation for the steps ahead.
2. Install Essential Dependencies
Install React, TypeScript, and essential build tools for a robust library setup:
npm install react react-dom npm install --save-dev typescript @types/react @types/react-dom npm install --save-dev rollup rollup-plugin-peer-deps-external rollup-plugin-postcss @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript sass
The right dependencies are now in place, ensuring your project is equipped for modern development and efficient bundling.
3. Organize Your Project Structure
Establish a clear and logical directory structure for your components and outputs:
4. Write Your Component
Develop a simple reusable React component as a starting point for your library:
import React from 'react'; import styles from './HelloWorld.module.scss'; type HelloWorldProps = { name: string; }; export const HelloWorld: React.FC<HelloWorldProps> = ({ name }) => ( <div className={styles.centerScreen}> <div className={styles.card}> <span className={styles.waveEmoji}></span> <div className={styles.textBlock}> <span className={styles.helloSmall}>Hello,</span> <span className={styles.name}>{name}</span> </div> </div> </div> );
Having your first component ready sets the stage for further expansion and consistent styling across your library.
5. Set Up TypeScript
Configure TypeScript for optimal type safety and the generation of type declarations:
{ "compilerOptions": { "declaration": true, "declarationDir": "dist/types", "emitDeclarationOnly": false, "jsx": "react", "module": "ESNext", "moduleResolution": "node", "outDir": "dist", "rootDir": "src", "target": "ES6", "strict": true, "esModuleInterop": true }, "include": ["src"] }
TypeScript is now fully configured, bringing type safety and easy downstream integration for consumers.
6. Create an Index Export
Make src/index.ts like this:
export { HelloWorld } from './HelloWorld';
7. Add a Type Declarations File
Enable TypeScript to recognize SCSS module imports and prevent type errors:
declare module '*.module.scss' { const classes: { [key: string]: string }; export default classes; }
With declaration files in place, your styling workflow integrates smoothly with TypeScript.
8. Configure Rollup
Set up Rollup for reliable library bundling and versatile output formats:
import peerDepsExternal from "rollup-plugin-peer-deps-external"; import postcss from "rollup-plugin-postcss"; import resolve from "@rollup/plugin-node-resolve"; import commonjs from "@rollup/plugin-commonjs"; import typescript from "@rollup/plugin-typescript"; export default { input: "src/index.ts", output: [ { file: "dist/index.js", format: "cjs", sourcemap: true, }, { file: "dist/index.esm.js", format: "esm", sourcemap: true, }, ], plugins: [ peerDepsExternal(), resolve(), commonjs(), typescript({ tsconfig: "./tsconfig.json" }), postcss({ modules: true, use: ["sass"], }), ], external: ["react", "react-dom"], };
9. Update package.json
Reference all build outputs and dependencies accurately in your package.json.:
{ "main": "dist/index.js", "module": "dist/index.esm.js", "types": "dist/types/index.d.ts", "files": [ "dist" ], "scripts": { "build": "rollup -c" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" } }
Your package metadata is set, paving the way for effortless installation and use.
10. Build the Package
Trigger Rollup to bundle your components:
npm run build
With a completed build, your library files are now ready for distribution.
11. Publishing to Azure Artifacts npm Registry
a) Set up your Azure Artifacts Feed
Go to Azure DevOps > Artifacts and create (or use) an npm feed.
b) Configure npm for Azure Artifacts
In your project root, create or update a .npmrc file with:
@yourscope:registry=https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/npm/registry/ always-auth=true
Replace @yourscope, yourorg, and yourfeed with your actual values.
c) Authenticate Locally
Use Azure's instructions for authentication, such as:
npm login --registry=https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/npm/registry/
In some setups, especially on Windows, you might need to install and run vsts-npm-auth to complete authentication.
d ) Build Your Package
Ensure your package is built and ready to publish (e.g., run npm run build if you have a build step.
e ) Publish Your Package
From the project root, run:
npm publish
And just like that, your component library is available in your Azure feed for your team or organization to install and use!
If you’d prefer to publish to the public npm registry, follow these steps:
12. Publishing to NPM
Prerequisites
- You already built your library (dist/ exists, with all outputs, after running npm run build).
- You have an npmjs.com account.
a) Log in to npm
In your terminal, from the root of your project, type:
npm login
Enter your npm username, password, and email when prompted.
b) Publish
Publish the package:
npm publish
After publishing to npmjs.com, you’ll want to showcase your package’s availability directly from your npm dashboard.
Instructions:
Go to npmjs.com and log in to your account.
Click on your username (top-right) and select Packages from the dropdown.
Find and click your newly published package.
Seeing your package live in npm’s dashboard is a proud milestone—your code is now out there, ready to make life easier for every developer who needs it!
Once published, your component library is available for installation in any compatible React project.
install the library in any React project:
npm install your-package-name
Output:
Below is an example of what you'll see after successfully publishing your package to npm. This confirmation means your component library can now be installed and used in any of your React projects.
Troubleshooting/Common Tips:
- Instructions: If the package name + version already exists on npm, bump your version in package.json.
- Make sure your main, module, and types fields point to valid files in your dist/ directory (you’ve already done this!).
- Check .npmignore or the "files" section in package.json so only necessary files are published.
Conclusion:
- Speed up development: No more duplicating code between projects.
- Guarantee consistency: All your apps share the same reliable components.
- Simplify updates: Bug fixes or enhancements are made once and shared everywhere.
- Easily distribute privately or publicly: Works with both internal feeds (like Azure Artifacts) and public npm.
No comments:
Post a Comment