Setup


Step 1: Create new app vite.js

npm create vite@latest

# Project name: …
 vite-app-ts
# Select a framework:
 React
# Select a variant:
 TypeScript + SWC

Step 2: Install dependencies

Dependencies
npm i @emotion/cache @emotion/react @emotion/styled @fontsource/barlow @fontsource/public-sans @mui/lab @mui/material @mui/material-nextjs @mui/x-data-grid @mui/x-date-pickers @mui/x-tree-view

Dev dependencies
npm i --save-dev @types/node

Step 3: Modifying files

  • Copy and override tsconfig.json / jsconfig.json.
  • Copy and override tsconfig.node.json.
  • Copy src/theme.
  • Remove src/theme/with-settings/**.
  • Update vite.config.ts.
vite.config.ts
import path from 'path';
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
 
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: [
      {
        find: /^~(.+)/,
        replacement: path.join(process.cwd(), 'node_modules/$1'),
      },
      {
        find: /^src(.+)/,
        replacement: path.join(process.cwd(), 'src/$1'),
      },
    ],
  },
});
 

Step 4: Create files

src/config-global.ts
export const CONFIG = {
  site: {
    basePath: import.meta.env.VITE_BASE_PATH ?? '',
  },
};

src/global.css
@import '@fontsource/public-sans/400.css';
@import '@fontsource/public-sans/500.css';
@import '@fontsource/public-sans/600.css';
@import '@fontsource/public-sans/700.css';
@import '@fontsource/public-sans/800.css';
 
@import '@fontsource/barlow/400.css';
@import '@fontsource/barlow/500.css';
@import '@fontsource/barlow/600.css';
@import '@fontsource/barlow/700.css';
@import '@fontsource/barlow/800.css';

Step 5: Update theme

src/theme/create-theme.ts
export function createTheme(): Theme {
  const initialTheme = {
    colorSchemes,
    shadows: shadows('light'),
    customShadows: customShadows('light'),
    shape: { borderRadius: 8 },
    components,
    typography,
    cssVarPrefix: '',
    shouldSkipGeneratingVar,
  };
 
  const theme = extendTheme(initialTheme);
 
  return theme;
}

src/theme/color-scheme-script.ts
export const schemeConfig = {
  modeStorageKey: 'theme-mode',
  defaultMode: 'light',
} as const;

src/theme/theme-provider.tsx
export function ThemeProvider({ children }: Props) {
  const theme = createTheme();
 
  return (
    <CssVarsProvider
      theme={theme}
      defaultMode={schemeConfig.defaultMode}
      modeStorageKey={schemeConfig.modeStorageKey}
    >
      <CssBaseline />
      {children}
    </CssVarsProvider>
  );
}

Step 6: Testing

src/App.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
 
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

src/App.tsx
import './App.css';
import 'src/global.css';
import { ThemeProvider } from 'src/theme/theme-provider';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
 
export default function App() {
  return (
    <ThemeProvider>
      <Stack spacing={1} alignItems="center">
        <Button variant="contained">Button</Button>
        <Button variant="contained" color="primary">
          Button
        </Button>
        <Button variant="contained" color="secondary">
          Button
        </Button>
        <Button variant="contained" color="info">
          Button
        </Button>
        <Button variant="contained" color="success">
          Button
        </Button>
        <Button variant="contained" color="warning">
          Button
        </Button>
        <Button variant="contained" color="error">
          Button
        </Button>
        <Button disabled variant="contained">
          Button
        </Button>
      </Stack>
    </ThemeProvider>
  );
}