02Personal · npm · Open source2024

create-pn-react-express - a Turborepo + Vite + React scaffold

Every new React project used to start the same way: scaffold a repo, then spend ten minutes creating folders and wiring up pnpm workspaces by hand. This CLI turns that into one command - it creates a Turborepo monorepo, drops in a Vite + React + TypeScript app, and scaffolds the source layout I reach for every time.

  • Node CLI
  • Turborepo
  • Vite
  • React
  • TypeScript

01The project

A single command sets up what would otherwise take ten manual steps:

  • npx create-pn-react-express <workspace-name> <app-name> - or run it without arguments and answer two prompts instead.
  • Bootstraps a Turborepo monorepo with pnpm as the package manager.
  • Adds a Vite + React + TypeScript app inside it.
  • Creates the source folders I open in every project - apis, components, constants, helpers, hocs, hooks, pages, redux, routes, types.
  • Rewrites pnpm-workspace.yaml to expose the new app, then runs a full workspace install.

02Tech stack

Node CLI
A zero-dependency entry point that shells out to the official generators.
prompts
Interactive workspace/app naming when no arguments are passed.
Turborepo + pnpm
The monorepo the scaffold produces, with a single workspace-install step.
Vite + React + TS
The client app, created via create-vite with the react-ts template.
child_process
execSync drives create-turbo, create-vite, and pnpm install in sequence.

03How it runs

The flow is a pipeline of four orchestrated steps, each inheriting the terminal so you can watch what the official generators are doing:

  • create-turbo bootstraps the workspace and package manager.
  • The default apps/ folder generated by Turborepo is removed, so the repo starts from a known state.
  • create-vite scaffolds the client app with the React + TypeScript template.
  • The source layout is anchored in src/, then pnpm-workspace.yaml is rewritten and the whole workspace installs once.

04Challenges while building

  • Bootstrapping interactive CLIs from inside another CLI. create-turbo and create-vite both want to own the terminal; inheriting stdio keeps their progress visible while forcing each step to run non-interactively.
  • Working-directory juggling. The script chdirs from the workspace root into apps/ and back, then writes pnpm-workspace.yaml; one wrong cwd corrupts every subsequent step, so the paths are asserted in order.
  • Undoing Turborepo’s defaults. create-turbo ships its own demo apps; tearing them out and rebuilding a clean apps/ directory is what makes every scaffold identical and predictable.
  • Two ways in, one flow out. The argument path and the interactive prompts path must produce the exact same pipeline without duplicating the orchestration.
  • First-run npx prompts. Node version and download confirmations surface mid-flow, and the script has to let them through instead of swallowing them or hanging.

05What\u2019s next

The README\u2019s future scope is to add a server app to the same command, so the scaffold grows from client-only to full-stack with the same guarantee - one command, one known layout.

06Links