Skip to content

Part 1.1 — Setting Up a React + TypeScript Project with pnpm

Site Console Site Console
4 min read Updated Nov 28, 2025 Web Development 0 comments
Setting Up a React + TypeScript Project with pnpm and Vite

If you’ve followed Part 0, your environment is ready: Node, pnpm, PostgreSQL, and Git.
Now, we’ll build the frontend foundation — a modern React + TypeScript project using Vite as our build tool.
This setup is lightweight, type-safe, and built to scale with our NestJS backend later.


1. Why Use pnpm + Vite for React Projects?

Traditional npm installs are slow and redundant.
pnpm fixes that by creating a single global package store. It’s faster, space-efficient, and ideal for full-stack monorepos.

Vite, on the other hand, replaces old bundlers (like CRA or Webpack) with lightning-fast hot reloads and TypeScript support out of the box.

Together, they give you:

  • Faster builds

  • Zero config TypeScript support

  • Modern ES module compatibility

  • Efficient monorepo integration


2. Create the Project

Let’s generate a React + TypeScript app using Vite and pnpm:

# From your workspace root (e.g., fullstack-app/apps)
cd apps
pnpm create vite web --template react-ts
cd web

Now install dependencies:

pnpm install

This creates a React app in /apps/web with TypeScript, ESLint, and hot module reload ready.


3. Folder Structure Overview

After Vite’s setup, your directory should look like this:

web/
├── public/
│   └── vite.svg
├── src/
│   ├── assets/
│   ├── App.tsx
│   ├── main.tsx
│   └── index.css
├── tsconfig.json
├── index.html
├── package.json
└── pnpm-lock.yaml

We’ll later adjust this structure for larger apps — separating components, hooks, and pages — but for now, keep it simple.


4. Configure ESLint and Prettier

Your editor should enforce code consistency automatically.
Let’s add ESLint and Prettier for linting and formatting.

pnpm add -D eslint prettier eslint-config-prettier eslint-plugin-react @typescript-eslint/parser @typescript-eslint/eslint-plugin

Create a .eslintrc.cjs:

module.exports = {
  parser: "@typescript-eslint/parser",
  parserOptions: { ecmaVersion: 2020, sourceType: "module" },
  settings: { react: { version: "detect" } },
  extends: [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  plugins: ["react", "@typescript-eslint"],
  rules: {
    "react/react-in-jsx-scope": "off"
  }
};

Add Prettier config (.prettierrc):

{
  "singleQuote": true,
  "semi": true,
  "printWidth": 80
}

Now test your setup:

pnpm dlx eslint src --fix

5. Verify TypeScript Configuration

Open your tsconfig.json.
Ensure strict mode is enabled — it’ll make your app more reliable.

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "ESNext"],
    "jsx": "react-jsx",
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

This ensures strong type checking, JSX support, and compatibility with modern React.


6. Run the App

Spin it up:

pnpm dev

Open your browser at http://localhost:5173.
You should see the default Vite + React screen.

Congratulations — your frontend environment is running with:

  • React

  • TypeScript

  • Vite

  • pnpm

You now have a modern baseline that rivals any production frontend setup.


7. Add a Simple Component to Test Type Safety

Let’s create a quick example to confirm our setup is working perfectly.

// src/components/Greeting.tsx
interface GreetingProps {
  name: string;
  age?: number;
}

export function Greeting({ name, age }: GreetingProps) {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      {age && <p>Age: {age}</p>}
    </div>
  );
}

Then import it into App.tsx:

import { Greeting } from './components/Greeting';

function App() {
  return (
    <main>
      <Greeting name="Ava" age={27} />
    </main>
  );
}

export default App;

If you accidentally pass the wrong prop type (e.g., age="27"), TypeScript will flag it immediately — proof your setup is working.


8. Version and Commit

Before we move forward, commit your setup:

git add .
git commit -m "Setup React + TypeScript app with Vite and pnpm"

You now have a reproducible, type-safe, and scalable React foundation ready for future integration with the backend.


9. Next Steps

In Part 1.2, we’ll start exploring React components and props in depth — building reusable, composable UI units that make large apps maintainable.

You’ve laid the groundwork for a professional frontend architecture.
From here, you’ll move from setup to structure.

Related

Leave a comment

Sign in to leave a comment.

Comments