Interactive CLI to scaffold a Vite + React + TypeScript app with optional Tailwind CSS v4, shadcn/ui, React Compiler, icon libraries, React Router, TanStack Query, and your choice of linter.
npx create-vite-reactstack
# or
npm create vite-reactstackYou can pass a project name:
npx create-vite-reactstack my-appPass . to scaffold in place into the current directory. Nothing is ever deleted — scaffolded files are added, and only the files the scaffold itself owns are overwritten:
npx create-vite-reactstack .You can also pass a relative path to scaffold into a nested directory (the last segment becomes the package name):
npx create-vite-reactstack apps/my-appRun without option flags and it walks you through:
- Project name
- TypeScript or JavaScript (JavaScript is gently overridden — TypeScript only)
- React Compiler (optional)
- Tailwind CSS
- Icon library (none / Lucide / Phosphor / Heroicons)
- shadcn/ui (requires Tailwind)
- React Router
- TanStack Query
- Linter (Biome / ESLint / Oxlint)
- Initialize git (includes an initial commit)
- Package manager (npm / pnpm / yarn / bun)
Then it scaffolds the project, optionally initializes git, installs dependencies, and prints next steps.
Every prompt can be answered with a flag — and passing any option flag makes the run non-interactive: explicit flags win and every option you didn't set falls back to its default, no questions asked. Run without option flags for the full interactive prompt, or pass --yes to accept all defaults.
| Flag | Description |
|---|---|
-y, --yes |
Use defaults for every option not set by a flag (skips all prompts) |
--compiler / --no-compiler |
Enable / disable React Compiler |
--tailwind / --no-tailwind |
Enable / disable Tailwind CSS v4 |
--shadcn / --no-shadcn |
Enable / disable shadcn/ui (requires Tailwind) |
--router / --no-router |
Add / skip React Router |
--query / --no-query |
Add / skip TanStack Query |
--linter <name> |
biome | eslint | oxlint |
--icons <name> |
none | lucide | phosphor | heroicons |
--git / --no-git |
Initialize / skip the git repository |
--pm <name> |
npm | pnpm | yarn | bun (alias: --package-manager) |
--skip-install |
Don't install dependencies |
-h, --help |
Show help |
-v, --version |
Show version |
Both --flag value and --flag=value work. Unknown flags are reported and ignored instead of being silently swallowed. Invalid values are rejected with an error.
npx create-vite-reactstack my-app --yes
npx create-vite-reactstack my-app --compiler --linter eslint --no-git
npx create-vite-reactstack my-app --yes --no-tailwind --skip-install
npx create-vite-reactstack . --yes --pm pnpm| Option | Default |
|---|---|
| React Compiler | off |
| Tailwind CSS | on |
| Icon library | lucide |
| shadcn/ui | on |
| React Router | off |
| TanStack Query | off |
| Linter | biome |
| Git | on |
| Package manager | detected from how you invoked the CLI (npm_config_user_agent) |
- Choosing ESLint pins TypeScript to
~6.0in the generated project, because typescript-eslint does not support TypeScript 7 yet. - Choosing pnpm writes a
pnpm-workspace.yamlwith anallowBuildslist so native postinstall builds (esbuild, Biome) aren't blocked by pnpm 10+.
pnpm install
pnpm build
pnpm start # runs the CLI
# or
node dist/index.js my-app
pnpm typecheck # tsc --noEmit
pnpm smoke # scaffold all matrix combos + assert the output
pnpm smoke:full # also install, build and lint the e2e projectsMIT