New Repo Setup
How this project was created with Vite, plus Tailwind v4 and ESLint setup steps you can reuse.
Create the project
Start a fresh React + TypeScript app with Vite:
npm create vite@latest my-app cd my-app npm install
Add Tailwind CSS (v4)
- Install Tailwind and the Vite plugin:
npm install -D tailwindcss @tailwindcss/vite
- Update
vite.config.tsto include the plugin:import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import tailwindcss from "@tailwindcss/vite"; export default defineConfig({ plugins: [tailwindcss(), react()], }); - Create your global CSS (e.g.,
src/index.cssorapp/app.css) with Tailwind imports and any base theme:@import "tailwindcss"; @theme { --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; } html, body { @apply bg-white text-slate-900 dark:bg-slate-950 dark:text-slate-100; } - Import that CSS in your root entry (e.g.,
main.tsxorapp/root.tsx).
Add ESLint (flat config, ESLint 9)
- Install lint deps:
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y globals
- Add
eslint.config.js:import js from "@eslint/js"; import globals from "globals"; import tsParser from "@typescript-eslint/parser"; import tsPlugin from "@typescript-eslint/eslint-plugin"; import reactPlugin from "eslint-plugin-react"; import reactHooks from "eslint-plugin-react-hooks"; import jsxA11y from "eslint-plugin-jsx-a11y"; export default [ { ignores: ["**/node_modules/**", "**/build/**", "**/dist/**"] }, { files: ["**/*.{ts,tsx}"], languageOptions: { parser: tsParser, parserOptions: { ecmaVersion: "latest", sourceType: "module", ecmaFeatures: { jsx: true } }, globals: { ...globals.browser, ...globals.node }, }, settings: { react: { version: "detect" } }, plugins: { "@typescript-eslint": tsPlugin, react: reactPlugin, "react-hooks": reactHooks, "jsx-a11y": jsxA11y, }, rules: { ...js.configs.recommended.rules, ...tsPlugin.configs.recommended.rules, ...reactPlugin.configs.recommended.rules, ...reactHooks.configs.recommended.rules, ...jsxA11y.configs.recommended.rules, "react/react-in-jsx-scope": "off", "react/prop-types": "off", "no-undef": "off", "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }], }, }, ]; - Add a lint script to
package.json:"scripts": { "lint": "eslint .", "dev": "vite", "build": "vite build", "preview": "vite preview", "typecheck": "tsc --noEmit" } - Run
npm run lintto verify.