PawHaven is an open-source full-stack project built with React and Node.js. With this project, you can learn how to build an enterprise-grade application from scratch — covering everything from frontend and backend development to CI/CD pipelines and cloud deployment, along with best practices at every stage.
This article is based on the architecture and practical experience of PawHaven. If you’d like to explore more runnable code examples, feel free to check out the GitHub Repository and give it a star ⭐️.
1. Project Background and Design Goals
PawHaven at the design stage, I defined several key goals:
- High scalability: New feature modules such as a donation system, volunteer management, and mobile applications may be added in the future.
- High maintainability: Support long-term operation and multi-developer collaboration, reducing maintenance costs.
- Contributor-friendly for global developers: The project is open source and may attract contributors from different regions. The code structure must be clear and standardized for quick onboarding.
These goals determined that PawHaven could not follow a temporary, scattered project structure and must adopt an enterprise-level architecture from the start.
2. Common Project Structures and Their Limitations
2.1 Traditional “Functional-Type” Structure
Many tutorials recommend a structure like this:
src
├─ components
├─ assets
├─ pages
├─ utils
├─ apis
├─ store
Advantages: Simple and intuitive, suitable for small projects or rapid prototyping.
Limitations:
- Scattered logic: Code for a single business module may be spread across pages, store, components, and services.
- High modification cost: Every time a feature needs to be modified or debugged, files must be searched in multiple directories.
- Blurred business boundaries: Modules can become coupled, reducing team efficiency and making division of work difficult.
- Difficult to scale: Adding new features often requires creating files in multiple directories.
- Hard to maintain: In large legacy projects, this structure significantly increases maintenance costs and communication overhead.
2.2 DDD (Domain-Driven Design) Pattern
Complex enterprise projects usually adopt Domain-Driven Design (DDD):
- Top-level directories are business modules (features)
- Each feature contains all related logic: components, pages, state, services, types
- Shared modules only contain cross-feature reusable functionality
Advantages:
- Self-contained modules: modifying a feature does not require searching across directories
- Clear business boundaries: team members can independently develop or test modules
- High scalability: new business modules can be added smoothly
- Easy maintenance: reduces coupling and improves readability
2.3 PawHaven’s DDD Implementation
In PawHaven, the frontend uses a feature-first directory design:
user
├─ src
│ ├─ features
│ │ ├─ RescueDetail
│ │ │ ├─ index.tsx
│ │ │ ├─ types.ts
│ │ │ ├─ rescueDetailSlice.ts
│ │ │ ├─ components
│ │ │ │ ├─ RescueTimeline.tsx
│ │ │ │ ├─ AnimalBasicInfo.tsx
│ │ │ │ └─ RescueInteraction.tsx
│ │ │ └─ apis
│ │ │ ├─ queries.ts
│ │ │ └─ request.ts
│ │ ├─ ReportStray
│ │ │ ├─ index.tsx
│ │ │ ├─ types.ts
│ │ │ ├─ constants.ts
│ │ │ ├─ reportStraySlice.ts
│ │ │ ├─ components
│ │ │ │ └─ ReportForm.tsx
│ │ │ └─ apis
│ │ │ ├─ requests.ts
│ │ │ └─ queries.ts
Each feature (e.g., RescueDetail, ReportStray) contains:
- Components (components)
- Pages (index.tsx)
- State management (slice)
- API requests (apis)
- Type definitions (types.ts)
- Constants (constants.ts)
This design ensures each business module is highly self-contained, facilitating independent development and maintenance by team members.
3. Component Layering Strategy
In enterprise projects, as features grow more complex, DDD alone is not enough. A layering strategy is needed. In PawHaven, layering applies not only to UI components but to all code units, including hooks, services, and utility functions.
PawHaven’s layering strategy:
3.1 Feature Layer (Internal to Feature)
- Closely tied to business logic
- Contains pages, business components, hooks, services, types
- Example: report-animal/ReportForm.tsx, report-animal/hooks/useReportAnimal.ts
3.2 Cross-Feature Layer (Application Level)
- Shared across multiple features but still contextually tied to business
- Examples: user info cards, navigation menus, layout components, cross-feature hooks
- Located at the application level, outside individual features
3.3 Shared Layer (Business-agnostic)
- Completely decoupled from business logic
- Includes UI dumb components (Button, Modal, Input), utility functions, generic hooks, constants, theme configs, internationalization text, etc.
- Reusable across the entire monorepo and can be easily extracted into independent libraries
This layering strategy ensures clear business boundaries while maximizing code reuse, achieving high scalability and maintainability.
4. Monorepo vs Multi-Repo
In enterprise projects, managing multiple apps and modules is a key decision. Common approaches are Multi-Repo and Monorepo.
4.1 Multi-Repo
- Each service or business has a separate repository, with tool libraries in their own repos
- Advantages: independent repositories, clear permission control, low initial learning curve
- Disadvantages: hard to share code, scattered dependencies, complex cross-repo refactoring
- Examples: Netflix, Spotify microservices
I have personally experienced the pain of Multi-Repo, where synchronizing shared code across projects was manual and error-prone, and frequent switching between repos reduced development efficiency.
4.2 Monorepo
- Multiple apps, services, and libraries are managed in a single repository
- Advantages: easy code sharing, unified dependencies and rules, simple cross-project refactoring, improved developer experience
- Disadvantages: requires more advanced tooling; build and test processes need optimization
- Examples: Google, Meta, Uber, Airbnb
4.3 Why PawHaven Chose Monorepo
Considering PawHaven’s development roadmap:
- Multiple frontend apps: user app (pawHaven), admin panel (admin), auth app (auth)
- Multiple backend microservices (NestJS) and shared packages
- Potential global contributors requiring a clear, standardized structure
Monorepo is therefore the most suitable choice.
Directory structure:
PawHaven-frontend/
├── apps/ # Applications
│ ├── user/ # User app
│ ├── admin/ # Admin app
├── packages/ # Shared modules
│ ├── components/
│ ├── hooks/
│ ├── utils/
│ ├── constants/
│ ├── theme/
│ ├── i18n/
│ └── api-client/
├── package.json
└── pnpm-workspace.yaml
4.4 Why pnpm Workspace
There are multiple Monorepo tools (Lerna, Nx, Turborepo). I chose pnpm workspace for:
- Fast installation: hard links and content-addressable storage save disk space and time
- Strict dependency isolation: avoids “phantom dependencies”
- Native workspace support: lightweight, simple configuration
- Enterprise compatibility: widely adopted in large companies and community projects
Example configuration:
# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
This setup allows multiple frontend or backend services to collaborate in a single repository while maintaining independent build and deployment pipelines.
5. Summary
PawHaven demonstrates that enterprise-level architecture is not just about organizing code—it’s about scalability, maintainability, and team efficiency.
From the start, PawHaven adopted a DDD / Feature-first approach with self-contained modules, ensuring clear business boundaries; combined with a component layering strategy (Feature layer, Cross-Feature layer, Shared layer) to maximize reuse; and implemented Monorepo + pnpm workspace to unify frontend, backend, and shared modules while keeping responsibilities separate.
This architecture not only facilitates current development but also lays a solid foundation for future feature expansion, team collaboration, and global contributor participation.
Ultimately, PawHaven provides a practical example of building an enterprise-level full-stack project from scratch: define clear boundaries, structure layers effectively, reuse shared modules, and unify management for sustainable long-term operation.
Top comments (0)