Skip to content

byverdu/ui-library

Repository files navigation

UI Library

A modern React component library built with TypeScript, esbuild, and Material-UI (MUI). A Dev mode is also available where you can see the changes and test components in the playground, is built with vite. This library provides reusable UI components, hooks, exports MUI components and theming solutions that can be consumed by multiple applications.

πŸ“¦ What's Included

  • Using esbuild as the bundler for fast, efficient builds
  • Supporting subpath exports for granular imports
  • Providing independent component bundling
  • Components: Reusable React components built on top of MUI
  • Hooks: Custom React hooks for common functionality
  • Theme: Centralized theming system with MUI integration and a custom theme provider
  • MUI Re-exports: Direct access to MUI components without duplicate dependencies
  • Dev mode: A playground where you can see the changes and test components

πŸ›  Bundler Choice: esbuild

esbuild over other bundlers because:

Advantages over Webpack

  • 10-100x faster build times
  • Simpler configuration
  • Better tree-shaking
  • Native ES modules support

Advantages over Vite

  • More predictable output structure
  • Better support for library builds
  • No virtual modules issues (Vite creates _virtuals folders)

Advantages over Rollup

  • Significantly faster builds
  • Built-in TypeScript support
  • Less configuration complexity

πŸ“ Project Structure

src/
β”œβ”€β”€ index.ts              # Main entry point
β”œβ”€β”€ lib/                  # Reusable components
β”‚   β”œβ”€β”€ AppBar/
β”‚   β”œβ”€β”€ Checkbox/
β”‚   β”œβ”€β”€ IconButton/
β”‚   └── Logo/
β”œβ”€β”€ hooks/                # Custom React hooks
β”‚   β”œβ”€β”€ useGetBoundingClientRect.tsx
β”‚   └── useSetTabTitle.tsx
β”œβ”€β”€ theme/                # Theming system
β”‚   β”œβ”€β”€ ThemeProvider.tsx
β”‚   β”œβ”€β”€ theme.ts
β”‚   └── types.ts
└── mui/                  # MUI re-exports
    └── index.ts

πŸ”§ Installation & Usage

Installing the Library

npm install @your-org/ui-library
# or
pnpm add @your-org/ui-library
# or
yarn add @your-org/ui-library

Basic Usage

// Import everything from main entry
import { AppBar, Checkbox, ThemeProvider, MUI } from '@your-org/ui-library';

// Or use subpath imports for better tree-shaking
import AppBar from '@your-org/ui-library/lib/AppBar';
import { AppBar } from '@your-org/ui-library/lib';
import { useSetTabTitle } from '@your-org/ui-library/hooks';
import { ThemeProvider } from '@your-org/ui-library/theme';
import { Button } from '@your-org/ui-library'; // Re-exported MUI components

πŸ“¦ Subpath Exports

The library supports granular imports through subpath exports:

// Components
import { AppBar } from '@your-org/ui-library/lib/AppBar';
import { Checkbox } from '@your-org/ui-library/lib/Checkbox';

// Hooks
import { useSetTabTitle } from '@your-org/ui-library/hooks';

// Theme
import { ThemeProvider } from '@your-org/ui-library/theme';

// MUI components (re-exported to avoid duplication)
import { MUIBox } from '@your-org/ui-library/mui';

// From multiple entry points
import { MUIBox, Checkbox, useSetTabTitle } from '@your-org/ui-library';

Available Subpaths

  • @your-org/ui-library - Main entry point
  • @your-org/ui-library/lib - All components
  • @your-org/ui-library/lib/* - Individual components
  • @your-org/ui-library/hooks - All hooks
  • @your-org/ui-library/hooks/* - Individual hooks
  • @your-org/ui-library/theme - Theme system
  • @your-org/ui-library/theme/* - Individual theme files
  • @your-org/ui-library/mui - MUI components

πŸ§ͺ Local Development & Testing

Running the Playground

  1. Run pnpm run dev to start the local server at http://localhost:5173.
  2. The Playground is under the dev folder.

Testing with pnpm link

The recommended way to test the library locally with consuming applications:

  1. In the library directory:
# Build the library
pnpm run build

# Link the package globally
pnpm link --global
  1. In your consuming application (optional):
# Link to the local library
pnpm link --global @your-org/ui-library
  1. Important: Handle React Hook Issues

When testing locally, you might encounter React hooks issues. Solve this by linking React from the consuming app to the library:

# In the consuming app, link React
cd node_modules/react
pnpm link --global

# In the library directory, use the linked React
cd /path/to/ui-library
pnpm link --global react

Alternative: File Protocol with bundled package

  1. In module project, execute npm pack
  2. This will build a <package-name>-<version>.tar.gz file.
  3. Move the file to the consumer project
  4. In consuming app's package.json, add the file protocol:
# In consuming app's package.json
{
  "dependencies": {
    "@your-org/ui-library": "file:../path/to/ui-library"
  }
}

Development Workflow

  1. Make changes to the library
  2. Run pnpm run build to rebuild
  3. Changes will be immediately available in linked applications
  4. For automatic rebuilding: pnpm run build:watch

🎨 MUI Integration

Why Re-export MUI

The library re-exports Material-UI components to:

  • Avoid peer dependency conflicts in consuming applications
  • Ensure version consistency across all apps using the library
  • Reduce bundle size by preventing duplicate MUI imports
  • Simplify dependency management for consuming applications

Usage

// Instead of importing MUI directly in your app:
// import { Button, TextField } from '@mui/material'; // ❌ Don't do this

// Use the re-exported MUI from the library:
import { MUIButton, MUITextField } from '@your-org/ui-library'; // βœ… Preferred approach

function MyComponent() {
  return (
    <div>
      <MUIButton variant="contained">Click me</MUIButton>
      <MUITextField label="Enter text" />
    </div>
  );
}

πŸ”¨ Build System

Build Scripts

# Clean and build everything
pnpm run build

# Build with watch mode for development
pnpm run build:watch

# Build only TypeScript declarations
pnpm run build:types

# Clean dist folder
pnpm run clean

Build Output Structure

dist/
β”œβ”€β”€ index.js              # Main entry
β”œβ”€β”€ index.d.ts            # Main types
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ index.js          # All components
β”‚   β”œβ”€β”€ index.d.ts
β”‚   β”œβ”€β”€ AppBar/
β”‚   β”‚   β”œβ”€β”€ index.js      # Individual component
β”‚   β”‚   β”œβ”€β”€ index.d.ts
β”‚   β”‚   β”œβ”€β”€ AppBar.d.ts
β”‚   β”‚   └── AppBar.js
β”‚   └── ...
β”œβ”€β”€ hooks/
β”‚   β”œβ”€β”€ index.js          # All hooks
β”‚   └── *.js              # Individual hooks
└── theme/
    β”œβ”€β”€ index.js          # Theme system
    └── *.js              # Individual theme files

πŸ”§ TypeScript Configuration

The library uses modern TypeScript configuration:

{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "module": "ES2022",
    "target": "ES2020",
    "jsx": "react-jsx"
  }
}

Module Resolution

Using "moduleResolution": "bundler" enables:

  • Better tree-shaking
  • Proper subpath exports support
  • Modern import/export handling

TODO:

  • Add Jest for testing
  • Find a way to create documentation

πŸ“š Resources

πŸ”¨ What JS bundler to use?

πŸ“¦ How to publish

πŸ›£οΈ Subpath implementation

πŸ›£οΈ How to test the library locally with another app

About

POC about how to create a ui-library based on React and extending MUI

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors