UPDATE: You can use the npm package create-component-lib to automate all the steps described in this blog post. create-component-lib Create React App is easily the best tool for creating and developing React applications. With a little bit of work, it can also be used to create a library of React components that can be published to npm and used in other React applications. Here's what you need to do: 1. Create a new project using create-react-app: create-react-app simple-component-library 2. Delete all the files inside src/, and create a new index.js file with some starter code: import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(<div>Hello world</div>, document.getElementById("root")); 3. Create a new folder src/lib and place your React components inside it. src/lib will serve as the root folder of the module published to npm. Here’s the code for an example component: import React from "react"; import "./TextInput.css"; const TextInput = ({ type = "text", label, value, onChange }) => ( <div className="simple-form-group"> {label && <label className="simple-text-label">{label}</label>} <input type={type} className="simple-text-input" value={value} onChange={e => onChange && onChange(e.target.value)} /> </div> ); export default TextInput; Styling can be done inline, or in separate CSS files: .simple-form-group { margin-bottom: 1rem; } .simple-text-label { display: block; color: red; } .simple-text-input { display: inline-block; margin-bottom: 0.5rem; font-size: 16px; font-weight: 400; color: rgb(33, 37, 41); } Finally, the component can be exported from src/lib for ease of importing: import TextInput from "./TextInput"; export { TextInput }; Optionally, you can also write tests for the components inside src/lib: import React from "react"; import TextInput from "./TextInput"; import renderer from "react-test-renderer"; describe("TextInput", () => { it("renders properly", () => { const tree = renderer .create(<TextInput label="Email" placeholder="name@example.com" />) .toJSON(); expect(tree).toMatchSnapshot(); }); }); 4. (Optional) Use the components in src/index.js to create examples for testing and debugging during development. Any code placed outside src/lib will not be published to npm. Here is an example usage of TextInput: import React from 'react'; import { render } from "react-dom"; import { TextInput } from "./lib"; const App = () => ( <div style={{ width: 640, margin: "15px auto" }}> <h1>Hello React</h1> <TextInput label="Email Address" placeholder="name@example.com" /> </div> ); render(<App />, document.getElementById("root")); Run npm start and navigate to http://localhost:3000 to view the result. It works (duh!) Tip: Use react-live to create a live-editable documentation site! 5. Install babel-cli using the command npm i babel-cli --save-dev and create a file .babelrc in the root of the project with the following contents: { "presets": [["react-app", { "absoluteRuntime": false }]] } 6. Replace the build script inside package.json with the following: "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files --ignore __tests__,spec.js,test.js,__snapshots__" The command npm run build will now transpile the code inside src/lib (ignoring tests and snapshots) into the folder dist. 7. Remove the line "private": true from package.json. Also remove react-scripts, react and react-dom from dependencies, and move them to devDependencies. Additionally, you can also add react and react-dom to peerDependencies. 8. To prepare for publishing, add the following lines to package.json: "main": "dist/index.js", "module": "dist/index.js", "files": [ "dist", "README.md" ], "repository": { "type": "git", "url": "URL_OF_YOUR_REPOSITORY" } 9. Remove the default README.md file, and create a new one with some information about the library. # simple-component-library A library of React components created using `create-react-app`.## Installation Run the following command: `npm install simple-component-library` 10. Publish to npm! npm run publish And that’s it! Now you can install the library with the command npm install simple-component-library and use it in any project created using Create React App. Here’s the full code for this article: aakashns/simple-component-library You can clone the repository and use it as a starting point to skip some of the steps. Hope it helps! UPDATE : You can use the npm package create-component-lib to automate all the steps described in this blog post. UPDATE create-component-lib create-component-lib create-component-lib create-component-lib create-component-lib create-component-lib Create React App is easily the best tool for creating and developing React applications. With a little bit of work, it can also be used to create a library of React components that can be published to npm and used in other React applications. Here's what you need to do: Create React App npm npm 1. Create a new project using create-react-app : create-react-app create-react-app create-react-app simple-component-library create-react-app simple-component-library create-react-app simple-component-library create-react-app simple-component-library 2. Delete all the files inside src/ , and create a new index.js file with some starter code: src/ src/ index.js index.js import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(<div>Hello world</div>, document.getElementById("root")); import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(<div>Hello world</div>, document.getElementById("root")); import React from "react" ; import ReactDOM from "react-dom" ; ReactDOM.render( < div > Hello world </ div > , document .getElementById( "root" )); import React from "react" ; import ReactDOM from "react-dom" ; ReactDOM.render( < div > Hello world </ div > , document .getElementById( "root" )); 3. Create a new folder src/lib and place your React components inside it. src/lib will serve as the root folder of the module published to npm . Here’s the code for an example component: src/lib src/lib src/lib src/lib npm npm import React from "react"; import "./TextInput.css"; const TextInput = ({ type = "text", label, value, onChange }) => ( <div className="simple-form-group"> {label && <label className="simple-text-label">{label}</label>} <input type={type} className="simple-text-input" value={value} onChange={e => onChange && onChange(e.target.value)} /> </div> ); export default TextInput; import React from "react"; import "./TextInput.css"; const TextInput = ({ type = "text", label, value, onChange }) => ( <div className="simple-form-group"> {label && <label className="simple-text-label">{label}</label>} <input type={type} className="simple-text-input" value={value} onChange={e => onChange && onChange(e.target.value)} /> </div> ); export default TextInput; import React from "react" ; import "./TextInput.css" ; const TextInput = ( { type = "text" , label, value, onChange } ) => ( < div className = "simple-form-group" > {label && < label className = "simple-text-label" > {label} </ label > } < input type = {type} className = "simple-text-input" value = {value} onChange = {e => onChange && onChange(e.target.value)} /> </ div > ); export default TextInput; import React from "react" ; import "./TextInput.css" ; const TextInput = ( { type = "text" , label, value, onChange } ) => ( < div className = "simple-form-group" > {label && < label className = "simple-text-label" > {label} </ label > } < input type = {type} className = "simple-text-input" value = {value} onChange = {e => onChange && onChange(e.target.value)} /> </ div > export default TextInput; Styling can be done inline, or in separate CSS files: .simple-form-group { margin-bottom: 1rem; } .simple-text-label { display: block; color: red; } .simple-text-input { display: inline-block; margin-bottom: 0.5rem; font-size: 16px; font-weight: 400; color: rgb(33, 37, 41); } .simple-form-group { margin-bottom: 1rem; } .simple-text-label { display: block; color: red; } .simple-text-input { display: inline-block; margin-bottom: 0.5rem; font-size: 16px; font-weight: 400; color: rgb(33, 37, 41); } .simple-form-group { margin-bottom: 1rem; } .simple-text-label { display : block; color: red; } .simple-text-input { display : inline-block; margin-bottom: 0. 5rem; font-size: 16px; font-weight: 400 ; color: rgb( 33 , 37 , 41 ); } .simple-form-group { display : block; display : inline-block; margin-bottom: 0. 5rem; font-weight: 400 ; color: rgb( 33 , 37 , 41 ); Finally, the component can be exported from src/lib for ease of importing: src/lib src/lib import TextInput from "./TextInput"; export { TextInput }; import TextInput from "./TextInput"; export { TextInput }; import TextInput from "./TextInput" ; export { TextInput }; import TextInput from "./TextInput" ; export { TextInput }; Optionally, you can also write tests for the components inside src/lib : write tests src/lib src/lib import React from "react"; import TextInput from "./TextInput"; import renderer from "react-test-renderer"; describe("TextInput", () => { it("renders properly", () => { const tree = renderer .create(<TextInput label="Email" placeholder="name@example.com" />) .toJSON(); expect(tree).toMatchSnapshot(); }); }); import React from "react"; import TextInput from "./TextInput"; import renderer from "react-test-renderer"; describe("TextInput", () => { it("renders properly", () => { const tree = renderer .create(<TextInput label="Email" placeholder="name@example.com" />) .toJSON(); expect(tree).toMatchSnapshot(); }); }); import React from "react" ; import TextInput from "./TextInput" ; import renderer from "react-test-renderer" ; describe( "TextInput" , () => { it( "renders properly" , () => { const tree = renderer .create( < TextInput label = "Email" placeholder = "name@example.com" /> ) .toJSON(); expect(tree).toMatchSnapshot(); }); }); import React from "react" ; import TextInput from "./TextInput" ; import renderer from "react-test-renderer" ; describe( "TextInput" , () => { it( "renders properly" , () => { const tree = renderer .create( < TextInput label = "Email" placeholder = "name@example.com" /> ) 4. (Optional) Use the components in src/index.js to create examples for testing and debugging during development. Any code placed outside src/lib will not be published to npm . Here is an example usage of TextInput : (Optional) src/index.js src/index.js src/lib src/lib npm npm TextInput TextInput import React from 'react'; import { render } from "react-dom"; import { TextInput } from "./lib"; const App = () => ( <div style={{ width: 640, margin: "15px auto" }}> <h1>Hello React</h1> <TextInput label="Email Address" placeholder="name@example.com" /> </div> ); render(<App />, document.getElementById("root")); import React from 'react'; import { render } from "react-dom"; import { TextInput } from "./lib"; const App = () => ( <div style={{ width: 640, margin: "15px auto" }}> <h1>Hello React</h1> <TextInput label="Email Address" placeholder="name@example.com" /> </div> ); render(<App />, document.getElementById("root")); import React from 'react' ; import { render } from "react-dom" ; import { TextInput } from "./lib" ; const App = () => ( < div style = {{ width: 640 , margin: " 15px auto " }}> < h1 > Hello React </ h1 > < TextInput label = "Email Address" placeholder = "name@example.com" /> </ div > ); render( < App /> , document .getElementById( "root" )); import React from 'react' ; import { render } from "react-dom" ; import { TextInput } from "./lib" ; const App = () => ( < div style = {{ width: 640 , margin: " 15px auto " }}> < h1 > Hello React </ h1 > < TextInput label = "Email Address" placeholder = "name@example.com" /> </ div > render( < App /> , document .getElementById( "root" )); Run npm start and navigate to http://localhost:3000 to view the result. npm start npm start http://localhost:3000 http://localhost:3000 It works (duh!) Tip: Use react-live to create a live-editable documentation site! react-live react-live react-live 5. Install babel-cli using the command npm i babel-cli --save-dev and create a file .babelrc in the root of the project with the following contents: babel-cli babel-cli babel-cli npm i babel-cli --save-dev npm i babel-cli --save-dev .babelrc .babelrc { "presets": [["react-app", { "absoluteRuntime": false }]] } { "presets": [["react-app", { "absoluteRuntime": false }]] } { "presets" : [[ "react-app" , { "absoluteRuntime" : false }]] } { "presets" : [[ "react-app" , { "absoluteRuntime" : false }]] 6. Replace the build script inside package.json with the following: build build package.json package.json "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files --ignore __tests__,spec.js,test.js,__snapshots__" "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files --ignore __tests__,spec.js,test.js,__snapshots__" "build" : "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files --ignore __tests__,spec.js,test.js,__snapshots__" "build" : "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files --ignore __tests__,spec.js,test.js,__snapshots__" The command npm run build will now transpile the code inside src/lib (ignoring tests and snapshots) into the folder dist . npm run build npm run build src/lib src/lib dist dist 7. Remove the line "private": true from package.json . Also remove react-scripts , react and react-dom from dependencies, and move them to devDependencies . Additionally, you can also add react and react-dom to peerDependencies . "private": true "private": true package.json package.json react-scripts react-scripts devDependencies devDependencies devDependencies react react react-dom react-dom peerDependencies peerDependencies peerDependencies 8. To prepare for publishing, add the following lines to package.json : package.json package.json "main": "dist/index.js", "module": "dist/index.js", "files": [ "dist", "README.md" ], "repository": { "type": "git", "url": "URL_OF_YOUR_REPOSITORY" } "main": "dist/index.js", "module": "dist/index.js", "files": [ "dist", "README.md" ], "repository": { "type": "git", "url": "URL_OF_YOUR_REPOSITORY" } "main" : "dist/index.js" , "module" : "dist/index.js" , "files" : [ "dist" , "README.md" ], "repository" : { "type" : "git" , "url" : "URL_OF_YOUR_REPOSITORY" } "main" : "dist/index.js" , "module" : "dist/index.js" , "files" : [ "dist" , "README.md" ], "repository" : { "type" : "git" , "url" : "URL_OF_YOUR_REPOSITORY" 9. Remove the default README.md file, and create a new one with some information about the library. README.md README.md # simple-component-library A library of React components created using `create-react-app`.## Installation Run the following command: `npm install simple-component-library` # simple-component-library A library of React components created using `create-react-app`.## Installation Run the following command: `npm install simple-component-library` # simple-component-library A library of React components created using `create-react-app` .## Installation Run the following command: `npm install simple-component-library` # simple-component-library A library of React components created using `create-react-app` .## Installation `npm install simple-component-library` 10. Publish to npm ! Publish to npm npm npm npm run publish npm run publish npm run publish npm run publish And that’s it! Now you can install the library with the command npm install simple-component-library and use it in any project created using Create React App. Here’s the full code for this article: npm install simple-component-library npm install simple-component-library aakashns/simple-component-library aakashns/simple-component-library aakashns/simple-component-library You can clone the repository and use it as a starting point to skip some of the steps. Hope it helps!