Giter Site home page Giter Site logo

marcoturi / react-redux-boilerplate Goto Github PK

View Code? Open in Web Editor NEW
44.0 2.0 5.0 7.77 MB

A meticulously crafted, extensible, and robust architecture for constructing production-grade React applications ๐Ÿš€

License: MIT License

JavaScript 17.15% Shell 0.11% Gherkin 1.26% TypeScript 78.93% HTML 0.51% CSS 2.04%
cucumber playwright react redux semantic-release tailwindcss typescript vite eslint prettier radix-ui shadcn-ui

react-redux-boilerplate's Introduction

React Redux Boilerplate

code style: prettier Commitizen friendly MIT License GitHub Actions Workflow Status GitHub Actions Workflow Status

A meticulously crafted, extensible, and robust architecture for constructing production-grade React applications. The project aim to provide guidelines on the development key points of a long term React project:

  • A well-defined folder structure and code organization for enhanced maintainability and scalability, with particular attention to the possibility of splitting and sharing components across projects.
  • A robust state management approach to effectively manage data and maintain application code SOLID
  • An automated release system to streamline the deployment process and ensure seamless updates with automatic changelog, version bump and tags
  • Consistent code formatting and styling to enhance code readability, maintain consistency, and promote adherence to best practices
  • A headless theme, with few dependencies and focus on accessibility
  • Powerful E2E tests with Cucumber and Playwright

โšก Features

๐Ÿ‘‰ Table of Contents

โœจ Getting Started

npx degit marcoturi/react-redux-boilerplate my-app
cd my-app

# To enable yarn 4 follow the instruction here: https://yarnpkg.com/getting-started/install
yarn #Install dependencies.

Common Commands

  • yarn start - start a development server with hot reload.
  • yarn build - build for production. The generated files will be on the dist folder.
  • yarn preview - locally preview the production build.
  • yarn test - run unit and integration tests.
  • yarn test:coverage - run unit and integration tests with coverage.
  • yarn e2e:local - run E2E test locally. Make sure to run yarn start before in a separate shell.
  • yarn type-check - check for typescript errors.
  • yarn outdated - update dependencies interactively.
  • yarn format - format all files with Prettier.
  • yarn lint - runs ESLint.

๐Ÿ—„๏ธ Folder Structure and Code Organization

TLDR; Embrace the vertical slice architecture

The vertical slice architecture is the recommended structure. Each feature encapsulates components, state management (redux), API interactions, and hooks. This architecture offers several compelling advantages:

  1. Reduced Coupling: By isolating each feature within its own slice, dependencies between different parts of the codebase are minimized. This foster improved code comprehension, facilitates code modifications, and mitigates the risk of introducing bugs during changes.
  2. Enhanced Maintainability: by simplifying the process of locating code pertaining to specific features. This stems from the organization of feature-specific code within a single slice, rather than scattering it across multiple layers or components.
  3. Accelerated Development: by enabling parallel work on different features. Each feature can be developed and tested independently, fostering a more streamlined development process.
  4. Streamlined Testing: Testing becomes more manageable due to the ability to isolate each feature for testing purposes.
  5. Improved Onboarding: facilitates a smoother onboarding experience for new developers. The organization of code around user features, rather than technical layers or components, aligns with developers' familiarity.
  6. Packetization: Features can be effortlessly moved and shared across projects.

Over the years, different structures were born based on different layers of features, including Atomic design or Feature slice. However, dividing code into numerous layers of features reduce the developer experience by the constant navigation between multiple folders. Also, the moment you want to move the logic to another package the refactor is also more invasive.

If you need to re-use features across projects, within the following structure is very easy to move the folders in a monorepo package without much re-factoring (thanks also to the usage of alias in imports).

src
|
+-- assets                    # assets folder can contain all the static files such as images, fonts, etc.
|
+-- pages                     # routes and pages configuration
|
+-- features                  # features used across the entire application
|
+----- Feature X              # Just a folder container of a group of features
|
+---------- Feature A
|
+---------------- store       # redux slice
|
+---------------- hooks       # react hooks
|
+---------------- components  # react components
|
+---------------- services    # services consumes by redux
|
+---------- Feature B         # (slices, hooks, etc. inside)
|
+---------- Feature C         # (slices, hooks, etc. inside)
|
+-- shared
|
+----- config        #  all the global configuration, env variables etc. get exported from here and used in the app
|
+----- helpers       #  any helper function that don't belong to a feature i.e. logging, generic storage (localstorage), etc.
|
+----- store         #  redux configuration
|
+-- UI               # UI components and configuration
|
+----- Elements      # Basic and complex UI elements
|
+----- Layout        # Page layouts used across the app

