Skip to content

Starter template for Next.js (app folder) application

Notifications You must be signed in to change notification settings

zavvdev/next-ts-template

Repository files navigation

Bootstrap

  1. Switch to Node.js version specified in .nvmrc file (Run nvm use if you have Nvm installed locally)

  2. Install pnpm (npm install -g pnpm)

  3. Run pnpm prepare && pnpm install

  4. Create .env.local file from .env.example

  5. Fill .env.local file with your variables.

  6. Run pnpm dev to launch app in development mode

  7. Run pnpm prod to build and launch app in production mode

Addition commands

pnpm lint - run eslint analyzer

pnpm prettier - run prettier analyzer

pnpm prettify - apply prettier style for codebase

pnpm analyze-code - same as pnpm lint && pnpm prettier

Project architecture

Layers

  • Entity
  • Domain
  • UI
  • Infra

Layers dependency flow

UI -> Domain -> Entity <- Infra

Entity

Independent layer. Contains core entities of the project. For example: User, PaymentMethod, Wallet etc. It should contain only entities that are related to domain business rules. For example, password validation schema or pagination schema are not related to business models but rather related to impementation details. Consider entities as some sort of database models.

Infra

The infrastructure layer deals with external services, data storage, and network communication. This includes APIs or any external resources that the application needs to interact with. Components in the Domain layer communicate with the Infrastructure layer to fetch data from APIs or perform other external operations. Also, it should consist of any code that is not related to business rules but rather as vital code for this codebase itself. What else should be here:

  1. Implementations for handling user authentication and authorization, including integration with authentication providers like OAuth, JWT (JSON Web Tokens), etc.

  2. Implementations for caching mechanisms to improve performance.

  3. Implementations for collecting application usage data, error tracking, and performance monitoring.

Domain

Houses the business logic and serves as an intermediary between the UI and Entity layer. It contains the application's core functionality and specific use-cases, such as data processing, validation, and business rules. This layer interacts with the UI layer to receive user inputs and data, processes them using the business logic.

UI

User interface part. It consists of components, which are responsible for rendering the user interface and handling user interactions. The primary goal of this layer is to present data to the users and collect their inputs. The UI layer should not contain business logic; instead, it delegates tasks to the Domain layer for processing.

./src/ui/components

Basic building blocks for UI. Separated into 5 types by Atomic Design principle. Dependency flow:

pages -> templates -> organisms -> molecules -> atoms

  1. atoms - 1-st type of reusable UI components
  • Depend only on props;
  • Controlled (in most cases. Try to always make them controlled);
  • Cannot depend on other reusable atom components from the same level;
  1. molecules - 2-nd type of reusable UI components
  • Can have internal state;
  • Can be composed from atoms only;
  • Cannot depend on other reusable molecule components from the same level;
  1. organisms - 3-d type of reusable UI components
  • Can be independent from incoming props and do specific scope of work;
  • Can be composed from atoms and molecules;
  • Cannot depend on other reusable organism components from the same level;
  1. templates - 4-th type of reusable UI components
  • Can be composed from atoms, molecules or organisms;
  • Cannot depend on other reusable template components from the same level;
  1. pages - 5-th type of reusable UI components
  • Can be composed from any entities from above;
  • Main entry point for route views;
  • Cannot depend on other reusable page components from the same level;

Each component from these layers can replicate the same layers logic if needed. For example, you can have page that will include its own atoms that will be used only in context of this page. In this case those atoms can import from src/ui/components/atoms since the page itself is a higher abstraction over global reusable atoms.

Give local feature components priority over global ones. It means that you need to develop a feature from perspective of isolation first and put each component in context of this feature. And only if feature components are needed globally - move them inside an appropriate folder of global components.