# Chronological guide: Building & Publishing a React Library

# Phase 1: Project Setup

## 1.1 Initialize the Project

```bash
# Create project directory
mkdir my-react-library
cd my-react-library

# Initialize with pnpm
pnpm init
```

## 1.2 Install Dependencies

```bash
# Install React as peer dependencies (users will provide these)
pnpm add react react-dom --save-peer

# Install TypeScript and build tools
pnpm add -D typescript @types/react @types/react-dom tsup

# Install React types for development
pnpm add -D react react-dom
```

## 1.3 Create Basic File Structure

```javascript
my-react-library/
├── src/
│   ├── index.ts
│   └── components/
│       └── HelloWorld.tsx
├── package.json
├── tsconfig.json
├── tsup.config.ts
└── README.md
```

# Phase 2: Create the Component

## 2.1 Create HelloWorld Component

Create `src/components/HelloWorld.tsx`:

```tsx
import React from "react";

interface HelloWorldProps {
  name?: string;
  className?: string;
}

export const HelloWorld: React.FC<HelloWorldProps> = ({
  name = "World",
  className = "",
}) => {
  return (
    <div className={`hello-world ${className}`}>
      <h1>Hello, {name}!</h1>
      <p>This is my first React library component.</p>
    </div>
  );
};
```

## 2.2 Create Main Export File

Create `src/index.ts`:

```ts
export { HelloWorld } from "./components/HelloWorld";
export type { HelloWorldProps } from "./components/HelloWorld";
```

# Phase 3: Configuration Files

## 3.1 TypeScript Configuration

Create `tsconfig.json`:

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["DOM", "DOM.Iterable", "ES6"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "declaration": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
```

## 3.2 Build Configuration

Create `tsup.config.ts`:

```ts
import { defineConfig } from "tsup";

export default defineConfig({
  entry: ["src/index.ts"],
  format: ["cjs", "esm"],
  dts: true,
  splitting: false,
  sourcemap: true,
  clean: true,
  external: ["react", "react-dom"],
});
```

## 3.3 Update package.json

```json
{
  "name": "@yourscope/my-react-library",
  "version": "0.1.0",
  "description": "My first React library",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
      "default": "./dist/index.js"
    }
  },
  "files": ["dist"],
  "scripts": {
    "build": "tsup",
    "dev": "tsup --watch",
    "prepublishOnly": "pnpm build"
  },
  "keywords": ["react", "component", "library", "typescript"],
  "author": "Your Name",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/yourusername/my-react-library"
  },
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.0",
    "@types/react-dom": "^18.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "tsup": "^8.0.0",
    "typescript": "^5.0.0"
  },
  "publishConfig": {
    "access": "public"
  }
}
```

# Phase 4: Build and Test

## 4.1 Build the Library

```bash
# Build the library
pnpm build

# Check the output in dist/
ls -la dist/
```

You should see:

* `index.cjs` (CommonJS)
    
* `index.js` (ESM)
    
* `index.d.ts` (TypeScript definitions)
    
* Source maps
    

## 4.2 Test the Build

```bash
# Test if the package can be imported
node -e "console.log(require('./dist/index.cjs'))"
```

# Phase 5: Create Documentation

## 5.1 Create [README.md](http://README.md)

<details>
  <summary>Example readme</summary>
<h1>My React Library</h1>
<p>A simple React component library.</p>
<h1>Installation</h1>
<pre><code class="language-bash">npm install @yourscope/my-react-library
# or
pnpm add @yourscope/my-react-library</code></pre>
<h1>Usage</h1>
<pre><code class="language-tsx">import { HelloWorld } from "@yourscope/my-react-library";

function App() {
  return (
    <div>
      <HelloWorld name="Developer" />
    </div>
  );
}</code></pre>
<h1>Components</h1>
<h2>HelloWorld</h2>
<p>A simple greeting component.</p>
<h3>Props</h3>
<ul>
<li><code>name?: string</code> -> The name to greet (default: "World")</li>
<li><code>className?: string</code> -> Additional CSS classes</li>
</ul>
<h1>License</h1>
<p>MIT</p>
</details>

# Phase 6: Prepare for Publishing

## 6.1 Create .npmignore

```javascript
src/
tsconfig.json
tsup.config.ts
*.log
node_modules/
.DS_Store
```

## 6.2 Verify Package Contents

```bash
# Check what will be published
pnpm pack --dry-run

# Or create a tarball to inspect
pnpm pack
tar -tzf *.tgz
```

# Phase 7: Publishing

## 7.1 Set Up npm Account

```bash
# Login to npm
pnpm login

# Verify you're logged in
pnpm whoami
```

## 7.2 Publish First Version

```bash
# Make sure everything is built
pnpm build

# Publish to npm
pnpm publish
```

# Phase 8: Version Updates

## 8.1 Making Changes

After making changes to your library:

```bash
# Update version (patch: 0.1.0 -> 0.1.1)
pnpm version patch

# Or minor version (0.1.0 -> 0.2.0)
pnpm version minor

# Or major version (0.1.0 -> 1.0.0)
pnpm version major
```

## 8.2 Publish Updates

```bash
# Build and publish
pnpm build
pnpm publish
```

# Phase 9: Development Workflow

## 9.1 Development Scripts

Add to package.json scripts:

```json
{
  "scripts": {
    "build": "tsup",
    "dev": "tsup --watch",
    "prepublishOnly": "pnpm build",
    "version": "pnpm build && git add dist/",
    "postversion": "git push && git push --tags"
  }
}
```

## 9.2 Testing Locally

To test your library in another project before publishing:

```bash
# In your library directory
pnpm link

# In your test project
pnpm link @yourscope/my-react-library
```

# Quick Reference Commands

```bash
# Setup
pnpm init
pnpm add react react-dom --save-peer
pnpm add -D typescript @types/react @types/react-dom tsup

# Development
pnpm dev          # Watch mode
pnpm build        # Build library

# Publishing
pnpm version patch # Update version
pnpm publish      # Publish to npm

# Testing
pnpm link         # Link for local testing
pnpm pack --dry-run # Check package contents
```
