TypeScript and React Project Setup — A Working Setup for May 2026


Setting up a new TypeScript and React project in 2026 is significantly easier than it was three years ago but the choice of tools has actually narrowed at the same time the ecosystem has matured. Here is the setup I am using for new projects in May 2026, with the reasoning for each choice.

The framework choice.

Next.js remains my default for any production-bound React project. The combination of file-based routing, server components, image optimisation, and the broader ecosystem maturity means it is the easiest path to a production application. The Next.js App Router has become stable enough that I am no longer hedging on whether to use it for new projects.

Astro is the alternative I reach for when the project is content-heavy and the dynamic interactivity needs are localised. The Astro islands architecture and the support for multiple frontend frameworks in a single project make it a good fit for marketing sites, documentation, and content-driven applications.

Vite is the choice when I need a single-page application without server rendering. The development server is fast, the build output is clean, and the configuration burden is minimal.

Create React App is no longer my default for any new project. The CRA framework has been deprecated and the broader ecosystem has moved on.

For this guide I will focus on the Next.js setup as it is the most common starting point.

The starting setup.

npx create-next-app@latest my-app

The interactive prompts. The choices I make:

  • TypeScript: Yes. The TypeScript benefits in a React project are substantial and the tooling has matured to the point where the integration is straightforward.
  • ESLint: Yes. The linting catches real issues and the configuration that comes with create-next-app is reasonable.
  • Tailwind CSS: Yes. Tailwind has won the CSS-tooling argument in the React ecosystem and I no longer feel the need to relitigate the choice for new projects.
  • src/ directory: Yes. The cleaner separation of source from configuration is worth the small additional path overhead.
  • App Router: Yes. The App Router is stable and is the future direction. Starting any new project on the Pages Router is creating future migration work.
  • Custom import alias: Yes, the @/* alias. The cleaner import paths reduce the cognitive load on file reorganisations.

The package additions.

After the initial setup I typically add:

npm install zod
npm install -D @types/node prettier prettier-plugin-tailwindcss

Zod is the runtime schema validation library that has become the standard for TypeScript projects. The combination of TypeScript types and Zod runtime validation gives you both compile-time and runtime safety.

Prettier with the Tailwind plugin is my standard for code formatting. The Tailwind plugin sorts the class names into a consistent order, which dramatically improves readability of large class lists.

The TypeScript configuration.

The default tsconfig.json from create-next-app is reasonable. The settings I adjust:

  • strict: true is the default and should stay. The strict mode catches real issues.
  • noUncheckedIndexedAccess: true is worth adding. The setting catches array and object index accesses that might return undefined and forces you to handle the undefined case.
  • verbatimModuleSyntax: true is worth adding for cleaner import/export semantics.
  • The path aliases should match the project structure.

The ESLint configuration.

The default ESLint configuration that comes with create-next-app is okay but I usually extend it:

npm install -D eslint-plugin-import eslint-plugin-jsx-a11y eslint-config-prettier

The import plugin catches common import organisation issues. The a11y plugin catches accessibility issues in JSX. The prettier config disables ESLint rules that conflict with Prettier formatting.

The directory structure.

The structure I use for a medium-sized Next.js project:

src/
  app/                  # Next.js App Router pages
    (marketing)/        # Route group for marketing pages
    (app)/              # Route group for authenticated app pages
    api/                # API routes
  components/
    ui/                 # Low-level reusable UI components
    [feature]/          # Feature-specific components
  lib/
    db/                 # Database client and queries
    auth/               # Authentication utilities
    utils/              # Generic utility functions
  styles/               # Global styles
  types/                # Shared TypeScript types

The structure scales reasonably from small projects to medium-sized projects. The route groups in the App Router are useful for separating different sections of the application without affecting the URL structure.

The state management.

For most projects I do not reach for a global state management library at all. The combination of React’s built-in state, the server components for data fetching, and React Query (TanStack Query) for client-side data fetching covers most needs.

For projects that genuinely need client-side global state, Zustand is my current pick. The API is straightforward, the bundle size is small, and the integration with TypeScript is clean.

Redux Toolkit remains a reasonable choice for the projects that genuinely need its specific features but the cases where it is the right choice have narrowed.

The data fetching.

For server components, the fetch API with Next.js’s enhanced caching and revalidation is the default. The pattern works well and the server-side rendering is fast.

For client components that need data fetching, TanStack Query is my default. The mature caching, the strong TypeScript integration, and the broad ecosystem make it the right choice.

For forms, React Hook Form with Zod resolver is the combination I use. The form state management is clean and the validation integrates with the shared schema types.

The styling approach.

Tailwind CSS for nearly everything. The utility-first approach combined with the component-extraction patterns covers most styling needs.

For component primitives, I usually start with shadcn/ui. The components are added to the project source code rather than installed as a dependency, which means you can customise them freely. The Radix UI primitives underneath are accessible and well-tested.

For animations, Framer Motion remains the go-to library when motion is required. CSS animations are fine for simple cases.

The deployment.

For a Next.js project, Vercel is the path of least resistance. The deployment is fast, the configuration is minimal, and the platform features integrate well with the framework.

For projects with specific deployment requirements, AWS via the SST framework or the Open Next adapter is a viable alternative. The Cloudflare Workers deployment story for Next.js has improved but is still not as smooth as Vercel.

For static sites that do not need the dynamic features of Next.js, Astro deployed to Cloudflare Pages or Vercel is the cleaner story.

The testing approach.

Vitest for unit tests. The Vite-native test runner is fast and the TypeScript integration is clean.

Playwright for end-to-end tests. The reliability and the developer experience are good. The recording feature is genuinely useful for getting started on E2E coverage.

React Testing Library for component tests where unit tests need to render components.

The CI/CD approach.

GitHub Actions for most projects. The integration with the rest of the GitHub developer experience is convenient. The setup for a typical Next.js project is straightforward — install, lint, type check, test, build.

The deployment is usually handled by the hosting platform’s automatic integration with GitHub rather than by the CI/CD pipeline directly.

The starting point that all of this produces is a project that is opinionated but easy to deviate from when the project’s needs are specific. The choices are conservative — they are choices that have been used in production by many teams and that have the documentation and community support to be confidently used. The 2026 React ecosystem is more mature and more boring than the 2020 ecosystem, and the boring choices are the productive ones for most projects.

For developers picking up React and TypeScript for the first time in 2026, the recommendation is the same — use Next.js, start with the App Router, embrace TypeScript, use Tailwind for styling, and worry about the more specialised tools only when the project’s needs surface them. The minimal starting setup is enough to build serious applications. The complexity should grow from the actual project needs, not from the desire to use every available tool.