Building a scalable component architecture from scratch requires implementing component composition patterns, shared UI packages, design system architecture, type-safe wrappers, and custom component development. From HeroUI v3 integration to TypeScript type safety and component reusability, creating a production-ready UI system requires weeks of careful development. Fastack comes with a complete UI component library built on HeroUI v3 that handles component composition, type safety, and design system patterns—saving you weeks of development time.
Why component architecture matters for SaaS
A well-structured component architecture provides essential benefits:
- Code reusability across applications
- Consistent design system implementation
- Type-safe component APIs with TypeScript
- Easy maintenance and updates
- Shared components across monorepo packages
What you get with Fastack
Fastack includes a complete UI component library built on HeroUI v3:
Shared UI package
Fastack provides a unified UI package that exports all components:
/**
* @saas/ui-core - Unified UI Component Library
*
* This package provides a unified interface for HeroUI components.
*
* Usage:
* import { Button, Input, Card, Modal, Tabs, Tab } from '@saas/ui-core';
*/
// Export components
export * from './components';
// Export HeroUI Providers directly
export { HeroUIProvider, ToastProvider } from '@heroui/react';
// Icons (library-agnostic)
export * from './icons';The @saas/ui-core package provides a single import point for all UI components, making it easy to use components across the monorepo while maintaining type safety and consistency.
Type-safe component wrappers
Fastack wraps HeroUI components with type-safe interfaces:
'use client';
import { Button as HeroUIButton, ButtonProps as HeroUIButtonProps } from '@heroui/react';
import { forwardRef } from 'react';
import { cn } from '@saas/utils';
export interface ButtonProps extends HeroUIButtonProps {}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, children, isDisabled, ...props }, ref) => {
return (
<HeroUIButton
ref={ref}
className={cn(className)}
isDisabled={isDisabled}
{...props}
>
{children}
</HeroUIButton>
);
}
);
Button.displayName = 'Button';Component wrappers extend HeroUI props with TypeScript interfaces, ensuring type safety while allowing customization. The cn utility merges Tailwind classes properly, and forwardRef ensures proper ref forwarding.
Compound component patterns
Fastack uses compound component patterns for complex components:
'use client';
import {
Modal as HeroUIModal,
ModalProps as HeroUIModalProps,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
} from '@heroui/react';
import { forwardRef } from 'react';
import { cn } from '@saas/utils';
export type ModalProps = HeroUIModalProps;
export const Modal = forwardRef<HTMLDivElement, ModalProps>(
({ className, ...props }, ref) => {
return (
<HeroUIModal
placement="center"
ref={ref}
className={cn(className)}
{...props}
/>
);
}
);
Modal.displayName = 'Modal';
// Sub-components
export { ModalContent, ModalHeader, ModalBody, ModalFooter };Compound components allow flexible composition. The Modal component exports sub-components that can be used together, providing a clean API while maintaining type safety.
Custom component variants
Fastack includes custom components with predefined variants:
export interface ErrorAlertProps {
message?: string;
title?: ReactNode;
description?: ReactNode;
className?: string;
isClosable?: boolean;
onClose?: () => void;
children?: ReactNode;
}
export function ErrorAlert({
message,
title,
description,
className,
isClosable,
onClose,
children,
}: ErrorAlertProps) {
return (
<Alert
color="danger"
variant="flat"
title={title}
description={description || message || children}
className={className}
isClosable={isClosable}
onClose={onClose}
/>
);
}Custom component variants like ErrorAlert and SuccessAlert provide convenient shortcuts for common use cases while maintaining the flexibility of the base component.
Complex custom components
Fastack includes complex custom components like code blocks:
export const CodeBlockCode = forwardRef<HTMLDivElement, CodeBlockCodeProps>(
(
{
code,
language = 'text',
theme = 'github-dark',
className,
showCopyButton = true,
...props
},
ref
) => {
const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null);
const [copied, setCopied] = useState(false);
useEffect(() => {
let isMounted = true;
async function highlight() {
if (!code) {
setHighlightedHtml('<pre><code></code></pre>');
return;
}
try {
const shiki = await import('shiki');
const html = await shiki.codeToHtml(code, { lang: language, theme });
if (isMounted) {
setHighlightedHtml(html);
}
} catch (error) {
console.error('Failed to highlight code:', error);
if (isMounted) {
setHighlightedHtml(`<pre><code class="language-${language}">${code}</code></pre>`);
}
}
}
highlight();
return () => {
isMounted = false;
};
}, [code, language, theme]);
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
} catch (err) {
console.error('Failed to copy:', err);
}
};
// ... render logic with syntax highlighting and copy button
}
);Complex components like CodeBlock demonstrate advanced patterns including async code highlighting, copy-to-clipboard functionality, and proper cleanup with useEffect.
Component usage examples
Fastack demonstrates component usage in real applications:
'use client';
import { Accordion, AccordionItem } from '@saas/ui-core';
import { useClientTranslations } from '@/i18n/client';
import { ScrollAnimate } from '@saas/utils';
export function LandingFaq() {
const t = useClientTranslations('landing');
const faqItems = ['1', '2', '3', '4', '5', '6'];
return (
<section id="faq" className="py-20 px-4 w-full bg-backgroundsection">
<div className="max-w-4xl mx-auto">
<ScrollAnimate animation="fadeInUp" className="text-center mb-16">
<h2 className="text-3xl sm:text-4xl font-bold text-foreground mb-4">
{t('faq.title')}
</h2>
<p className="text-lg text-foreground/70 max-w-2xl mx-auto">
{t('faq.subtitle')}
</p>
</ScrollAnimate>
<ScrollAnimate animation="fadeInUp" delay={200}>
<Accordion variant="splitted" className="w-full">
{faqItems.map((key) => (
<AccordionItem
key={key}
aria-label={t(`faq.items.${key}.question`)}
title={t(`faq.items.${key}.question`)}
>
<p className="text-foreground/70">
{t(`faq.items.${key}.answer`)}
</p>
</AccordionItem>
))}
</Accordion>
</ScrollAnimate>
</div>
</section>
);
}Components from @saas/ui-core are used throughout the application, demonstrating real-world usage patterns with i18n integration and responsive design.
Available components
Fastack's @saas/ui-core package includes 60+ production-ready components, all available from a single import:
import { Button, Input, Card, Modal, Tabs, Tab } from '@saas/ui-core';Form components
ButtonInputTextareaSelectAutocompleteCheckboxRadioGroupSwitchInputOtpInputDateInputTimeInputNumberSliderLayout & navigation
CardModalTabsAccordionSidebarNavbarDropdownPaginationTableScrollShadowFeedback & display
AlertSpinnerProgressSkeletonBadgeChipTooltipAvatarImageImageZoomContent & media
CodeCodeBlockLinkKbdCarouselCalendarTableOfContentsBackground & effects
DotPatternParticlesBackgroundGridFloatingLinesLightPillarMarqueeBorderBeamAuroraTextAvatarCirclesConfettiUtilities & hooks
ThemeProviderThemeToggleSearchuseDisclosureuseToastuseConfettiMotion componentsAll components are fully typed with TypeScript, support dark mode, and follow HeroUI v3 design patterns. Each component can be imported individually or as part of compound component patterns for maximum flexibility.
Time saved: 20+ hours
Building a reusable UI component library from scratch typically requires:
- Setting up component package structure (2-3 hours)
- Creating type-safe wrappers (4-5 hours)
- Implementing compound components (3-4 hours)
- Building custom component variants (3-4 hours)
- Creating complex components (4-5 hours)
- Testing component integration (2-3 hours)
- Documenting component API (2-3 hours)
Total: 20-27 hours of development time that you save with Fastack.
Best practices included
Fastack follows component architecture best practices:
- Type-safe wrappers - Full TypeScript support
- Compound components - Flexible composition patterns
- Shared package - Reusable across monorepo
- Custom variants - Convenient shortcuts for common cases
- Design system - Consistent styling and behavior
Conclusion
A well-structured component architecture is essential for scalable SaaS applications. Fastack provides a complete UI component library built on HeroUI v3 that saves you weeks of development time while ensuring type safety and design consistency.
With Fastack, you get:
- Shared UI package with unified component exports
- Type-safe component wrappers with full TypeScript support
- Compound component patterns for flexible composition
- Custom component variants for common use cases
- Complex custom components with advanced functionality
- Design system architecture built-in from day one
Ready to build your SaaS faster?
Get our scalable, production-ready boilerplate to save endless hours of development and setup
