DEV Community

Abhirup Pal
Abhirup Pal

Posted on

Building a Modern React Library Starter: A Comprehensive Guide

Introduction

Creating a modern React library requires careful consideration of build tools, development experience, and output optimization. This guide will walk you through building a professional React library starter using TypeScript, SWC, and Rollup—a powerful combination that offers superior performance, reliability, and developer experience.

Why These Tools Matter

TypeScript: Type Safety and Developer Experience

  • Static Type Checking: Catch errors during development rather than runtime

  • Enhanced IDE Support: Better autocomplete, refactoring, and code navigation

  • Self-Documenting Code: Types serve as living documentation

  • Improved Maintenance: Makes large codebases more manageable

  • Growing Community: Extensive type definitions for popular libraries

SWC: Next-Generation Compilation

  • Rust-Powered Performance: Up to 20x faster than Babel
  • Drop-in Replacement: Compatible with existing Babel configurations
  • Low Memory Footprint: More efficient resource utilization
  • Native TypeScript Support: Direct compilation without intermediate steps
  • Active Development: Regular updates and improvements

Rollup: Optimized Library Bundling

  • Tree Shaking: Advanced dead code elimination
  • Multiple Output Formats: ESM, CommonJS, and UMD support
  • Smaller Bundle Size: No unnecessary runtime code
  • Plugin Ecosystem: Rich set of official and community plugins
  • Code Splitting: Efficient chunk management

Project Setup Guide

1. Initialize Project Structure

mkdir react-library cd react-library npm init -y # Create essential directories mkdir src 
Enter fullscreen mode Exit fullscreen mode

2. Install Dependencies

# Core dependencies npm install react react-dom --save-peer # Development dependencies npm install --save-dev typescript @types/react @types/react-dom \ @swc/core @swc/helpers \ rollup @rollup/plugin-swc @rollup/plugin-node-resolve \ @rollup/plugin-commonjs rollup-plugin-peer-deps-external 
Enter fullscreen mode Exit fullscreen mode

3. TypeScript Configuration

Create tsconfig.json:

{ "compilerOptions": { "target": "ES2018", "module": "ESNext", "lib": ["DOM", "DOM.Iterable", "ESNext"], "declaration": true, "declarationDir": "dist/types", "emitDeclarationOnly": true, "jsx": "react-jsx", "strict": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "isolatedModules": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true }, "include": ["src"], "exclude": ["node_modules", "dist"] } 
Enter fullscreen mode Exit fullscreen mode

4. Rollup Configuration

Create rollup.config.js:

import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import { swc, defineRollupSwcOption } from '@rollup/plugin-swc'; import peerDepsExternal from 'rollup-plugin-peer-deps-external'; import terser from '@rollup/plugin-terser'; const packageJson = require('./package.json'); const swcConfig = defineRollupSwcOption({ jsc: { parser: { syntax: 'typescript', tsx: true, }, transform: { react: { runtime: 'automatic', development: false, refresh: false, }, }, target: 'es2018', }, minify: false, }); export default [ // ESM build { input: 'src/index.tsx', output: [ { file: packageJson.module, format: 'esm', sourcemap: true, }, ], plugins: [ peerDepsExternal(), resolve({ extensions: ['.ts', '.tsx', '.js', '.jsx'], }), commonjs(), swc(swcConfig), terser(), ], external: ['react', 'react-dom'], }, // CommonJS build { input: 'src/index.tsx', output: [ { file: packageJson.main, format: 'cjs', sourcemap: true, exports: 'auto', }, ], plugins: [ peerDepsExternal(), resolve({ extensions: ['.ts', '.tsx', '.js', '.jsx'], }), commonjs(), swc(swcConfig), terser(), ], external: ['react', 'react-dom'], }, ]; 
Enter fullscreen mode Exit fullscreen mode

5. Package.json Configuration

Update your package.json:

{ "name": "your-library-name", "version": "1.0.0", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "types": "dist/types/index.d.ts", "files": [ "dist" ], "sideEffects": false, "scripts": { "build": "rollup -c", "types": "tsc", "prepare": "npm run types && npm run build", "lint": "eslint ." }, "peerDependencies": { "react": ">=17.0.0 <19.0.0", "react-dom": ">=17.0.0 <19.0.0" }, } 
Enter fullscreen mode Exit fullscreen mode

Writing Library Code

Component Example

Create src/index.tsx:

import React from "react"; export interface HelloProps { name: string; } export default function Hello({ name }: HelloProps) { return <div>Hello {name}!</div>; } 
Enter fullscreen mode Exit fullscreen mode

Best Practices

1. Development Workflow

  • Use Git hooks (husky) for pre-commit linting and testing
  • Implement semantic versioning
  • Set up continuous integration/deployment

2. Documentation

  • Include detailed README.md
  • Provide usage examples
  • Document peer dependencies

3. Performance

  • Keep bundle size minimal
  • Implement tree-shaking friendly exports
  • Avoid runtime dependencies when possible

Publishing

  1. Update version in package.json
  2. Build the library: npm run build
  3. Test the build: npm pack
  4. Publish: npm publish

Add working example

Setup a vite app for providing example, and testing code changes in the repo itself. This can also be done with a storybook.

npm create vite@latest example -- --template react-ts 
Enter fullscreen mode Exit fullscreen mode

add your package in the dependencies section of the example package.json

"react-library-starter": "file:../" 
Enter fullscreen mode Exit fullscreen mode

Import your component and test it in the example project.

Your React library is now ready for publishing! 🎉

If you’d like to dive in with a ready-to-use setup, check out the complete starter template here: https://github.com/Abhirup-99/react-library-starter-template. This template includes everything we’ve covered and is designed to help you kickstart your React library development with minimal setup.

Happy coding!

Top comments (0)