Creating reusable npm packages can make your development process more efficient and enjoyable. In this article, we'll guide you through creating a modern and robust project setup using React, TypeScript, CSS Modules, and other tools. Before we start, you can find the source code here: . This repository serves as a base for creating npm packages using React and TypeScript. It's preconfigured with a build process and a set of recommended packages for a modern development workflow. https://github.com/helgastogova/npm-react-typescript-template The key features include: : Modern UI development with strong type safety and a superior developer experience. React & TypeScript : Styling components in isolation, avoiding CSS conflicts, and enabling modular design. CSS Modules : Ensuring code quality by adhering to JavaScript and React's best practices. ESLint : Efficiently bundling React and TypeScript code into a single file for distribution. Rollup : Utilizing next-gen CSS features and handling browser compatibility. PostCSS : Monitoring your library's size and preventing accidental size bloat. Size Limit Let's dive into each tool more comprehensively. CSS Modules CSS modules serve as a beacon of safety in the realm of styling chaos. They implement local scoping for your styles, warding off conflicts and overlap issues. Each CSS module will be "encapsulated" into the component, ensuring the styles you define won't leak out and affect other elements unintentionally. Consider this simple component where we use CSS Module: // TestComponent.tsx import React from 'react'; import s from './TestComponent.module.css'; type TestComponentProps = { text?: string; }; export const TestComponent: React.FC<TestComponentProps> = ({ text }) => { return <div className={s.root}>{text ?? 'Hello!'}</div>; }; And its associated CSS Module: /* TestComponent.module.css */ .root { background-color: pink; padding: 20px; border-radius: 8px; } In this case, the class from won't affect any other class in a different module. .root TestComponent.module.css .root ESLint is like a lighthouse guiding you through a tumultuous sea of code. It helps maintain code quality, catching errors and enforcing best coding practices before they become problems. ESLint In your , you have: package.json "scripts": { "lint": "eslint './src/**/*.{ts,tsx}'" } Run the linter with . ESLint will scan through your TypeScript files and warn you about any potential issues. This is particularly handy for large codebases where it's easy for small errors or inconsistencies to creep in. npm run lint Rollup is your code's personal fitness trainer. It takes your JavaScript, TypeScript, and CSS and bundles them into one lean, efficient package ready for distribution. Rollup It's lightweight and fast, but the real benefit comes from its "tree-shaking" capability. Rollup can eliminate unused code from the final bundle, making your package as lean as possible. Here's an example of how your Rollup configuration might look: // rollup.config.js const postcss = require('rollup-plugin-postcss'); const typescript = require('@rollup/plugin-typescript'); const peerDepsExternal = require('rollup-plugin-peer-deps-external'); const resolve = require('@rollup/plugin-node-resolve').default; const commonjs = require('@rollup/plugin-commonjs'); module.exports = { input: 'src/index.tsx', output: { dir: 'dist', format: 'cjs', sourcemap: true, }, plugins: [ peerDepsExternal(), resolve(), typescript(), commonjs(), postcss({ modules: true, }), ], }; PostCSS is like a time-traveler, allowing you to write CSS using future syntax and features. It then travels back in time (so to speak), transforming these modern styles into code that even older browsers can understand. PostCSS You can see PostCSS in action in the Rollup configuration above. Using the , your modern CSS is transformed and included in your final bundle. The beauty of this is that you can write CSS using the latest features without worrying about browser compatibility. rollup-plugin-postcss Size Limit is the ever-vigilant watchman, making sure your library doesn't get too bloated. It calculates the real cost of your library by adding both the JavaScript and CSS that will be downloaded by users. It's a valuable tool to help you keep your bundle size in check. Size Limit In your : package.json "scripts": { "size": "size-limit", }, "size-limit": [ { "path": "dist/*.js", "limit": "10 KB" } ] You can then run to check the size of your bundle. If it exceeds the limit you've set (in this case, 10 KB), the script will throw an error. It's a great way to ensure you're not unknowingly adding to your users' download times. npm run size Setup To start using this template, clone the repository: git clone https://github.com/helgastogova/npm-react-typescript-template.git Navigate into the directory: cd npm-react-typescript-template Install the dependencies: npm install You're all set to start developing your package! The entry point is src/index.tsx Building the Package After creating your own component and when you're ready to build your package for distribution, run: npm run build Your built package will be in the directory, ready for publishing to npm. dist Publishing to npm Ensure that you've set the field in your to your desired package name. Also, remember to update the version number before each new publish. Once that's done, log in to npm using: name package.json npm login Enter your username, password, and email. Once logged in, you can publish your package with: npm publish Now you have published your component in the , and people can start using it. You are awesome! npmjs library Happy coding!