Shared Packages
reptidex’s simplified frontend architecture uses 2 core shared packages that promote code reuse, consistency, and maintainability across all 4 applications.
Package Architecture
Simplified Structure
packages/
├── @reptidex/ui/ # Complete design system and UI components
└── @reptidex/core/ # Business logic, utilities, and API layer
Package Management
Package Manager : pnpm with workspace support
Versioning : Semantic versioning with automated releases
Publishing : Internal registry with scoped packages
Dependencies : Shared dependencies hoisted to monorepo root
Build System : Turborepo for optimized builds and caching
Core Packages
@reptidex/ui
Purpose : Comprehensive design system and component library
Package Type : UI Components & Design System
Dependencies : Material UI, Tailwind CSS, React
Bundle Size : ~150KB gzipped
Applications : All 4 frontend applications
Key Components :
Base Components
Material UI theme customization
Button, Input, Card, Modal variants
Form components with validation
Loading states and skeletons
Navigation and layout components
reptidex Components
AnimalCard with lineage display
MorphBadge with genetics info
PedigreeTree visualization
BreedingPairCard components
MarketplaceListing cards
Charts & Visualizations
Growth tracking charts
Breeding calendar components
Sales analytics dashboards
Genetic probability calculators
Interactive pedigree trees
Design System
Consistent typography scale
reptidex brand color palette
Responsive breakpoint system
Dark/light theme support
Accessibility compliance (WCAG 2.1)
Component Example :
import { AnimalCard , MorphBadge , Button } from '@reptidex/ui' ;
export const AnimalListing = ({ animal }) => (
< AnimalCard
animal = { animal }
showPedigree
actions = {
<>
<MorphBadge morphs = {animal. morphs } />
<Button variant = "primary" size = "lg" >
View Details
</Button>
</>
}
/>
);
Theme Configuration :
import { createTheme } from '@reptidex/ui/theme' ;
const theme = createTheme ({
palette: {
primary: {
main: '#2E7D32' ,
light: '#60AD5E' ,
dark: '#1B5E20'
},
secondary: {
main: '#8D6E63' ,
light: '#BCAAA4' ,
dark: '#5D4037'
}
},
typography: {
fontFamily: 'Inter, system-ui, sans-serif' ,
h1: { fontSize: '2.5rem' , fontWeight: 600 },
body1: { fontSize: '1rem' , lineHeight: 1.6 }
}
});
@reptidex/core
Purpose : Business logic, API integration, and shared utilities
Package Type : Business Logic & API Layer
Dependencies : React Query, Zod, date-fns
Bundle Size : ~80KB gzipped
Applications : All 4 frontend applications
Key Features :
API Integration
Type-safe API clients for all 6 services
React Query hooks with caching
Error handling and retry logic
Real-time subscriptions via WebSocket
Mock data for development
Business Logic
Genetic calculation utilities
Breeding program validation
Price calculation algorithms
Lineage tracking logic
Morph combination rules
Authentication
JWT token management
Role-based access control
Session handling utilities
Protected route components
Permission validation
Data Validation
Zod schemas for all data types
Form validation utilities
API response validation
Type-safe error handling
Input sanitization
API Client Example :
import { useAnimals , useBreeder , animalsAPI } from '@reptidex/core' ;
// React Query hook with caching
const AnimalsList = () => {
const { data : animals , isLoading , error } = useAnimals ({
filters: {
species: 'python-regius' ,
available: true ,
organization: user . organizationId
},
pagination: { page: 1 , limit: 20 }
});
if ( isLoading ) return < AnimalsSkeleton />;
if ( error ) return < ErrorMessage error ={ error } />;
return (
< div >
{ animals . data . map ( animal => (
< AnimalCard key = {animal. id } animal = { animal } />
))}
</ div >
);
};
// Direct API access
const createAnimal = async ( animalData : CreateAnimalRequest ) => {
try {
const animal = await animalsAPI . create ( animalData );
return { success: true , data: animal };
} catch ( error ) {
return { success: false , error: error . message };
}
};
Business Logic Example :
import { calculateGeneticProbability , validateBreedingPair } from '@reptidex/core' ;
// Genetic probability calculation
const BreedingCalculator = ({ sire , dam }) => {
const probabilities = calculateGeneticProbability ({
sire: sire . genetics ,
dam: dam . genetics ,
targetMorphs: [ 'pied' , 'banana' ]
});
return (
< div >
< h3 > Expected Offspring </ h3 >
{ probabilities . map ( prob => (
< div key = {prob. phenotype } >
{ prob . phenotype } : { prob . probability }% chance
</ div >
))}
</ div >
);
};
// Breeding pair validation
const validatePair = validateBreedingPair ( sire , dam );
if ( ! validatePair . valid ) {
console . error ( 'Invalid breeding pair:' , validatePair . errors );
}
Authentication Utilities :
import { useAuth , ProtectedRoute } from '@reptidex/core' ;
const BreederDashboard = () => {
const { user , isAuthenticated , hasRole } = useAuth ();
if ( ! isAuthenticated ) return < LoginForm />;
if ( ! hasRole ( 'breeder' )) return < AccessDenied />;
return < BreederWorkspace user ={ user } />;
};
// Protected route wrapper
export const BreederRoute = ({ children }) => (
< ProtectedRoute requiredRoles = { [ 'breeder' ]}>
{children}
</ProtectedRoute>
);
Development Workflow
Package Development
# Install all dependencies
pnpm install
# Build both packages
pnpm build
# Run tests for all packages
pnpm test
# Develop specific package with hot reload
pnpm --filter @reptidex/ui dev
pnpm --filter @reptidex/core dev
# Add dependency to specific package
pnpm --filter @reptidex/ui add @mui/material
pnpm --filter @reptidex/core add react-query
Version Management
# Create changeset for version bump
pnpm changeset
# Version packages based on changesets
pnpm changeset version
# Publish packages to registry
pnpm changeset publish
# Check current versions
pnpm list --depth=0
Cross-Application Development
# Link packages for local development
pnpm --filter web-public add @reptidex/ui@workspace: *
pnpm --filter web-breeder add @reptidex/core@workspace: *
# Build packages and applications together
pnpm build --filter=@reptidex/ui --filter=web-public
# Run application with package watching
pnpm dev --parallel
Package Dependencies
Dependency Graph
External Dependencies
@reptidex/ui Dependencies :
@radix-ui/react-* ^1.0.0 - Headless UI primitives
class-variance-authority ^0.7.0 - CVA for component variants
clsx ^2.0.0 - Conditional className utility
tailwind-merge ^2.0.0 - Tailwind class merging
tailwindcss ^3.4.0 - Utility-first CSS framework
lucide-react ^0.400.0 - Icon library
@reptidex/core Dependencies :
@tanstack/react-query ^5.0.0 - Data fetching and caching
zustand ^4.4.0 - State management
zod ^3.22.0 - Schema validation
date-fns ^3.0.0 - Date manipulation utilities
axios ^1.6.0 - HTTP client
Peer Dependencies
Both packages require:
react ^18.2.0
react-dom ^18.2.0
typescript ^5.2.0
Build Configuration
Turborepo Configuration
{
"pipeline" : {
"build" : {
"dependsOn" : [ "^build" ],
"outputs" : [ "dist/**" , ".next/**" ]
},
"dev" : {
"cache" : false ,
"persistent" : true
},
"test" : {
"dependsOn" : [ "build" ],
"outputs" : [ "coverage/**" ]
}
}
}
TypeScript Configuration
{
"compilerOptions" : {
"target" : "ES2022" ,
"module" : "ESNext" ,
"moduleResolution" : "bundler" ,
"allowImportingTsExtensions" : true ,
"declaration" : true ,
"declarationMap" : true ,
"outDir" : "./dist" ,
"rootDir" : "./src" ,
"strict" : true ,
"skipLibCheck" : true ,
"jsx" : "react-jsx"
},
"include" : [ "src/**/*" ],
"exclude" : [ "dist" , "node_modules" , "**/*.test.*" ]
}
Package Export Configuration
{
"name" : "@reptidex/ui" ,
"version" : "1.0.0" ,
"type" : "module" ,
"main" : "./dist/index.js" ,
"types" : "./dist/index.d.ts" ,
"exports" : {
"." : {
"import" : "./dist/index.js" ,
"types" : "./dist/index.d.ts"
},
"./theme" : {
"import" : "./dist/theme/index.js" ,
"types" : "./dist/theme/index.d.ts"
},
"./components/*" : {
"import" : "./dist/components/*/index.js" ,
"types" : "./dist/components/*/index.d.ts"
}
},
"peerDependencies" : {
"react" : "^18.2.0" ,
"react-dom" : "^18.2.0"
}
}
Testing Strategy
Unit Testing
// @reptidex/ui component testing
import { render , screen } from '@testing-library/react' ;
import { AnimalCard } from '../AnimalCard' ;
import { mockAnimal } from '../../__mocks__/animal' ;
describe ( 'AnimalCard' , () => {
it ( 'renders animal information correctly' , () => {
render (< AnimalCard animal ={ mockAnimal } />);
expect ( screen . getByText ( mockAnimal . name )). toBeInTheDocument ();
expect ( screen . getByText ( mockAnimal . species )). toBeInTheDocument ();
expect ( screen . getByRole ( 'img' , { name: /animal photo/ i })). toBeInTheDocument ();
});
it ( 'displays morph badges when provided' , () => {
const animalWithMorphs = { ... mockAnimal , morphs: [ 'pied' , 'banana' ] };
render (< AnimalCard animal ={ animalWithMorphs } />);
expect ( screen . getByText ( 'pied' )). toBeInTheDocument ();
expect ( screen . getByText ( 'banana' )). toBeInTheDocument ();
});
});
// @reptidex/core business logic testing
import { calculateGeneticProbability } from '../genetics' ;
import { mockSire , mockDam } from '../../__mocks__/animals' ;
describe ( 'calculateGeneticProbability' , () => {
it ( 'calculates correct probabilities for simple recessive' , () => {
const result = calculateGeneticProbability ({
sire: { pied: 'het' },
dam: { pied: 'het' },
targetMorphs: [ 'pied' ]
});
expect ( result ). toEqual ([
{ phenotype: 'normal' , probability: 75 },
{ phenotype: 'pied' , probability: 25 }
]);
});
});
Integration Testing
// Cross-package integration tests
import { render , screen , waitFor } from '@testing-library/react' ;
import { QueryClient , QueryClientProvider } from '@tanstack/react-query' ;
import { AnimalsList } from '@reptidex/ui' ;
import { useAnimals } from '@reptidex/core' ;
const TestWrapper = ({ children }) => {
const queryClient = new QueryClient ({
defaultOptions: { queries: { retry: false } }
});
return (
< QueryClientProvider client = { queryClient } >
{ children }
</ QueryClientProvider >
);
};
describe ( 'UI and Core Integration' , () => {
it ( 'renders animals list with API data' , async () => {
render (
< TestWrapper >
< AnimalsList organizationId = "test-org-123" />
</ TestWrapper >
);
await waitFor (() => {
expect ( screen . getByText ( 'Loading animals...' )). toBeInTheDocument ();
});
await waitFor (() => {
expect ( screen . getByText ( 'Test Ball Python' )). toBeInTheDocument ();
});
});
});
Bundle Optimization
Tree Shaking : Dead code elimination for both packages
Code Splitting : Lazy loading for heavy components
Bundle Analysis : Regular monitoring of package sizes
Peer Dependencies : Avoiding duplicate React/Material UI bundles
{
"scripts" : {
"build" : "turbo build --filter=@reptidex/ui --filter=@reptidex/core" ,
"build:ui" : "tsup src/index.ts --format esm,cjs --dts --clean" ,
"build:core" : "tsup src/index.ts --format esm,cjs --dts --clean" ,
"dev" : "turbo dev --parallel" ,
"test" : "turbo test --parallel"
}
}
Component Memoization : React.memo for expensive components
Query Optimization : Efficient React Query cache management
Virtual Scrolling : Large lists in Animal browsing
Image Optimization : Lazy loading and WebP conversion
Documentation & Storybook
Interactive Documentation
// Storybook stories for @reptidex/ui
export default {
title: 'Components/AnimalCard' ,
component: AnimalCard ,
parameters: {
docs: {
description: {
component: 'Displays animal information with optional pedigree and actions'
}
}
}
} ;
export const Default = {
args: {
animal: mockAnimal ,
showPedigree: false ,
actions: < Button > View Details </ Button >
}
};
export const WithPedigree = {
args: {
animal: mockAnimalWithPedigree ,
showPedigree: true
}
};
API Documentation
// Auto-generated TypeScript documentation
/**
* Hook for fetching animals with filtering and pagination
* @param options - Query options including filters and pagination
* @returns React Query result with animals data
*/
export function useAnimals ( options : UseAnimalsOptions ) : UseQueryResult < AnimalsResponse > {
return useQuery ({
queryKey: [ 'animals' , options ],
queryFn : () => animalsAPI . getAnimals ( options ),
staleTime: 5 * 60 * 1000 , // 5 minutes
cacheTime: 10 * 60 * 1000 // 10 minutes
});
}
Future Roadmap
Short-term Enhancements (Q1 2025)
Design Tokens : Centralized design system tokens for consistency
Advanced Animations : Sophisticated motion design for interactions
Mobile Optimization : Enhanced mobile component variants
Accessibility Audit : WCAG 2.1 AA compliance verification
Medium-term Goals (Q2-Q3 2025)
Micro Frontends : Module Federation for independent deployments
Native Components : React Native component library for mobile apps
GraphQL Integration : Type-safe GraphQL client and code generation
Advanced Caching : Sophisticated caching strategies with Redis
Long-term Vision (Q4 2025+)
Plugin Architecture : Extensible package system for third-party integrations
AI Components : AI-powered components for genetic predictions
Internationalization : Built-in i18n support for global expansion
Performance Monitoring : Runtime performance tracking and optimization
The simplified 2-package architecture provides all necessary functionality while maintaining clean separation of concerns and optimal performance across all reptidex applications.