Home

Awesome

Analyses E2E Tests

<a href="http://react-pwa.surenatoyan.com/" target="_blank" rel="noreferrer"> <img src="./public/cover.png" title="Base App"> </a>

React-PWA - v2 is here 🚀🎉⚡️

Starter kit for modern web applications!

Synopsis

This project (a GitHub template) is an opinionated setup for modern web applications. It's a combination of essential (and minimal) libraries/components/utils/dev-tools/etc., which developers usually need during the process of making modern React applications.

Motivation

Almost all projects need to have a router, a UI framework, store integration, theming, error handling, base file/folder structure, a builder, some developer tools (eslint, prettier, etc), tests and many more. In this starter kit, we tried to put together the best options available from the above-mentioned fields. Out of the box, it provides a modern production-ready setup created by developers for developers 💚

Tech stack

Core features

Dev tools and tests

Vite

Vite is a blazingly fast build tool based on native ES modules, rollup, and esbuild. It provides a great developer experience and super fast builds.

React

The latest version (v18) is used here. All dependencies support React v18 and the v2 is refactored according to the latest changes and requirements of React v18.

TypeScript

"Not using TypeScript is like driving without a seatbelt" - Matt Howard.

For those who are not familiar with TypeScript - don't worry, you will love it, as we all did. TypeScript is a superset of JavaScript; it should be very easy to work with if you know JavaScript.

Router

React Router v6 is used here. You can find routing in the src/routes folder.

UI-framework

MUI v5 is used here. MUI is a fully-loaded component library, super customizable, and easy to use.

Store

As a store management tool Recoil is used. Check the src/store folder for more information.

Notifications

Out of the box you have a notification system. To show a simple notification you can use useNotification hook:

import { useNotifications } from '@/store/notifications';

function MyCoolComponent() {
  const [notifications, actions] = useNotification();

  function showNotification() {
    actions.push({ message: 'Բարև, կարմի՛ր արև' });
  }

  return (
    ...
  );
}

Theme

The theme system is based on MUI Theme. To get the current theme mode or to change it you can use useTheme hook:

...
import { useTheme } from '@/store/theme';

function MyCoolComponent() {
  const [theme, actions] = useTheme();

  // check the current theme mode
  console.log(theme);

  // if you want to change the theme, call an appropriate action
  function toggleTheme() {
    actions.toggle();
  }

  ...
}

You have access to theme object via sx prop and styled-components:

import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { styled } from '@mui/material/styles';

// styled-components
const MyCoolButton = styled(Button)(({ theme }) => ({
  marginRight: theme.spacing(1),
  color: theme.palette.text.disabled,
}));

// sx prop
function MyCoolComponent() {
  return <Box sx={{ borderRadius: theme.shape.borderRadius }}>...</Box>;
}

Also, you can redefine the theme in the theme configuration file. Check the src/theme/themes.ts file for more information.

Base file/folder structure

Here how the base file/folder structure looks like:

<img src="./public/file-folder-structure.png" title="file folder structure">

Special attention deserves pages/, sections/ and components/. These are the main building blocks of the application and here is the difference between them:

Another important mention is any component's folder structure. It should look like this:

- [Component]
  - index.ts
  - [Component].tsx
  - types.ts
  - styled.ts
  - utils.tsx
  - etc.

It's a good practice to keep all related files in one folder. It makes it easier to find and maintain them. Only the first two files are required. You may or may not have component-related types, styles, utils, etc. But if you have them, keep them in the same folder and separate files. Let's see what each file is responsible for:

PWA

Out of the box, it's a Progressive Web Application. It can be installed on mobile and desktop devices 🙂, it can work offline, and many more. Check more about PWAs here

Your users will also be informed about the new version of your app:

<img src="./public/pwa-reload.png" width="600" title="pwa reload">

Performance

