3 cool things about the `create-vite` CLI you might not have known
Source: Dev.to
At a glance
Everything starts in the init function of the src/index.ts file.
The CLI progresses through six stages:
- Get (or ask for) the project name and target directory.
- Handle the directory if it exists and is not empty.
- Get a valid package name (if the project name from step 1 isn’t a valid NPM package name).
- Ask the user to choose a framework and variant.
- Ask whether an immediate install is desired.
- Scaffold folders and files.
Key libraries that give the CLI its polished experience:
mri– parses CLI arguments.@clack/prompts– renders attractive interactive prompts.picocolors– adds colors to console output.
Overall, create‑vite is a straightforward and simple tool, but its implementation contains several interesting details.
Cool thing 1 – All the different CLI flags
Besides the documented --template flag, create‑vite supports several others:
| Flag | Description |
|---|---|
--overwrite / --no-overwrite | Overwrite the target directory if it’s non‑empty. |
--immediate / --no-immediate | Run the install and start the dev server immediately after scaffolding. |
--interactive (-i) / --no-interactive | Prompt the user for input or assume defaults. The default template is vanilla‑ts; overwrite and immediate default to false. Non‑interactive mode is handy for CI/CD pipelines or when an AI agent runs the command. |
Available template names
You can pass any of the following strings to --template:
// vanilla
"vanilla-ts",
"vanilla",
// vue
"vue-ts",
"vue",
"custom-create-vue",
"custom-nuxt",
"custom-vike-vue",
// react
"react-ts",
"react-compiler-ts",
"react-swc-ts",
"react",
"react-compiler",
"react-swc",
"rsc",
"custom-react-router",
"custom-tanstack-router-react",
"redwoodsdk-standard",
"custom-vike-react",
// preact
"preact-ts",
"preact",
"custom-create-preact",
// lit
"lit-ts",
"lit",
// svelte
"svelte-ts",
"svelte",
"custom-svelte-kit",
// solid
"solid-ts",
"solid",
"custom-tanstack-router-solid",
"custom-vike-solid",
// ember
"ember-app-ts",
"ember-app",
// qwik
"qwik-ts",
"qwik",
"custom-qwik-city",
// angular
"custom-angular",
"custom-analog",
// marko
"marko-run",
// others
"create-vite-extra",
"create-electron-vite"
Cool thing 2 – “Support” for AI agents
create‑vite uses @vercel/detect-agent to check whether an AI agent is invoking the CLI. If an agent is detected and interactive mode is enabled, the CLI prints a helpful message suggesting a non‑interactive run:
create-vite --no-interactive --template <template-name>
Cool thing 3 – Some coding techniques
Determining the package manager via npm_config_user_agent
The CLI can infer which package manager the user ran it with by reading the npm_config_user_agent environment variable. For example, with pnpm you can see the full agent string:
pnpm config get user-agent
# pnpm/10.20.0 npm/? node/v20.11.1 linux x64
The code then splits this string to extract the package manager name (see the implementation at line 777 of the source file).
Detecting whether stdin is a TTY
process.stdin.isTTY tells the CLI if the standard input is connected to a terminal. When input is piped (e.g., cat data.txt | xargs pnpm create-vite), isTTY is false, so interactive prompts are disabled.
Handling Ctrl‑C (cancellation) gracefully
After each prompt, the code checks whether the user cancelled the operation and, if so, exits cleanly with a friendly message:
if (prompts.isCancel(projectName)) return cancel();
The @clack/prompts author recommends this pattern, and seeing it in a production‑ready codebase reinforces its importance.