A production-ready template for building micro frontend (MFE) applications with React, TypeScript, and modern tooling. This template provides essential components, utilities, and patterns to quickly scaffold new MFE projects.
- Atomic Design: Components organized as Atoms → Molecules → Organisms
- Design System: Comprehensive design tokens with WCAG AA compliance
- Theme Support: Light, dark, and system theme modes
- Modern Stack: React 18, TypeScript, Vite, Tailwind CSS
- Testing Ready: Vitest configuration with 90%+ coverage thresholds
- Build Optimized: tsup for library builds, Vite for development
- Developer Experience: ESLint, Prettier, and comprehensive tooling
- Accessibility: ARIA labels, keyboard navigation, semantic HTML
# Clone the template
git clone https://github.com/jonmatum/react-mfe-template.git my-mfe-project
cd my-mfe-project
# Install dependencies
npm install
# Start development
npm run dev
# Build for production
npm run buildimportReactfrom'react';import{SettingsProvider,Button,Modal,useSettings}from'my-mfe-library';import'my-mfe-library/dist/style.css';functionApp(){return(<SettingsProvider><MyComponent/></SettingsProvider>);}functionMyComponent(){const{ settings, updateSettings }=useSettings();return(<divclassName="p-4"><ButtononClick={()=>console.log('Clicked!')}>
Hello MFE!
</Button></div>);}- Button: Configurable button with variants (primary, secondary, ghost)
- LoadingSpinner: Animated loading indicator with customizable sizes
- Switch: Toggle switch for settings and preferences
- Modal: Accessible modal dialog with backdrop and keyboard support
- SettingsProvider: Global state management for theme and layout preferences
- classNames: Utility for combining CSS classes
- storage: Local storage helpers with error handling
- theme: Theme management utilities
- tokens: Comprehensive design token system
- Colors: Primary, secondary, and semantic color palettes
- Typography: Font families, sizes, and weights
- Spacing: Consistent spacing scale
- Shadows: Elevation system
- Breakpoints: Responsive design breakpoints
src/
├── components/
│ ├── atoms/ # Basic building blocks
│ │ ├── Button.tsx
│ │ ├── LoadingSpinner.tsx
│ │ └── Switch.tsx
│ ├── molecules/ # Simple combinations
│ │ └── Modal.tsx
│ └── organisms/ # Complex combinations (add as needed)
├── contexts/ # React contexts
│ └── SettingsContext.tsx
├── types/ # TypeScript definitions
│ └── index.ts
├── utils/ # Utility functions
│ ├── index.ts
│ └── tokens.ts
├── styles/ # CSS files
│ └── index.css
└── index.ts # Main exports
The template includes a comprehensive theming system:
import{useSettings}from'my-mfe-library';functionThemeToggle(){const{ settings, updateSettings }=useSettings();return(<buttononClick={()=>updateSettings({theme: settings.theme==='light' ? 'dark' : 'light'})}>
Toggle Theme
</button>);}light: Light themedark: Dark themesystem: Follows system preference
# Development
npm run dev # Start development server
npm run build # Build for production
npm run build:lib # Build library only# Quality
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint issues
npm run type-check # TypeScript type checking
npm run test# Run tests
npm run test:coverage # Run tests with coverage# Formatting
npm run format # Format with Prettier
npm run format:check # Check formatting- Atoms: Basic UI elements (buttons, inputs, icons)
- Molecules: Simple combinations (search box, card header)
- Organisms: Complex combinations (navigation, forms)
// Example: Adding a new atom// src/components/atoms/Input.tsximportReactfrom'react';import{BaseComponentProps}from'../../types';import{classNames}from'../../utils';interfaceInputPropsextendsBaseComponentProps{type?: string;placeholder?: string;value?: string;onChange?: (e: React.ChangeEvent<HTMLInputElement>)=>void;}constInput: React.FC<InputProps>=({ className, ...props})=>{return(<inputclassName={classNames('block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',className)}{...props}/>);};exportdefaultInput;Don't forget to export new components in src/index.ts:
export{defaultasInput}from'./components/atoms/Input';Use atoms to build more complex components:
// src/components/molecules/SearchBox.tsximportReact,{useState}from'react';import{MagnifyingGlassIcon}from'@heroicons/react/24/outline';importInputfrom'../atoms/Input';importButtonfrom'../atoms/Button';interfaceSearchBoxProps{onSearch: (query: string)=>void;placeholder?: string;}constSearchBox: React.FC<SearchBoxProps>=({
onSearch,
placeholder ='Search...'})=>{const[query,setQuery]=useState('');consthandleSubmit=(e: React.FormEvent)=>{e.preventDefault();onSearch(query);};return(<formonSubmit={handleSubmit}className="flex gap-2"><Inputvalue={query}onChange={(e)=>setQuery(e.target.value)}placeholder={placeholder}className="flex-1"/><Buttontype="submit"variant="primary"><MagnifyingGlassIconclassName="h-5 w-5"/></Button></form>);};exportdefaultSearchBox;import{colors,spacing,typography}from'your-mfe-project';// Use tokens in your componentsconstcustomStyles={backgroundColor: colors.primary[500],padding: spacing[4],fontSize: typography.fontSize.base[0],};// Prefer utility classes<divclassName="bg-blue-500 p-4 text-base rounded-md shadow-sm">
Content
</div>// Use design tokens for consistency<divclassName="bg-primary-500 p-4 text-base rounded-md shadow-sm">Content</div>// Test component behaviordescribe('MyComponent',()=>{it('renders correctly',()=>{render(<MyComponent/>);expect(screen.getByRole('button')).toBeInTheDocument();});it('handles user interactions',()=>{consthandleClick=vi.fn();render(<MyComponentonClick={handleClick}/>);fireEvent.click(screen.getByRole('button'));expect(handleClick).toHaveBeenCalled();});it('applies custom className',()=>{render(<MyComponentclassName="custom-class"/>);expect(screen.getByRole('button')).toHaveClass('custom-class');});});The template enforces 90%+ coverage thresholds:
- Statements: 90%
- Branches: 90%
- Functions: 90%
- Lines: 90%
npm run build:watch # Watch mode for developmentnpm run build # Full production build
npm run build:lib # Library build only# Update version
npm version patch|minor|major
# Publish to npm
npm publishCreate .env files for different environments:
# .env.development
VITE_API_URL=http://localhost:3001
# .env.production
VITE_API_URL=https://api.yourproject.comModify tsup.config.ts for build customization:
exportdefaultdefineConfig({entry: ['src/index.ts'],format: ['cjs','esm'],dts: true,sourcemap: true,external: ['react','react-dom','@heroicons/react'],// Add your customizations});# Build for production
npm run build
# Deploy to GitHub Pages (if configured)
npm run deploy# Ensure you're logged in to npm
npm login
# Publish the package
npm publish- Follow the atomic design principles
- Write comprehensive tests
- Use TypeScript for all new code
- Follow the existing code style
- Update documentation as needed
This template is licensed under the MIT License. See LICENSE for details.