Skip to main content

Project Characteristics

Naming Conventions

For detailed information on naming conventions for files, components, hooks, and more, please refer to the Naming Conventions page.

State Management

State management in the application prioritizes performance and simplicity. Client-side state is minimized, making the most of the server's capabilities to reduce complexity in the browser.

In cases where client-side state is necessary, Zustand is used as the primary state management solution. Zustand offers a minimalist and powerful API, perfectly compatible with React Server Components, allowing for the creation of separate and atomic stores that can be selectively imported into client components without compromising the overall architecture and without the need for a provider.

The application implements useActionState to manage form state. This implementation leverages improvements in form state handling while maintaining compatibility with Server Actions.

URL-based state management is implemented using the nuqs library, allowing important states to be preserved in the URL to improve shareability and navigation without losing user context.

The useFormStatus hook with its enhanced properties (data, method, action) is used as the primary tool for providing feedback during form operations, ensuring a smooth user experience during data submission processes.

Component Architecture

The application's architecture is strictly based on React Server Components (RSC) as its structural pillar. RSCs are a critical element for performance optimization, significantly reducing the amount of JavaScript sent to the client and facilitating direct access to server resources.

It is necessary to minimize the use of use client directives, limiting them exclusively to cases where user interactivity is essential or specific access to browser APIs is required. This technical restriction is fundamental to keeping most of the logic on the server, thus maximizing the application's performance and efficiency.

The implementation of Suspense is a mandatory technical requirement for all asynchronous operations, establishing defined loading states during processes such as data fetching. This specification guarantees an optimal user experience during loading cycles.

Server Actions are the standard protocol for data mutation operations, validation, and form processing, maximizing the security and efficiency benefits inherent in server-side execution.

Style Management

The approach to style management is primarily based on Tailwind CSS along with shadcn/ui components. To maintain style consistency and reduce repetition, we will implement an organized system for creating and applying classes.

For frequently repeated styles, it is recommended to use the @apply directive in separate CSS files named according to the entity/component. This allows for visual consistency throughout the application while leveraging the efficiency of Tailwind.

Each reusable UI component must have its variants and styled states clearly defined. More complex or specific styles should be extracted into separate files and applied using @apply, instead of long strings of classes within the components.

For components with style variations based on properties, we will implement utility functions for class construction that generate the appropriate combinations based on the received props. This keeps the styling logic encapsulated and facilitates maintenance.

A mobile-first approach will be used for all responsive designs, leveraging Tailwind's capabilities to create adaptable interfaces for different screen sizes in a consistent and predictable manner.

Text Management

The management of static texts in the application follows a domain-based approach to avoid hardcoded strings scattered throughout components. Each domain encapsulates its own UI texts in a messages.ts file within its folder, following the Screaming Architecture principle. Common texts shared across domains are defined in /config/messages.ts.

This practice improves maintainability, ensures consistency, and facilitates future internationalization (i18n) implementations.

For detailed information on text management strategies, patterns, and best practices, please refer to the Text Management page.

Folder Structure

The project implements Screaming Architecture along with Atomic Design, following a logical organization that facilitates navigation, maintenance, and scalability.

The main /src folder contains all the essential folders for development.

/src
├── app/ # App Router (layout, routes, pages)
│ ├── layout.tsx
│ ├── page.tsx
│ ├── dashboard/
│ │ ├── page.tsx
│ │ └── loading.tsx
│ └── api/
│ └── auth/route.ts

├── components/ # Global UI components
│ ├── ui/ # shadcn components copied via CLI
│ ├── atoms/ # Simple shared visual components
│ ├── molecules/ # Composition of atoms
│ ├── organisms/ # Composition of molecules
│ └── layout/ # Common layouts (Navbar, Sidebar, Footer)

├── domains/ # Business domains (Screaming Architecture)
│ ├── auth/
│ │ ├── components/ # Domain-specific components
│ │ │ ├── atoms/
│ │ │ └── molecules/
│ │ ├── hooks/
│ │ ├── stores/ # Zustand stores for the auth domain
│ │ │ └── auth.store.ts
│ │ ├── messages.ts # Auth domain text messages
│ │ ├── validation-messages.ts # Auth validation messages
│ │ ├── auth.schema.ts
│ │ └── actions.ts

