Skip to content

Part 0.6 — Preparing for Part 1: Project Structure and Mindset

Site Console Site Console
4 min read Updated Nov 24, 2025 Web Development 0 comments

You now have the fundamentals: a configured environment, a Git workflow, and a grasp of how the web works.
Before jumping into Part 1, we’ll focus on something often skipped but absolutely crucial — how to structure your full-stack project and how to think like a full-stack engineer.


1. The Mindset of a Professional Full-Stack Developer

Full-stack work isn’t about doing “frontend and backend” separately — it’s about connecting them meaningfully.

Here’s how pros think:

  • End-to-end flow awareness: Every UI interaction maps to a backend operation and a database query.

  • Ownership: You own the experience, from button click to database write.

  • Consistency: Naming conventions, error formats, and DTOs should match across the stack.

  • Maintainability over speed: Your future self (and your teammates) should be able to read your code easily.

  • Automation over repetition: If you do something twice manually, script it once.

The mindset is: architect first, code second.


2. The Monorepo Approach (One Workspace to Rule Them All)

We’ll build our app as a monorepo — a single codebase containing both frontend (React) and backend (NestJS), managed by pnpm workspaces.

Why?

  • Shared code (types, DTOs, utils) between client and server

  • One pnpm install for everything

  • Easier CI/CD setup

  • Simplified version control


3. Directory Structure Overview

Here’s the structure we’ll use throughout the entire series:

fullstack-app/
├── apps/
│   ├── web/           # React + TypeScript frontend
│   └── api/           # NestJS + Prisma backend
├── packages/
│   ├── types/         # Shared TypeScript types/interfaces
│   ├── utils/         # Common helper functions
│   └── config/        # Shared environment and constants
├── prisma/            # Central Prisma schema + migrations
├── .github/           # CI/CD workflows
├── docker/            # Dockerfiles and compose configs
├── .env.example       # Environment template
├── package.json
├── pnpm-workspace.yaml
└── README.md

Each folder will evolve in later parts — React components in web, REST controllers and DTOs in api, and shared contracts in packages/types.


4. Setting Up pnpm Workspaces

Inside your root folder:

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

This tells pnpm to treat all subfolders as part of one workspace.
Now, when you run pnpm install, dependencies are linked intelligently — no duplication, no drift.


5. Environment Variables and Config Management

A consistent .env file strategy is essential across the stack.
We’ll use dotenv in both React and NestJS.

Example .env.example:

DATABASE_URL="postgresql://postgres:password@localhost:5432/fullstack_dev"
API_URL="http://localhost:3000"
NODE_ENV="development"
JWT_SECRET="supersecret"

Each environment (development, staging, production) will have its own .env file, but all share the same structure.


6. Shared Types for End-to-End Consistency

Avoid backend–frontend drift by sharing TypeScript definitions.
In /packages/types:

// packages/types/src/user.ts
export interface User {
  id: number;
  name: string;
  email: string;
}

Use it everywhere:

// apps/web/hooks/useUsers.ts
import { User } from "@types/user";

This ensures React, NestJS, and Prisma always agree on what a “User” means — reducing bugs and integration issues.


7. Versioning, Linting, and Formatting Standards

Your workspace should enforce one style and one version of key tools.

Install and configure:

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

Add shared configs in /packages/config/eslint.config.js and /packages/config/prettier.config.js.

Example ESLint config:

module.exports = {
  extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint"],
  root: true,
};

Then apply it across apps using:

pnpm dlx eslint .

8. Developer Mindset: Automation and Documentation

Document every architectural decision as you go.
Use a docs/ folder or your README to capture:

  • Project purpose

  • API routes

  • Deployment steps

  • Environment variables

And automate what you repeat:

  • Database resets

  • Lint + format on commit (using Husky + lint-staged)

  • Pre-push tests in CI

When your setup automates quality, you focus on features.


9. Preparing for Part 1

You’re now set for the exciting part — building the frontend.

In Part 1, we’ll:

  • Spin up a new React + TypeScript app

  • Explore components, state, and events

  • Connect frontend interactions to real backend calls later

Before moving on, ensure:

  • PostgreSQL is running (Docker or local)

  • pnpm workspace is linked

  • .env and .gitignore are in place

  • GitHub repo is connected

Your project skeleton is now complete — production-minded, scalable, and clean.


10. Key Takeaway

Structure isn’t overhead — it’s velocity insurance.
By organizing your project early, you’ll build faster later with fewer surprises.

Next, we’ll officially start Part 1: React + TypeScript Basics: Components, State, Events — the hands-on beginning of your full-stack build.

Related

Leave a comment

Sign in to leave a comment.

Comments