├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── .prettierrc.json ├── .stylelintrc.json ├── .vscode ├── .extensions.json └── .settings.json ├── README.md ├── index.html ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── src ├── App.jsx ├── assets │ └── images │ │ ├── app_screenshot.gif │ │ ├── favicon.svg │ │ └── logo.svg ├── index.css ├── index.html ├── main.jsx └── tests │ └── example.spec.js ├── tailwind.config.js └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | max_line_length = 80 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [*.md] 16 | max_line_length = 0 17 | trim_trailing_whitespace = false 18 | 19 | # Matches multiple files with brace expansion notation 20 | # Set default charset 21 | [*.{js,jsx,ts,tsx,py}] 22 | charset = utf-8 23 | 24 | [*.py] 25 | indent_style = space 26 | indent_size = 4 27 | 28 | # Tab indentation (no size specified) 29 | [Makefile] 30 | indent_style = tab 31 | 32 | # Matches the exact files either package.json or .travis.yml 33 | [{package.json,.travis.yml}] 34 | indent_style = space 35 | indent_size = 2 36 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "browser": true, 5 | "es2021": true, 6 | "jest/globals": true, 7 | "node": true 8 | }, 9 | "plugins": [ 10 | "react", 11 | "jsx-a11y", 12 | "jest", 13 | "import", 14 | "unused-imports" 15 | ], 16 | "extends": [ 17 | "airbnb", 18 | "airbnb/hooks", 19 | "plugin:import/recommended", 20 | "plugin:jest/recommended", 21 | "plugin:jsx-a11y/recommended", 22 | "prettier" 23 | ], 24 | "parserOptions": { 25 | "ecmaFeatures": { 26 | "jsx": true 27 | }, 28 | "ecmaVersion": "latest", 29 | "sourceType": "module" 30 | }, 31 | "overrides": [ 32 | { 33 | "files": [ 34 | "src/**/*.{js,jsx}" 35 | ], 36 | "rules": { 37 | "react/prop-types": "off", 38 | "import/order": [ 39 | "error", 40 | { 41 | "groups": [ 42 | "builtin", 43 | "external", 44 | "internal", 45 | [ 46 | "parent", 47 | "sibling" 48 | ], 49 | "index", 50 | "object", 51 | "type" 52 | ], 53 | "pathGroups": [ 54 | { 55 | "pattern": "./**/**\\.css", 56 | "group": "type", 57 | "position": "after" 58 | } 59 | ], 60 | "pathGroupsExcludedImportTypes": [ 61 | "builtin" 62 | ], 63 | "alphabetize": { 64 | "order": "asc", 65 | "caseInsensitive": true 66 | }, 67 | "newlines-between": "always", 68 | "warnOnUnassignedImports": true 69 | } 70 | ] 71 | } 72 | } 73 | ], 74 | "rules": { 75 | "jsx-a11y/click-events-have-key-events": "warn", 76 | "jsx-a11y/label-has-associated-control": "warn", 77 | "jsx-a11y/no-noninteractive-element-interactions": "warn", 78 | "jsx-quotes": [ 79 | "error", 80 | "prefer-double" 81 | ], 82 | "no-unused-vars": "warn", 83 | "react/function-component-definition": "off", 84 | "react/react-in-jsx-scope": "off", 85 | "react/prop-types": "warn", 86 | "semi": "error" 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | pnpm-debug.log* 7 | node_modules 8 | dist 9 | public 10 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSameLine": false, 4 | "bracketSpacing": true, 5 | "jsxSingleQuote": false, 6 | "plugins": ["./node_modules/prettier-plugin-tailwindcss"], 7 | "printWidth": 80, 8 | "quoteProps": "as-needed", 9 | "semi": true, 10 | "singleQuote": true, 11 | "tabWidth": 2, 12 | "trailingComma": "none" 13 | } 14 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["stylelint-scss", "@namics/stylelint-bem"], 3 | "extends": [ 4 | "stylelint-config-standard-scss", 5 | "stylelint-config-idiomatic-order", 6 | "stylelint-config-prettier-scss" 7 | ], 8 | "rules": { 9 | "font-family-name-quotes": null, 10 | "plugin/stylelint-bem-namics": { 11 | "patternPrefixes": [], 12 | "helperPrefixes": [] 13 | }, 14 | "scss/at-rule-no-unknown": [ 15 | true, 16 | { 17 | "ignoreAtRules": ["tailwind", "layer"] 18 | } 19 | ], 20 | "selector-class-pattern": null 21 | 22 | }, 23 | "overrides": [ 24 | { 25 | "customSyntax": "postcss-scss", 26 | "files": ["**/*.scss"] 27 | }, 28 | { 29 | "customSyntax": "@stylelint/postcss-css-in-js", 30 | "files": ["**/*.jsx", "**/*.tsx"], 31 | "rules": { 32 | "function-name-case": [ 33 | "lower", 34 | { 35 | "ignoreFunctions": ["/.*/"] 36 | } 37 | ], 38 | "selector-class-pattern": [ 39 | "^([a-z][a-z0-9]*)(-[a-z0-9]+)*((__([a-z][a-z0-9]*)(-[a-z0-9]+)*)?(--([a-z][a-z0-9]*)(-[a-z0-9]+)*)?)$" 40 | ], 41 | "value-keyword-case": [ 42 | "lower", 43 | { 44 | "ignoreFunctions": ["/.*/"], 45 | "ignoreKeywords": ["/.*/"], 46 | "ignoreProperties": ["/.*/"] 47 | } 48 | ] 49 | } 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /.vscode/.extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "editorconfig.editorconfig", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode", 6 | "orta.vscode-jest", 7 | "stylelint.vscode-stylelint", 8 | "styled-components.vscode-styled-components" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/.settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": true, 6 | "source.fixAll.stylelint": true 7 | }, 8 | "css.validate": false, 9 | "scss.validate": false, 10 | "stylelint.validate": ["css", "postcss", "scss"] 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vite React Starter 2 | 3 |  4 |  5 |  6 |  7 |  8 |  9 |  10 |  11 |  12 |  13 |  14 | 15 | > Opinionated Vite starter template. 16 | 17 |  18 | 19 | ## Description 20 | 21 | An starter template for Vite React 18 projects including a bunch of useful tools and libraries enforcing best practices and autofix on save. 22 | 23 | For styling it comes with SASS, Emotion, and TailwindCSS ready to use. Choose your favorite CSS framework and get started. It also includes the @namics/stylelint-bem plugin for BEM style validation. 24 | 25 | ## Built With 26 | 27 | - [Vite](https://vitejs.dev/) Next generation frontend tooling. 28 | - [Babel](https://babeljs.io/) The compiler for next generation JavaScript. 29 | - [React Router](https://reactrouter.com/) Declarative Routing for React.js 30 | - [ESLint](https://eslint.org/) Find and fix problems in your JavaScript code. 31 | - [Prettier](https://prettier.io/) Opinionated code formatter. 32 | - [Stylelint](https://stylelint.io/) A mighty, modern linter that helps you avoid errors and enforce conventions in your styles. 33 | - [@emotion/react](https://emotion.sh/) Emotion is a library designed for writing css styles with JavaScript. 34 | - [@emotion/styled](https://emotion.sh/) Styled is a way to create React components that have styles attached to them. 35 | - [Sass](https://sass-lang.com/) Syntactically Awesome Style Sheets. 36 | - [TailwindCSS](https://tailwindcss.com/) Rapidly build modern websites without ever leaving your HTML. 37 | - [Jest](https://jestjs.io/) Delightful JavaScript Testing. 38 | - [Testing Library](https://testing-library.com/) The React Testing Library is a very light-weight solution for testing React components 39 | 40 | ### Other Plugins 41 | 42 | - [prop-types](https://www.npmjs.com/package/prop-types) Runtime type checking for React props and similar objects. 43 | - [react-error-boundary](https://www.npmjs.com/package/react-error-boundary) Simple reusable React error boundary component. 44 | - [eslint-config-airbnb](https://www.npmjs.com/package/eslint-config-airbnb) Airbnb's extensible shared config. 45 | - [eslint-plugin-import](https://www.npmjs.com/package/eslint-plugin-import) Linting support of ES2015+ (ES6+) import/export syntax. 46 | - [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y) Enforce accessibility best practices for React components. 47 | - [eslint-plugin-unused-imports](https://www.npmjs.com/package/eslint-plugin-unused-imports) Report and remove unused es6 modules. 48 | - [postcss](https://www.npmjs.com/package/postcss) PostCSS is a tool for transforming CSS with JavaScript plugins. 49 | - [stylelint-config-idiomatic-order](https://www.npmjs.com/package/stylelint-config-idiomatic-order) Order your styles based on idiomatic-css. 50 | 51 | ## Getting Started 52 | 53 | To get a local copy up and running follow these simple example steps. 54 | 55 | ### Prerequisites 56 | 57 | - Recommended `node` : `>=16.13.0` 58 | - `npm` or `pnpm` or `yarn` 59 | 60 | I advice to use `pnpm` for managing dependencies. It's faster and more reliable than `npm`. To install [pnpm](https://pnpm.io/) just run: 61 | 62 | - `corepack enable` 63 | - `corepack prepare pnpm@7.0.0-rc.3 --activate` 64 | 65 | After that the syntax is the same as `npm` e.g. `npm install` becomes `pnpm install`. 66 | 67 | ### Setup 68 | 69 | 1. Download or fork this project 70 | 2. Extract the content to a new directory, rename it and cd the directory. 71 | 3. Install all dependencies using: 72 | 73 | - `npm install` or `pnpm install` or `yarn` 74 | 75 | ## Scripts 76 | 77 | ### Start dev server 78 | 79 | - `npm run dev` or `pnpm run dev` or `yarn run dev` and open the browser at `http://localhost:3000` 80 | 81 | ### Build for production 82 | 83 | - `npm run build` or `pnpm run build` or `yarn run build` 84 | 85 | ### Locally preview production build 86 | 87 | After creating the production build, run: 88 | 89 | - `npm run preview` or `yarn run preview` 90 | 91 | ### Start server 92 | 93 | - `npm run serve` or `pnpm run serve` or `yarn run serve` and open the browser at `http://localhost:4173` 94 | 95 | ## Connect With Me 96 | 97 | 98 | 99 | | | | 100 | | ------------ | ---------------------------------------------------- | 101 | | **GitHub** | [@fabri4c](https://github.com/fabri4c) | 102 | | **Twitter** | [@fabri_4c](https://twitter.com/fabri_4c) | 103 | | **LinkedIn** | [@fabri4c](https://www.linkedin.com/in/fabri4c/) | 104 | 105 | ## Show your support 106 | 107 | You can give a ⭐️ if you like this project! 108 | 109 | ## Acknowledgments 110 | 111 | The ideas and inspiration from this project are coming from the following: 112 | 113 | - [ESLint docs](https://eslint.org/docs/user-guide/configuring/) 114 | - [Prettier docs](https://prettier.io/docs/en/index.html) 115 | - [Stylelint docs](https://stylelint.io/user-guide/configure/) 116 | - [starter-vite-react](https://github.com/warugaki-web-developer/starter-vite-react) 117 | - [Vitamin](https://github.com/wtchnm/Vitamin) 118 | 119 | ## License 120 | 121 | No License. You can use this starter as you wish. 122 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |Vite React Starter 💯
9 |
10 | Vite + React
11 | ESLint + Prettier + Stylelint
12 |
13 | Sass + Emotion + Tailwind
14 |
15 | Jest + Testing Library
16 |