The petfolio-fe repository¶
The PetFolio Frontend is built as a Nx monorepo with a modular architecture designed for scalability and maintainability.
Read the introduction to Nx for more information on how the workspace uses Nx.
Applications and libraries¶
The workspace is split into applications and libraries - deployable entry points in apps/ and reusable shared code in libs/.
Our applications¶
| Project | Description |
|---|---|
petfolio-business |
Main Next.js application (App Router) |
petfolio-docs |
MkDocs Material documentation site |
petfolio-ui-tests |
Playwright end-to-end tests |
Our libraries¶
| Project | Description |
|---|---|
ui-component-library |
Shared React component library with Storybook |
util-global-theme |
Material UI theming utilities and type definitions |
Nx enforces strict module boundaries between these projects, controlling which libraries each application and library is allowed to import from.
Technology stack¶
| Technology | Category | Purpose |
|---|---|---|
| Nx | Build System | Monorepo orchestration and task management |
| Next.js | Framework | App routing, SSR, server components |
| React | UI Library | Building user interfaces |
| Material UI | Design System | Component library with theming |
| TypeScript | Language | Adds type safety to JavaScript |
| Jest | Testing | Unit and integration testing |
| Playwright | Testing | End-to-end browser testing |
| ESLint | Linting | Code quality and style enforcement |
| Storybook | Documentation | Interactive component documentation |
| MkDocs Material | Documentation | Static documentation site generation |
Design patterns¶
File naming conventions¶
| File Type | Pattern | Example |
|---|---|---|
| Component | PascalCase | Button.tsx |
| Test | *.spec.tsx |
Button.spec.tsx |
| Story | *.stories.tsx |
Button.stories.tsx |
| Styled Component | Styled*.tsx |
StyledButton.tsx |
| Utility | camelCase | themeUtils.ts |
| Config | kebab-case | next.config.mjs |
| Documentation | kebab-case | getting-started.md |
Atomic design¶
Components are organised hierarchically:
graph LR
A[Atoms] --> B[Molecules]
B --> C[Organisms]
C --> D[Templates]
D --> E[Pages]
classDef layer-infra fill:#f5a6232e,stroke:#f5a623,stroke-width:2px
classDef layer-domain fill:#7ed32126,stroke:#7ed321,stroke-width:2px
classDef layer-api fill:#4a90d926,stroke:#4a90d9,stroke-width:2px
class A,B layer-infra
class C,D layer-domain
class E layer-api
Diagram key
- Blue (API layer): Pages - route-level entry points
- Green (Domain layer): Organisms and Templates - composed business UI
- Orange (Infrastructure layer): Atoms and Molecules - foundational building blocks
- Atoms: Basic building blocks (Button, Input, Icon)
- Molecules: Simple combinations (SearchBar, FormField)
- Organisms: Complex components (Header, ProductCard)
- Templates: Page layouts
- Pages: Actual routes in the app
Direct imports with path aliases¶
To avoid barrel export issues (bundle size, HMR performance, server/client boundary violations), components are imported directly from their source files using TypeScript path aliases.
Path aliases are configured in tsconfig.base.json:
Example imports:
Benefits:
- Clear server/client boundaries in Next.js App Router
- Better tree-shaking for smaller bundles
- Faster builds and Hot Module Replacement (HMR)
- Explicit component dependencies
Enforcement:
ESLint enforces this pattern by banning the export * from syntax, preventing barrel exports from being created.
Security¶
- ESLint Security Plugin: Detects common vulnerabilities
- No Unsanitised Plugin: Prevents XSS attacks
- TypeScript Strict Mode: Catches type-related bugs
- Multi-stage builds: Minimal production images
- Trivy scanning: Vulnerability detection in dependencies
- Non-root user: Containers run with restricted privileges
- Health checks: Automatic restart on failure
- Dependabot: Automated dependency updates
- Version pinning: Exact versions in package-lock.json
- Audit on CI:
npm auditruns in pipeline
Performance¶
- App Router: Automatic code splitting
- Server Components: Reduced client bundle size
- Standalone output: Optimised production builds
- Image optimisation: Built-in next/image
- Nx cache: 10-100x faster repeat builds
- Incremental builds: Only rebuild changed code
- Parallel execution: Utilise all CPU cores