| name | code-patterns-library |
| description | Reusable code patterns and design templates following glue coding philosophy - prioritize searching, reusing, and connecting over creating. Includes API response formats, custom React hooks, Repository pattern, UI component patterns, and skeleton project strategies. Use when implementing new features, designing APIs, creating components, or when asked about code patterns, best practices, or reusable solutions. |
Code Patterns Library
Proven, reusable code patterns following the glue coding philosophy.
Core Philosophy
Reuse > Connect > Create
Priority order when implementing features:
- 🔍 Search - Find battle-tested solutions
- 📦 Reuse - Use mature libraries and frameworks
- 🔗 Connect - Write glue code to connect modules
- ✏️ Create - Only write new code when necessary
Code Source Priority
Official docs examples > Mature open-source > Existing project code > New code
API Response Format
Standard Interface
interface ApiResponse<T> {
success: boolean
data?: T
error?: string
meta?: {
total: number
page: number
limit: number
}
}
Usage Examples
const successResponse: ApiResponse<User> = {
success: true,
data: {
id: '123',
name: 'John Doe',
email: 'john@example.com'
}
}
const errorResponse: ApiResponse<never> = {
success: false,
error: 'User not found'
}
const paginatedResponse: ApiResponse<User[]> = {
success: true,
data: [],
meta: {
total: 100,
page: 1,
limit: 10
}
}
Utility Functions
export function successResponse<T>(
data: T,
meta?: ApiResponse<T>['meta']
): ApiResponse<T> {
return { success: true, data, meta }
}
export function errorResponse(error: string): ApiResponse<never> {
return { success: false, error }
}
export async function getUser(id: string): Promise<ApiResponse<User>> {
try {
const user = await db.users.findById(id)
if (!user) {
return errorResponse('User not found')
}
return successResponse(user)
} catch (error) {
return errorResponse(error.message)
}
}
Custom React Hooks
useDebounce
import { useState, useEffect } from 'react'
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => clearTimeout(handler)
}, [value, delay])
return debouncedValue
}
Use Case: Search input, API call debouncing
function SearchComponent() {
const [searchTerm, setSearchTerm] = useState('')
const debouncedSearchTerm = useDebounce(searchTerm, 500)
useEffect(() => {
if (debouncedSearchTerm) {
searchAPI(debouncedSearchTerm)
}
}, [debouncedSearchTerm])
return (
<input
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search..."
/>
)
}
useLocalStorage
import { useState } from 'react'
export function useLocalStorage<T>(
key: string,
initialValue: T
): [T, (value: T) => void] {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key)
return item ? JSON.parse(item) : initialValue
} catch (error) {
console.error(error)
return initialValue
}
})
const setValue = (value: T) => {
try {
setStoredValue(value)
window.localStorage.setItem(key, JSON.stringify(value))
} catch (error) {
console.error(error)
}
}
return [storedValue, setValue]
}
Use Case: Persist user preferences, theme settings
function ThemeToggle() {
const [theme, setTheme] = useLocalStorage('theme', 'light')
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current theme: {theme}
</button>
)
}
useAsync
import { useState, useEffect, useCallback } from 'react'
interface AsyncState<T> {
loading: boolean
data: T | null
error: Error | null
}
export function useAsync<T>(
asyncFunction: () => Promise<T>,
immediate = true
) {
const [state, setState] = useState<AsyncState<T>>({
loading: immediate,
data: null,
error: null
})
const execute = useCallback(async () => {
setState({ loading: true, data: null, error: null })
try {
const data = await asyncFunction()
setState({ loading: false, data, error: null })
} catch (error) {
setState({ loading: false, data: null, error: error as Error })
}
}, [asyncFunction])
useEffect(() => {
if (immediate) {
execute()
}
}, [execute, immediate])
return { ...state, execute }
}
Use Case: Async data fetching
function UserProfile({ userId }: { userId: string }) {
const { loading, data, error } = useAsync(
() => fetchUser(userId),
true
)
if (loading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
if (!data) return null
return <div>{data.name}</div>
}
Repository Pattern
Interface
interface Repository<T> {
findAll(filters?: Filters): Promise<T[]>
findById(id: string): Promise<T | null>
create(data: CreateDto): Promise<T>
update(id: string, data: UpdateDto): Promise<T>
delete(id: string): Promise<void>
}
interface Filters {
[key: string]: any
}
type CreateDto = Omit<T, 'id' | 'createdAt' | 'updatedAt'>
type UpdateDto = Partial<CreateDto>
Implementation
import { supabase } from '../lib/supabase'
export class UserRepository implements Repository<User> {
private table = 'users'
async findAll(filters?: Filters): Promise<User[]> {
let query = supabase.from(this.table).select('*')
if (filters) {
Object.entries(filters).forEach(([key, value]) => {
query = query.eq(key, value)
})
}
const { data, error } = await query
if (error) throw error
return data || []
}
async findById(id: string): Promise<User | null> {
const { data, error } = await supabase
.from(this.table)
.select('*')
.eq('id', id)
.single()
if (error) return null
return data
}
async create(data: CreateDto): Promise<User> {
const { data: user, error } = await supabase
.from(this.table)
.insert(data)
.select()
.single()
if (error) throw error
return user
}
async update(id: string, data: UpdateDto): Promise<User> {
const { data: user, error } = await supabase
.from(this.table)
.update(data)
.eq('id', id)
.select()
.single()
if (error) throw error
return user
}
async delete(id: string): Promise<void> {
const { error } = await supabase
.from(this.table)
.delete()
.eq('id', id)
if (error) throw error
}
}
Usage
import { UserRepository } from '../repositories/UserRepository'
export class UserService {
private userRepo = new UserRepository()
async getUserById(id: string) {
const user = await this.userRepo.findById(id)
if (!user) {
throw new Error('User not found')
}
return user
}
async createUser(data: CreateUserDto) {
if (!data.email.includes('@')) {
throw new Error('Invalid email')
}
return await this.userRepo.create(data)
}
async getActiveUsers() {
return await this.userRepo.findAll({ isActive: true })
}
}
UI Component Patterns
Composition Pattern
interface CardProps {
children: React.ReactNode
className?: string
}
export function Card({ children, className }: CardProps) {
return (
<div className={`card ${className || ''}`}>
{children}
</div>
)
}
export function CardHeader({ children }: { children: React.ReactNode }) {
return <div className="card-header">{children}</div>
}
export function CardBody({ children }: { children: React.ReactNode }) {
return <div className="card-body">{children}</div>
}
export function CardFooter({ children }: { children: React.ReactNode }) {
return <div className="card-footer">{children}</div>
}
import { Card, CardHeader, CardBody, CardFooter } from './components/Card'
function UserCard() {
return (
<Card>
<CardHeader>
<h2>User Info</h2>
</CardHeader>
<CardBody>
<p>Name: John Doe</p>
<p>Email: john@example.com</p>
</CardBody>
<CardFooter>
<button>Edit</button>
</CardFooter>
</Card>
)
}
Render Props Pattern
interface DataFetcherProps<T> {
url: string
children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode
}
function DataFetcher<T>({ url, children }: DataFetcherProps<T>) {
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false))
}, [url])
return <>{children(data, loading, error)}</>
}
function UserList() {
return (
<DataFetcher<User[]> url="/api/users">
{(users, loading, error) => {
if (loading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
if (!users) return null
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}}
</DataFetcher>
)
}
Skeleton Project Strategy
When Implementing New Features
- Search for Skeleton Projects
"react typescript starter"
"nextjs authentication boilerplate"
"express api template"
Evaluation Criteria:
- ⭐ Stars count (community approval)
- 📅 Recent updates (active maintenance)
- 📝 Documentation quality (usability)
- 🔒 Security (no known vulnerabilities)
- 📦 Dependency health (no outdated deps)
- Parallel Evaluation
Evaluate candidates across dimensions:
- Security: Check dependency vulnerabilities, review auth implementation
- Scalability: Clear architecture, easy to customize, plugin support
- Relevance: Tech stack match, feature coverage, learning curve
- Implementation: Integration difficulty, migration cost, maintenance burden
- Clone Best Match
git clone https://github.com/user/best-match-project.git
cd best-match-project
git checkout -b integrate-to-your-project
- Iterate Within Verified Structure
- Keep skeleton's core architecture
- Customize features as needed
- Add project-specific business logic
- Follow original project's coding style
- Preserve original test structure
Recommended Skeletons
React + TypeScript Components:
- shadcn/ui - Copy-paste components
- Radix UI - Unstyled accessible components
- Headless UI - Tailwind official components
API Backend Templates:
- nestjs/nest - Enterprise Node.js framework
- express-typescript-boilerplate - Express + TS
- fastify-starter - High-performance API framework
Full-Stack Templates:
- t3-stack - Next.js + tRPC + Prisma
- create-t3-app - T3 Stack scaffolding
- supabase-starter - Supabase full-stack template
Utility Functions
Type-Safe Event Handling
export function createEventHandler<T extends Event>(
handler: (event: T) => void
) {
return (event: T) => {
event.preventDefault()
handler(event)
}
}
const handleSubmit = createEventHandler<FormEvent<HTMLFormElement>>((e) => {
const formData = new FormData(e.currentTarget)
})
Safe Type Guards
export function isString(value: unknown): value is string {
return typeof value === 'string'
}
export function isNumber(value: unknown): value is number {
return typeof value === 'number' && !isNaN(value)
}
export function isArray<T>(value: unknown): value is T[] {
return Array.isArray(value)
}
function processValue(value: unknown) {
if (isString(value)) {
return value.toUpperCase()
}
if (isNumber(value)) {
return value * 2
}
throw new Error('Invalid value type')
}
Best Practices Summary
- Prioritize Reuse - Search for existing solutions, avoid reinventing the wheel
- Standardize Interfaces - Use consistent API response formats and data structures
- Type Safety - Leverage TypeScript's type system fully
- Component Thinking - Break UI into reusable small components
- Separation of Concerns - Repository pattern separates data access from business logic
- Skeleton Projects - Start new features based on mature projects
- Continuous Learning - Follow community best practices and new patterns
Remember: Good code isn't written from scratch, it's built on the shoulders of giants by reusing and composing validated solutions.