FAQ

Q: What to do if features folder start multiplying ? A: Try to avoid more than 6 folders in the same folder, group them inside "scope" folders.

Q: I have only a redux slice, where should I put it? A: Put it in the features folder. You don't know if you will have to create components around it in the future.

๐Ÿ—ƒ๏ธ State management: Why redux?

TLDR; Embrace Redux for keep changes in your app more predictable and traceable.

Why should Redux reign supreme over the multitude of state management solutions? His strength lies in enforcing codebase consistency and facilitating effortless debugging through the ability to visualize, store, and potentially rehydrate application state in the event of errors (see error section).

Within a Redux-powered application, responsibilities are meticulously defined:

  • Components: Solely responsible for dispatching actions and displaying data through selectors. No business or domain logic inside.
  • Selectors and Reducers: Encapsulate the application's business and domain logic. Their pure function nature renders them highly testable, reusable through composition, and exceptionally maintainable.
  • RTK Query, thunks and Listener middleware: Orchestrates the management of all side effects.

Redux flow

While some may argue that newer state management solutions offer less boilerplate, these often lack a designated location for business code placement. In the React ecosystem, custom hooks provide the cleanest approach for addressing this issue. However, the reliance on custom hooks to encapsulate domain logic in a large team, can quickly lead to an unwieldy codebase, with components ballooning to over 200-300 lines. In my experience, without a clear project-defined location for application domain logic, it inevitably gravitates towards react/ui components, rendering them unmaintainable.

๐Ÿงฑ UI Components and Style system

TLDR; Chose UI Components with few dependencies

Choosing a UI library can be a complex decision, and it is often influenced by both the requirements of the project and the capabilities of the team. To ensure that a project is long-lived and maintainable, I recommend choosing a UI library that does not tie you with many dependencies and exposing the APIs of UI components to a minimum by encapsulating them.

Why Radix + Shadcn as UI component library?

Why Tailwind?

  • Consistency and Maintainability: Tailwind's utility-first approach promotes consistent styling across the entire codebase. Developers can easily reuse predefined classes and components, ensuring a unified look and feel throughout the project. This consistency makes it easier for new team members to onboard and maintain the codebase, reducing the risk of inconsistencies and maintainability issues.

  • Rapid Prototyping and Development: Tailwind's declarative syntax allows developers to quickly prototype and develop features without the overhead of writing complex CSS rules. The prebuilt utility classes provide a quick and straightforward way to style elements, accelerating the development process and enabling developers to focus on functionality rather than styling intricacies.

  • Reduced Code Bloat and Complexity: Tailwind eliminates the need for writing repetitive CSS rules, which can often lead to code bloat and complexity. The utility-first approach encourages developers to utilize predefined classes, reducing the amount of code they need to write and maintain. This simplification enhances code readability, maintainability, and overall project health.

  • Collaboration and Efficiency: Tailwind's consistency and component-based approach facilitate efficient collaboration among team members. Developers can easily share and reuse styled components, ensuring consistency and reducing duplication of effort. This collaboration promotes efficiency and productivity, particularly in large teams where multiple developers are working on the same codebase.

  • Responsive Design and Accessibility: Tailwind CSS provides a comprehensive set of utility classes for responsive design, enabling developers to easily create responsive layouts that adapt to different screen sizes and devices. Additionally, Tailwind's accessibility features make it easier to build websites that are inclusive and usable by people with disabilities.

  • Modular and Customizable: Tailwind's utility classes can be organized into custom components and modules, allowing developers to tailor the framework to the specific needs of their project. This modularity provides flexibility and customization, ensuring that Tailwind fits seamlessly into the project's architecture and design principles.

In summary, Tailwind CSS offers a plethora of benefits for long-term projects and large teams, including consistency, maintainability, rapid prototyping, reduced code bloat, collaboration efficiency, responsive design, accessibility, modularity, and a great developer experience. Its utility-first approach, prebuilt components, and focus on code quality make it an excellent choice for building complex and maintainable web applications.

๐ŸŒ Release system

TLDR; Automate Versioning and Changelog Generation via a standalone Pipeline

Over the years there have been different release systems: git flow, github flow, gitlab flow and truck-based delivery.