After all these integrations the biggest bundle size is ~79KB. It means even the first load will be pretty fast (in my case it's 1.1s), further loads (already cached by service worker and workbox) will take ~0.25s.

<img src="./public/bundle.png" title="bundle"> <img src="./public/audit.png" title="audit">

NOTE: The performance is not 100 because it's running on demo server.

Hotkeys

A basic implementation of hotkeys is demonstrated here. Check the src/sections/HotKeys for more information.

Currently, you can use the following hotkeys:

Alt+s - to toggle the theme mode Alt+t - to toggle the sidebar Alt+/ - to open the hotkeys dialog

Error Handling

Nobody likes white screens and crashes without any notes. In src/error-handling you can find the error handling implementation. Here you can find withErrorHandler high order component. You can wrap any component by this HOC and it will catch all errors and show a default or your custom fallback. Currently, the main APP component is wrapped by withErrorHandler HOC.

Pages

From a layout point of view the application consists of 3 main parts:

The last one is a router-based switcher. All routes are defined in src/routes. By default, pages are being loaded asynchronously via asyncComponentLoader. You can use it to asynchronously load any React component you want. It uses React.Suspense and React.lazy with some magic 🧙‍♂️

Tests

Tests are a vital part of any project. Sometimes they are boring, sometimes they are hard to write, but they are very important. This setup tries to make the testing process as easy as possible. It contains:

Unit tests

Vitest is used here for unit tests. Check src/insertIf/insertIf.spec.ts for an example. You can run unit tests by running:

npm run test:unit # or yarn test:unit
E2E tests

Playwright is used for e2e tests. Check e2e/ folder to see examples. You can run e2e tests by running:

npm run test:e2e # or yarn test:e2e

If you want to run e2e tests in UI mode, run:

npm run test:e2e:ui # or yarn test:e2e:ui

playwright.config.ts contains the configuration for e2e tests. Currently, it's configured to run tests in chromium, firefox and webkit browsers. You can add more browsers if you want.

GitHub Actions

There are 2 GitHub Actions workflows:

Environmental variables

Put your environmental variables in the .env file (they should be prefixed with VITE_) and use them in your code via import.meta.env.[variable_name] syntax. .env file is not committed to the repository (it's under .gitignore), but env/.shared is. You can use it as a template. Usually, you will have different .env files for different environments (dev, staging, production, etc.), like:

Copy the content of env/.[template_name] to .env file and fill it with your variables. Note: env/.shared is being copied to .env file automatically after npm install.

EsLint

The latest version of eslint with the latest recommended collection of eslint rules is available out of the box. It contains:

Check the .eslintrc.json file for more information.

Prettier

prettier - stop fighting about styling in code reviews; save your time and energy - configure it once and let the machine format/correct your code.

Check the .prettierrc.json file for more information.

There is an additional configuration for your import statements. They will be automatically ordered and grouped by the given rules (check the .prettierrc.js) - one more topic for debates in code reviews :)

Husky

You can use husky to lint your commit messages, run tests, lint code, etc.

Currently, only pre-commit hook is set up. Every time you try to do a commit it will run prettier and eslint to be sure that everything is according to the rules.

Lint-staged

lint-staged helps to run eslint and prettier only on staged files - it makes the linting process super fast and sensible.

https localhost

https localhost is a simple way to run your application on localhost with https.

Just run:

npm run https-preview # or yarn https-preview

after:

npm run build # or yarn build

and check https://localhost in your browser.

NOTE: the first time it will ask you about installing localhost certificate. For more info check this

Usage

You can use this template by just pressing Use this template.

<img src="./public/use-template.png" width="300" title="Use this temaplte">

Or you can fork/clone it.

Install dependencies:

npm install # or yarn

In order to run it in development, run:

npm run dev # or yarn dev

In order to do a production build, run:

npm run build # yarn build

There are other scripts as well:

Live Demo

<div> <img src="./public/demo-dark.png" width="280" title="Dark demo"> <img src="./public/demo-light.png" width="280" title="Light demo"> </div>

License

MIT