Step‑by‑Step Guide to Building and Publishing a React Component Library with CRA, Docz, and Netlify
This article provides a comprehensive, step‑by‑step tutorial on creating, documenting, and publishing a React component library using create‑react‑app, TypeScript, docz, npm linking, and Netlify, covering configuration, build scripts, on‑demand loading, and deployment best practices.
Building a component library may sound simple, but it involves many technical details such as Webpack configuration, Markdown-to‑Vue conversion, unit testing, and on‑demand loading. This guide walks through the entire process using widely‑used tools.
The tutorial uses create‑react‑app as the base scaffold, adds TypeScript , configures ESLint , and sets up a basic file structure for styles and components. Example initialization:
npx create-react-app myapp --typescriptNode version should be >10.15.0. After creating the project, add an .env file with EXTEND_ESLINT=true to enable ESLint.
The library’s source layout includes a styles folder with variables.scss , mixins.scss , and index.scss , and a components folder where each component (e.g., Button ) contains its own .tsx , .scss , .mdx , and test files.
|-styles
| |-variables.scss // variables and configurable settings
| |-mixins.scss // global mixins
| |-index.scss // entry point for all styles
|-components
| |-Button
| |-button.scss // component style
| |-button.mdx // component documentation
| |-button.tsx // component code
| |-button.test.tsx // unit test
| |-index.tsx // component export
| |-index.tsx // library entryInstall node‑sass to compile SCSS:
npm i node-sass -DFor building the library, create tsconfig.build.json to compile .tsx files and add scripts for cleaning, building TypeScript, and building CSS:
{
"compilerOptions": {
"outDir": "dist",
"module": "esnext",
"target": "es5",
"declaration": true,
"jsx": "react",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["src"],
"exclude": ["src/**/*.test.tsx", "src/**/*.stories.tsx", "src/setupTests.ts"]
}Compile SCSS to CSS with a script entry:
"script":{
"build-css": "node-sass ./src/styles/index.scss ./dist/index.css"
}Update the build command:
"script":{
"clean": "rimraf ./dist",
"build": "npm run clean && npm run build-ts && npm run build-css"
}After building, the library produces JS and CSS files ready for consumption.
To debug locally, use npm link to connect the library with a demo project, avoiding version conflicts of React. The steps are:
Run npm link inside the library folder.
Run npm link ../../demo/node_modules/react to link the demo’s React copy.
In the demo project, run npm link reactui .
Publish the library to npm after logging in ( npm adduser ) and configuring package.json with main , module , types , files , dependencies , and especially peerDependencies for react and react-dom (>=16.8.0).
{
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"dependencies": {"axios": "^0.19.1", "classnames": "^2.2.6", "react-transition-group": "^4.3.0"},
"peerDependencies": {"react": ">=16.8.0", "react-dom": ">=16.8.0"}
}For documentation, the author compares Storybook and Docz , choosing Docz for its simplicity. Install Docz and add scripts:
npm install docz {
"scripts": {
"docz:dev": "docz dev",
"docz:build": "docz build",
"docz:serve": "docz build && docz serve"
}
}Create doczrc.js to configure source files, output directory, title, TypeScript support, theme directory, and menu:
export default {
files: ['./src/components/**/*.mdx', './src/*.mdx'],
dest: 'docsite',
title: 'Component Library',
typescript: true,
themesDir: 'theme',
menu: ['Quick Start', 'Business Components']
}Customize the Docz theme by overriding the Header component and its styles in a theme/gatsby-theme-docz folder, allowing logo changes and other UI tweaks.
Deploy the generated documentation either via GitHub Pages (adjusting the path to docsite ) or, more conveniently, using Netlify . Netlify automatically builds from the repository and provides a custom domain option.
To enable on‑demand component loading, the guide first suggests babel-plugin-import with a configuration that rewrites imports to the library’s dist/components path. Example:
"plugins": [
["import", {
"libraryName": "reactui",
"libraryDirectory": "dist/components",
"camel2DashComponentName": false,
"style": true
}]
]Alternatively, leverage Webpack’s tree shaking by setting "sideEffects": false in package.json , but exclude SCSS files to keep styles:
"sideEffects": ["*.scss"]For style‑on‑demand loading, each component’s index.tsx imports its SCSS file. The author provides a Node‑Sass script that compiles each component’s SCSS into a separate file in the dist folder, preserving the original file name but with a .scss extension, allowing consumers to import styles automatically.
// Core function to compile SCSS per component
function createCss(name) {
const lowerName = name.toLowerCase();
sass.render({
file: currPath(`../src/components/${name}/${lowerName}.scss`),
outputStyle: 'compressed',
sourceMap: true,
}, (err, result) => {
if (err) console.log(err);
const stylePath = `../dist/components/${name}/`;
fs.writeFile(currPath(`${stylePath}/${lowerName}.scss`), result.css, function(err) {
if (err) console.log(err);
});
});
}The article concludes that the entire process—from scaffolding with CRA, documenting with Docz, deploying with Netlify, to publishing on npm and enabling on‑demand loading—provides a solid foundation for building a reusable React component library.
JD Retail Technology
Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.