Beyond the choice of the release system, this project suggests automating this process within the pipeline, in order to avoid discrepancies and inefficiencies with semantic-release.

Streamlined Release Process

To initiate a new release, developers simply need to merge a branch into main. The system seamlessly handles versioning and changelog generation based on commit history. Naturally, this process is contingent upon successful test and build executions.

Adaptability to diverse Environments

This method seamlessly adapts to various deployment scenarios:

  • Real-time environment updates with every commit: Implement a job that triggers releases on the "environment" branch (e.g., develop).
  • Multiple environments: Duplicate the deployment logic for additional environments or centralize deployment using a baseline repository. Alternatively, leverage semantic-release's capability to generate context-specific tags (e.g., beta/alpha).

The complete toolkit:

  • Commitlint: Enhances commit consistency for automated versioning and changelog generation
  • Husky: Mandates commitlint execution for every commit
  • Semantic-release: Automates release/tag/changelog creation within the pipeline

This comprehensive toolkit streamlines the release process, ensuring efficiency, consistency, and reproducibility.

Why is important to have standard commits?

  1. Automated Changelog Generation and Semantic Versioning: Standardized commits enable the seamless generation of comprehensive changelogs and facilitate the accurate determination of semantic version increments.
  2. Enhanced Change Identification: By employing fundamental keywords such as "feat," "chore," and "revert," teams can effortlessly discern the nature of the modifications, fostering clarity and collaboration.
  3. Streamlined Onboarding for New Contributors: Standardized commits significantly reduce the onboarding effort for developers, enabling them to swiftly integrate into the team and contribute meaningfully.

๐Ÿ‘๏ธ Format and style

TLDR; Embrace a consistent style guide, avoid Eslint's flat format, and leverage Prettier for formatting

  • Postpone utilizing the new flat format until these issues are resolved: eslint and eslint-typescript
  • Forgo the use of eslint-plugin-prettier opt for eslint-config-prettier. In general, delegate formatting responsibilities to Prettier, not Eslint as they also suggest in their official docs.
  • Consider the available style guide options: standard, airbnb, google. For a comprehensive comparison, you can check here. Our preference is the airbnb style guide due to its widespread adoption and comprehensive coverage of React-specific guidelines.

List of rules:

โš ๏ธ Error Handling and Analytics

TLDR; If you use redux correctly, you achieve exceptional developer experience during debugging.

One of the compelling advantages of the architecture presented in this project is its remarkable ability to facilitate debugging and error handling, fostering an exceptional developer experience.

Throughout the development process, the Redux Dev Tools extension for the browser provides real-time insights into the application's state transitions triggered by user interactions. In a production environment, when utilized appropriately (i.e., components dispatch Redux actions without encapsulating any business logic within themselves), we gain the capability to meticulously trace every user action preceding the occurrence of an error or in case we want to track them for analytics purposes:

Sentry redux actions

Additionally, we can easily track and potentially rehydrate the user's state at the precise moment of the error (screenshot from sentry):

Sentry redux state

๐Ÿ“š Additional libraries

  • Time and dates: date-fns - Moment is dead. Date-fns is a maintained, fast, functional and modular alternative.
  • Forms: react-hook-form - Small size with no dependencies, good performance and DX and UX experience.
  • Data manipulation: ramda - Alternative for lodash that promotes functional programming
  • Logging and monitoring: Sentry

Contributing

Contributions are always welcome! If you have any ideas, suggestions, fixes, feel free to contribute. You can do that by going through the following steps:

  1. Clone this repo
  2. Create a branch: git checkout -b your-feature
  3. Make some changes
  4. Test your changes
  5. Push your branch and open a Pull Request

License

MIT

react-redux-boilerplate's People

Contributors

renovate[bot] avatar semantic-release-bot avatar marcoturi avatar

Stargazers

Noureddine Bouyous avatar Daniel Dorobantu avatar Amy Phan avatar SHASHIKUMAR VADEMPURA avatar Sutanto Gasali avatar Giovanni Ruzzi avatar Patrik Pyrzanowski avatar Areek Ray avatar Gorakh Raj Joshi avatar Adrian Doinea avatar  avatar Artem Gromakov avatar Artsiom Soryn avatar Ben Guericke avatar Ovuoke Aghwotu avatar Kevin Chang avatar Albert Chang avatar  avatar Ramganesh R avatar Harpreet Mall avatar  avatar Daniel Taki avatar  avatar Thijs Lambert avatar  avatar Christian Feo avatar  avatar Vito Laera avatar mircolac avatar Simone Magnolini avatar Alessandro Fontana avatar Luca Campli avatar  avatar  avatar  avatar ercรผment avatar Oluwole Samuel Olumide avatar Anthony DeFreitas avatar Juan Aristizabal avatar Fabrizio Guglielmino avatar Stefano avatar Damien avatar Donald Iloekwe avatar  avatar