│ ├── users/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── stores/
│ │ │ └── user.store.ts
│ │ ├── messages.ts # Users domain text messages
│ │ │ # For i18n: use messages/en.ts, messages/es.ts
│ │ └── ...

├── lib/ # Global logic and initializations
│ ├── auth.ts
│ ├── db.ts
│ └── middleware.ts

├── config/ # Global configurations
│ ├── site.ts # Titles, metadata, etc.
│ ├── messages.ts # Common/shared UI texts (cross-domain)
│ └── constants.ts # Global constants

├── styles/
│ ├── main.css # Global styles: resets, tailwind base, etc.
│ ├── components/ # Reusable global styles (not tied to a domain)
│ │ ├── atoms/
│ │ │ └── input.css
│ │ ├── molecules/
│ │ │ └── form-group.css
│ │ ├── organisms/
│ │ │ └── hero-section.css
│ │ └── layout/
│ │ ├── header.css
│ │ └── sidebar.css
│ │
│ ├── domains/ # Domain-specific styles (Screaming Architecture)
│ │ ├── auth/
│ │ │ └── login-form.css
│ │ ├── users/
│ │ │ └── user-card.css
│ │ └── ...
│ │
│ └── utils/ # Mixins, helpers, media queries, etc.
│ ├── media.css
│ └── animations.css

├── utils/ # Shared utility functions
│ ├── date.util.ts
│ ├── validation.util.ts
│ └── ...

├── stories/ # Visual components for Storybook
│ ├── components/
│ │ ├── button.stories.tsx
│ │ └── card.stories.tsx
│ ├── domains/
│ │ ├── auth/
│ │ │ └── login-form.stories.tsx
│ │ └── users/
│ │ └── user-card.stories.tsx
│ └── README.md

├── .storybook/ # Storybook configuration
│ ├── main.ts
│ └── preview.ts

├── .env # Environment variables
└── middleware.ts # Global Next.js middleware

The /app folder houses the main routes and pages of the application, following the file-system-based routing of Next.js (App Router). Here, the general layouts, main pages, and API routes of the project are defined.

The /components folder contains all globally reusable components, structured according to the principles of Atomic Design. Inside /ui, components generated by shadcn/ui are grouped, while /atoms, /molecules, and /organisms organize reusable visual elements from lesser to greater complexity. The /layout subfolder groups structural components such as navigation, sidebar, and footer.

The /domains directory organizes business logic following the Screaming Architecture philosophy. Each domain (e.g., auth, users, etc.) encapsulates its own components, hooks, services, validations, specific actions, and text messages. Additionally, within each domain, a /stores/ folder is included where the local state is defined using Zustand, and a messages.ts file contains all domain-specific UI texts, allowing for complete isolation and modularity by feature.

The /styles/ folder defines the visual foundation of the system, organized both by levels of abstraction (Atomic Design) and by business contexts. This structure allows for keeping reusable styles, domain-specific styles, and global visual configurations of the project separate.

The /lib folder centralizes initializations and shared logic between domains, such as authentication configuration, database access, or system middlewares.

In /config, global system configurations are defined, including the application's metadata in site.ts, global constants, and common messages shared across multiple domains in messages.ts. Domain-specific messages are located within each domain's folder, following the Screaming Architecture principle of encapsulation.

Inside /utils, generic utility functions such as formatters or validators are housed, which can be used transversally in multiple project modules.

The /stories directory stores Storybook stories used to document and visualize components in isolation. It is structured into subfolders that separate global components from those specific to a domain, maintaining consistency with the project's architecture. This allows for clear documentation aligned with the modular design of the application.

Finally, /.storybook/ contains the main Storybook configuration, including files like main.ts and preview.ts, which define the execution environment and story loading.

This structure promotes a clear separation of responsibilities, improves long-term maintainability, and facilitates collaborative work in scalable development environments.


Annexes

nuqs: Modern, type-safe search parameter manager for React applications.

nuqs | Type-safe search params state management for React