Skip to main content

Overview

The frontend uses multiple configuration files to manage build tools, type checking, linting, and styling:
  • vite.config.ts: Vite build tool configuration
  • tsconfig.json: Root TypeScript configuration with project references
  • tsconfig.app.json: TypeScript configuration for application code
  • tsconfig.node.json: TypeScript configuration for Node.js tooling (Vite config)
  • eslint.config.js: ESLint linting rules
  • tailwind.config.js: TailwindCSS utility classes configuration
  • postcss.config.js: PostCSS plugins (autoprefixer, Tailwind)

Vite Configuration

Vite is configured with a minimal setup optimized for React development.

vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
})

Key Features

  • React Plugin: @vitejs/plugin-react enables React Fast Refresh and JSX transformation
  • Default Settings: Uses Vite’s optimized defaults for development and production

Common Customizations

Change the development server port:
export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
  },
})

Build Configuration

Customize production build output:
export default defineConfig({
  plugins: [react()],
  build: {
    outDir: 'dist',
    sourcemap: true,
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
        },
      },
    },
  },
})

TypeScript Configuration

The project uses TypeScript project references for improved build performance.

tsconfig.json (Root)

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}
This root config defines project references without including any files directly. It coordinates between:
  • App config: Application source code
  • Node config: Build tool configuration files

tsconfig.app.json (Application)

{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src"]
}

Compiler Options Explained

  • target: "ES2020": Compile to ES2020 JavaScript (modern browsers)
  • module: "ESNext": Use latest ECMAScript module syntax
  • lib: ["ES2020", "DOM", "DOM.Iterable"]: Include type definitions for modern JS and browser APIs
  • useDefineForClassFields: true: Use standard class field semantics
  • moduleResolution: "bundler": Optimized resolution for bundlers like Vite
  • allowImportingTsExtensions: true: Allow importing .ts/.tsx files directly
  • isolatedModules: true: Ensure each file can be transpiled independently
  • moduleDetection: "force": Treat all files as modules
  • noEmit: true: Don’t emit output (Vite handles bundling)
  • jsx: "react-jsx": Use React 17+ automatic JSX runtime (no need to import React)
This enables:
// No React import needed
export function Component() {
  return <div>Hello</div>
}
All strict options are enabled for maximum type safety:
  • strict: true: Enable all strict type checking options
  • noUnusedLocals: true: Error on unused local variables
  • noUnusedParameters: true: Error on unused function parameters
  • noFallthroughCasesInSwitch: true: Error on fallthrough cases in switch statements
  • noUncheckedSideEffectImports: true: Verify side-effect imports are intentional

tsconfig.node.json (Build Tools)

{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "target": "ES2022",
    "lib": ["ES2023"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["vite.config.ts"]
}
This config is specifically for Node.js tooling files like vite.config.ts. It uses a newer target (ES2022) since Node.js supports modern JavaScript features.

ESLint Configuration

ESLint is configured with TypeScript support and React-specific rules.

eslint.config.js

import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'

export default tseslint.config(
  { ignores: ['dist'] },
  {
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
    },
  },
)

ESLint Rules Breakdown

  • js.configs.recommended: ESLint’s recommended JavaScript rules
  • tseslint.configs.recommended: TypeScript-specific recommended rules
Catches common issues like:
  • Unreachable code
  • Unused variables (caught by TypeScript too)
  • Invalid regular expressions

Customizing ESLint

Add custom rules:
export default tseslint.config(
  { ignores: ['dist'] },
  {
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
      // Custom rules
      'no-console': ['warn', { allow: ['warn', 'error'] }],
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
      '@typescript-eslint/explicit-function-return-type': 'off',
    },
  },
)

TailwindCSS Configuration

Tailwind is configured to scan React component files for utility classes.

tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

Configuration Options

The content array tells Tailwind which files to scan for class names:
content: [
  "./index.html",           // HTML entry point
  "./src/**/*.{js,ts,jsx,tsx}", // All source files
]
Tailwind will purge unused classes not found in these files during production builds.
Extend or customize the default Tailwind theme:
theme: {
  extend: {
    colors: {
      primary: '#3490dc',
      secondary: '#ffed4e',
    },
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
    },
    spacing: {
      '128': '32rem',
    },
  },
}
Use in components:
<div className="bg-primary text-secondary font-sans p-128">
Add official or community plugins:
import forms from '@tailwindcss/forms'
import typography from '@tailwindcss/typography'

export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  plugins: [forms, typography],
}
Enable dark mode support:
export default {
  darkMode: 'class', // or 'media'
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}
Use dark mode classes:
<div className="bg-white dark:bg-gray-900">

Importing Tailwind

Tailwind directives are imported in src/index.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
This file is imported in src/main.tsx:
import './index.css'

PostCSS Configuration

PostCSS processes CSS with Tailwind and Autoprefixer.

postcss.config.js

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
  • tailwindcss: Processes Tailwind directives and generates utility classes
  • autoprefixer: Adds vendor prefixes for cross-browser compatibility

Configuration Best Practices

Type Safety

Keep strict TypeScript settings enabled. They catch bugs early and improve code quality.

Linting

Run ESLint before committing. The React Hooks rules prevent common React mistakes.

Build Optimization

Use Vite’s default optimizations. Only customize when you have specific performance needs.

Tailwind Purging

Ensure content paths in tailwind.config.js include all files using Tailwind classes.

Next Steps

Setup

Review installation and dependency requirements

Development

Learn the development workflow and build process

Build docs developers (and LLMs) love