Project Structure

Document: 05-project-structure.md
Version: 1.0.0


Purpose

This document defines the standard project structure used across all Rundown web development projects.

A consistent project structure improves maintainability, reduces onboarding time, and allows developers to navigate any project without first learning its layout.

Unless project requirements dictate otherwise, all Rundown projects should follow the structure outlined below.


Standard Project Layout

project-name/

├── app/
├── components/
├── features/
├── hooks/
├── lib/
├── payload/
├── public/
├── styles/
├── types/
├── utils/
├── scripts/
├── tests/
├── docs/

├── .github/
├── .vscode/

├── .env.example
├── .gitignore
├── docker-compose.yml
├── Dockerfile
├── next.config.ts
├── package.json
├── pnpm-lock.yaml
├── README.md
├── tsconfig.json
└── eslint.config.js

Directory Standards

/app

Contains the application's routing, layouts, pages, API routes, and server components.

Rules:


/components

Contains reusable UI components shared across the application.

Examples:

Button/
Navbar/
Footer/
Card/
Hero/
Modal/

Rules:


/features

Contains feature-specific logic and components.

Examples:

Blog/
Portfolio/
Contact/
Products/
Authentication/

Each feature should contain its own:

Features should be isolated wherever practical.


/hooks

Contains reusable React hooks.

Examples:

useScroll.ts
useMediaQuery.ts
useTheme.ts

Rules:


/lib

Contains shared libraries and application services.

Examples:

database.ts

payload.ts

redis.ts

email.ts

analytics.ts

The lib directory should contain integrations rather than business logic.


/payload

Contains all Payload CMS configuration.

Typical structure:

payload/

collections/

globals/

blocks/

fields/

access/

hooks/

This directory should remain isolated from frontend code wherever possible.


/public

Contains publicly accessible static assets.

Examples:

Do not store client-managed content here.

Client uploads belong in Cloudflare R2.


/styles

Contains global styling resources.

Examples:

globals.css

variables.css

Tailwind configuration should remain outside this directory.


/types

Contains shared TypeScript types.

Examples:

product.ts

user.ts

navigation.ts

Shared interfaces should not be duplicated across features.


/utils

Contains pure utility functions.

Examples:

slugify.ts

formatDate.ts

capitalize.ts

Utility functions should remain framework-independent whenever possible.


/scripts

Contains project automation scripts.

Examples:

Scripts should be executable independently of the application.


/tests

Contains automated tests.

Project structure should mirror the application where practical.


/docs

Contains project-specific documentation.

Examples:

This directory complements Rundown OS and should only include documentation specific to the project.


Root Files

Every Rundown project should include:

File Purpose
README.md Project overview and setup instructions
.env.example Required environment variables
Dockerfile Container configuration
docker-compose.yml Local development services
package.json Project dependencies
pnpm-lock.yaml Dependency lock file
tsconfig.json TypeScript configuration
eslint.config.js Linting rules

Best Practices


Engineering Decision

Feature-Based Organization

Status: Accepted

Decision

Projects should primarily organize business logic by feature rather than by file type.

Reasoning

Feature-based organization:

Alternatives Considered

Feature-based organization provides the best balance between maintainability and scalability for the types of projects developed by Rundown.


Summary

A standardized project structure ensures every Rundown application follows the same architectural conventions.

Consistency improves collaboration, simplifies maintenance, and allows reusable tooling, documentation, and development practices to be applied across all projects.