Skip to content

The petfolio-fe repository

The PetFolio Frontend is built as a Nx monorepo with a modular architecture designed for scalability and maintainability.

Like a typical Nx workspace, we have many more libs than apps.

Read the introduction to Nx for more information.

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]

    style A fill:#e1f5ff
    style B fill:#b3e5fc
    style C fill:#81d4fa
    style D fill:#4fc3f7
    style E fill:#29b6f6
  • 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:

1
2
3
4
5
6
7
8
{
  "compilerOptions": {
    "paths": {
      "@util-global-theme/*": ["libs/util-global-theme/src/lib/*"],
      "@ui-component-library/*": ["libs/ui-component-library/src/lib/*"]
    }
  }
}

Example imports:

1
2
3
4
5
6
7
8
9
import foo
import boo.baz
import foo.bar.baz

class Foo:
   def __init__(self):
       self.foo = None
       self.bar = None
       self.baz = None
1
2
3
4
5
def bubble_sort(items):
    for i in range(len(items)):
        for j in range(len(items) - 1 - i):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
1
2
3
4
5
6
7
// Component library - use direct imports
import { Button } from '@ui-component-library/atoms/Button/Button';
import { ButtonSize, ButtonVariant } from '@ui-component-library/atoms/Button/Button.types';

// Theme utilities - use direct imports
import { createDefaultTheme } from '@util-global-theme/createTheme/createDefaultTheme';
import { TypographyVariant } from '@util-global-theme/types/TypographyVariant';

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 audit runs 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