Skip to main content

Play+ Application Folder Structure Guide

1. Philosophy: An Architecture That Breathes

The structure of our application is a direct reflection of our design philosophy. A clean, predictable, and scalable folder structure is essential for building applications that are a pleasure to maintain. It reduces cognitive load, streamlines collaboration, and ensures every developer knows exactly where to find what they need and where to put new code.

This guide defines the official, opinionated folder structure for all Play+ applications.

Core Principles

  • Centralized System Layer: All core Play+ helpers are initialized and exported from a top-level /system directory. All core files are prefixed with play. to create a clear visual distinction.
  • Centralized Configuration: All overridable config files for the Play+ helpers are housed under /config and follow the play.*.config.json convention.
  • Separation of Concerns: Clear boundaries are drawn between features, UI components, configurations, utilities, and foundational system services.
  • Co-located Testing: Each test file lives alongside the file it tests, encouraging maintenance and discoverability.

2. React Folder Structure

This structure is optimized for React applications built using tools like Vite or Create React App and emphasizes a feature-based, modular organization.

your-react-app/
├── .github/ # CI/CD workflows (pre-configured)
├── .husky/ # Pre-commit hooks (linting, testing)
├── public/ # Static assets (icons, images, robots.txt)

├── reports/ # (GIT-IGNORED) Outputs from tests and audits
│ ├── coverage/
│ └── performance/

├── docs/ # Project documentation (ADRs, guides)

├── config/ # Play+ helper configurations
│ ├── play.a11y.config.json
│ ├── play.cache.config.json
│ ├── play.error.config.json
│ ├── play.feature.config.json
│ ├── play.guard.config.json
│ ├── play.log.config.json
│ └── play.perf.config.json

├── .env # Root environment variables
├── .env.local

├── system/ # Centralized Play+ framework layer
│ ├── api/
│ │ ├── api.proxy.ts
│ │ ├── api.routes.ts
│ │ └── api.service.ts
│ ├── index.ts # Exports all Play+ helpers
│ ├── play.a11y.ts
│ ├── play.cache.ts
│ ├── play.env.ts
│ ├── play.error.ts
│ ├── play.feature.ts
│ ├── play.guard.ts
│ ├── play.log.ts
│ └── play.perf.ts

└── src/
├── assets/ # Global assets (fonts, logos, SVGs)
├── components/ # Shared, presentational components only
│ ├── Button.tsx
│ ├── Input.tsx
│ ├── Modal.tsx
│ └── ...
├── features/ # Feature-sliced application logic
│ ├── auth/
│ │ ├── AuthForm.tsx
│ │ └── AuthForm.test.tsx
│ └── profile/
├── shared/ # Reusable logic across app
│ ├── hooks/ # Reusable global hooks
│ └── lib/ # Utilities like date formatters
├── routes/ # React Router configurations
├── stores/ # Global state (e.g., Zustand, Jotai)
├── styles/ # Design tokens and base styles
│ ├── themes/
│ └── main.scss
├── types/ # Shared types and interfaces
├── middleware/ # Interceptors, guards, etc.
└── App.tsx
main.tsx

3. Angular Folder Structure

This structure adapts the Play+ philosophy to the idiomatic conventions of an Angular CLI project.

your-angular-app/
├── .github/ # CI/CD workflows
├── .husky/ # Pre-commit hooks

├── reports/ # (GIT-IGNORED) Outputs from tests and audits
│ ├── coverage/
│ └── performance/

├── docs/ # Project documentation

├── config/ # Play+ helper configurations
│ ├── play.a11y.config.json
│ ├── play.cache.config.json
│ ├── play.error.config.json
│ ├── play.feature.config.json
│ ├── play.guard.config.json
│ ├── play.log.config.json
│ └── play.perf.config.json

├── system/ # Centralized Play+ framework layer
│ ├── api/
│ │ └── api.service.ts
│ ├── play.a11y.service.ts
│ ├── play.cache.service.ts
│ ├── play.env.service.ts
│ ├── play.error.service.ts
│ ├── play.feature.service.ts
│ ├── play.guard.service.ts
│ ├── play.log.service.ts
│ └── play.perf.service.ts

└── src/
├── app/
│ ├── core/ # Core logic and singleton services
│ ├── features/ # Feature Modules (auth, profile, etc.)
│ ├── components/ # Shared, presentational UI components
│ ├── lib/ # Shared utility functions
│ ├── middleware/ # Guards, interceptors, pipes
│ ├── types/ # Shared interfaces, enums
│ ├── app-routing.module.ts
│ ├── app.component.ts
│ └── app.module.ts
├── assets/ # Global static assets
├── environments/ # Angular environment configs
└── styles/ # Design tokens and global styling
├── themes/
└── styles.scss

4. Key Directory Explanations

DirectoryPurpose & Guidelines
docs/Project-specific documentation like ADRs, onboarding guides, or team playbooks.
config/User-overridable Play+ config files. Use consistent play.*.config.json naming for clarity. For multi-app orgs, consider publishing these via a private npm package (e.g. @my-org/playplus-config).
components/Pure presentational components (UI-only, no business logic). Examples: Button, Card, Input. These are generic and reusable across features.
features/Feature-sliced architecture. Each folder represents a feature (e.g., auth/, profile/). Encapsulates business logic, views, and state for that domain.
shared/hooks/Global React hooks shared across features.
shared/lib/Reusable utility functions—formatters, validators, math utilities, etc.
system/Core Play+ system files. Houses reusable helpers (e.g., play.error.ts) and adapters (e.g., api.service.ts). Do not place app logic here.
types/Shared TypeScript interfaces, enums, and models used across multiple layers.
middleware/Guard functions, HTTP interceptors, authorization logic, etc.
reports/Git-ignored outputs from audits (e.g., Lighthouse), code coverage, etc.
styles/Theming and global design tokens. Includes themes/ folder for modular theme files.
routes/Centralized route config (React Router, Angular Router) with clear boundary from features.

5. Test Strategy

Play+ projects follow a test co-location strategy. This means that each test file lives directly alongside the file it tests.

📌 Example (React)

src/
└── components/
└── Button.tsx
Button.test.tsx

📌 Example (Angular)

src/
└── app/features/auth/
└── login.component.ts
login.component.spec.ts

Benefits:

  • Encourages test creation during development
  • Makes test discovery intuitive
  • Keeps test logic scoped and relevant

Use appropriate tooling like Vitest, Jest, or Karma/Jasmine, depending on your framework.


✅ Summary

The Play+ folder structure is designed for clarity, consistency, and maintainability. It embodies our design philosophy by drawing strong lines between app logic, reusable elements, and core system capabilities.

This guide should be treated as the canonical structure across all Play+ applications, enabling seamless onboarding, developer velocity, and architectural integrity.