Watchers

 avatar  avatar

react-redux-boilerplate's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update dependency vite to v5.2.11
  • fix(deps): update dependency react-redux to v9.1.2
  • fix(deps): update dependency @sentry/react to v7.113.0
  • fix(deps): update dependency lucide-react to v0.377.0

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/codeql-analysis.yml
  • actions/checkout v4
  • github/codeql-action v3
  • github/codeql-action v3
.github/workflows/release.yml
  • actions/checkout v4
  • actions/setup-node v4
  • actions/setup-node v4
  • actions/upload-artifact v4
npm
package.json
  • @radix-ui/react-label 2.0.2
  • @radix-ui/react-navigation-menu 1.1.4
  • @radix-ui/react-select 2.0.0
  • @radix-ui/react-slot 1.0.2
  • @radix-ui/react-switch 1.0.3
  • @radix-ui/themes 2.0.3
  • @reduxjs/toolkit 2.2.3
  • @sentry/react 7.112.2
  • class-variance-authority 0.7.0
  • clsx 2.1.1
  • lucide-react 0.376.0
  • ramda 0.30.0
  • react 18.3.1
  • react-dom 18.3.1
  • react-error-boundary 4.0.13
  • react-redux 9.1.1
  • react-router 6.23.0
  • react-router-dom 6.23.0
  • tailwind-merge 2.3.0
  • tailwindcss-animate 1.0.7
  • web-vitals 3.5.2
  • @commitlint/cli 18.6.1
  • @commitlint/config-conventional 18.6.3
  • @cucumber/cucumber 10.6.0
  • @cucumber/html-formatter 21.3.1
  • @cucumber/messages 24.1.0
  • @cucumber/pretty-formatter 1.0.1
  • @mswjs/data 0.16.1
  • @playwright/test 1.43.1
  • @semantic-release/changelog 6.0.3
  • @semantic-release/commit-analyzer 11.1.0
  • @semantic-release/git 10.0.1
  • @semantic-release/github 9.2.6
  • @semantic-release/npm 11.0.3
  • @semantic-release/release-notes-generator 12.1.0
  • @testing-library/dom 9.3.4
  • @testing-library/jest-dom 6.4.2
  • @testing-library/react 14.3.1
  • @testing-library/user-event 14.5.2
  • @trivago/prettier-plugin-sort-imports 4.3.0
  • @types/node 20.12.8
  • @types/ramda 0.29.12
  • @types/react 18.3.1
  • @types/react-dom 18.3.0
  • @typescript-eslint/eslint-plugin 7.8.0
  • @typescript-eslint/parser 7.8.0
  • @vitejs/plugin-react-swc 3.6.0
  • @vitest/coverage-v8 1.5.3
  • autoprefixer 10.4.19
  • cssnano 6.1.2
  • cucumber-console-formatter 1.0.0
  • cucumber-html-reporter 7.1.1
  • eslint 8.57.0
  • eslint-config-airbnb 19.0.4
  • eslint-config-airbnb-typescript 17.1.0
  • eslint-config-prettier 9.1.0
  • eslint-plugin-import 2.29.1
  • eslint-plugin-jsx-a11y 6.8.0
  • eslint-plugin-promise 6.1.1
  • eslint-plugin-react 7.34.1
  • eslint-plugin-react-hooks 4.6.2
  • eslint-plugin-react-refresh 0.4.6
  • eslint-plugin-unicorn 51.0.1
  • eslint-plugin-vitest 0.5.4
  • fs-extra 11.2.0
  • husky 9.0.11
  • jsdom 24.0.0
  • lint-staged 15.2.2
  • msw 2.2.14
  • pinst 3.0.0
  • postcss 8.4.38
  • prettier 3.2.5
  • prettier-plugin-tailwindcss 0.5.14
  • semantic-release 23.0.8
  • tailwindcss 3.4.3
  • ts-node 10.9.2
  • typescript 5.4.5
  • vite 5.2.10
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.3
  • node >=20.0.0
  • yarn >=4.0.0
  • yarn 4.1.1
nvm
.nvmrc
  • node 20.*

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.