Project Setup With vize init
vize init selects, installs, and configures Vize in an existing project in one pass. It is
interactive by default and fully scriptable with flags.
Run it from the directory containing your project's package.json.
vpx vize init
It configures five things, each of which you can take or leave:
| Feature | What it wires up |
|---|---|
| oxlint plugin | oxlint-plugin-vize, in the file your lint command actually reads |
| vite plugin | @vizejs/vite-plugin in vite.config.* |
| nuxt module | @vizejs/nuxt in nuxt.config.* |
| fmt | project settings and formatter defaults, plus vize:fmt scripts |
| typecheck | the existing TypeScript project, or a new scaffold when missing, and the vize:check script |
| editor extension | a .vscode/extensions.json recommendation |
The vite plugin and the nuxt module are the same choice: init detects which one your project needs.
Init preserves existing configuration and does not create a dedicated Vize file. See Configuration for shared settings and the current release availability of this setup behavior.
What It Detects
Detection runs first and is printed before you are asked anything, so you can catch a wrong directory or a missing lockfile before any file is touched:
[vize init] detected in /path/to/project:
framework: Vite+ (vite.config.ts)
package manager: pnpm
language: TypeScript (tsconfig.json)
lint command: vp lint
Vue settings: vue: in vite.config.*
oxlint config: none
| Signal | How it is decided |
|---|---|
| Framework | nuxt.config.{ts,mts,js,mjs} or a nuxt dependency means Nuxt; otherwise a vite.config.* means Vite; otherwise neither |
| Both present | Nuxt wins — a Nuxt project owns its own Vite instance, so the module is the supported integration point. Override with --vite. |
| Neither present | The bundler feature is offered as unavailable; the other four remain choices. init does not invent a build setup for you. |
| Package manager | The lockfile first (pnpm-lock.yaml, bun.lockb/bun.lock, yarn.lock, package-lock.json), then the packageManager field. A Vite+ project uses vp add. |
| Language | tsconfig.json or a typescript dependency identifies TypeScript. Selecting typecheck creates tsconfig.json when absent. |
| Lint command | vp lint when Vite+ is in use, otherwise the oxlint binary. This decides which file the Oxlint configuration goes in. |
| Already done | An existing Vize config, an existing Oxlint config, an existing lint block, plugins already wired, and installed dependencies |
Which Lint File It Writes
This is the part worth understanding, because getting it wrong fails silently.
| Command | Reads |
|---|---|
vp lint, vp check |
the lint block in vite.config.ts |
oxlint, oxlint-vize |
.oxlintrc.json / oxlint.config.ts |
Vite+ never reads .oxlintrc.json. A .oxlintrc.json carrying jsPlugins and vize/* rules looks
configured, but vp lint ignores it, Oxlint never sees a vize/* rule id, and the run reports
zero Vize diagnostics while exiting 0. See the Oxlint Plugin guide for the full
picture.
init therefore writes the file your lint command reads, not the one that is easiest to write:
| Your project | What init writes |
|---|---|
| uses Vite+ | the lint block in vite.config.*, built with createVizeLintConfig() |
| does not use Vite+ | oxlint.config.ts when no readable config exists; otherwise preserves the existing config |
uses Vite+ and runs oxlint directly |
both entry points; newly generated settings use the same preset, while an existing readable Oxlint config is preserved |
| uses Vite+ but its Vite config cannot be edited | no lint config edit — see When Init Refuses To Edit |
The lint block is emitted through createVizeLintConfig(), which returns a complete block so the
jsPlugins entry that loads the bridge cannot go missing. The example focuses on the lint block;
retain the imports your existing plugins need:
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
import { createVizeLintConfig } from "oxlint-plugin-vize";
export default defineConfig({
lint: createVizeLintConfig({
preset: "happy-path",
settings: {
helpLevel: "short",
},
}),
}).withVue({});
For a project without Vite+, the equivalent oxlint.config.ts:
import { defineConfig } from "oxlint";
import { configs } from "oxlint-plugin-vize";
export default defineConfig({
plugins: ["vue"],
jsPlugins: ["oxlint-plugin-vize"],
settings: {
vize: {
preset: "happy-path",
helpLevel: "short",
},
},
rules: configs.happyPath,
});
Note
Oxlint auto-discovers
.oxlintrc.json,.oxlintrc.jsonc, andoxlint.config.ts. It does not discoveroxlint.config.mjs,.js,.cjs,.mts, or.cts. If your project holds one of those,initreports it as present but unread rather than treating it as configuration.
Non-Interactive Use
init refuses to prompt when stdin is not a TTY, so it fails fast in CI instead of hanging. Pass
--yes together with the features you want:
vpx vize init --yes --lint --vite --fmt --typecheck --editor
The example explicitly selects the Vite plugin with --vite; choose the Nuxt module option
instead for a Nuxt project. Feature flags override the detected selection. Unmentioned features
keep their detected defaults; use the negative flags below to exclude features you do not want.
| Option | Effect |
|---|---|
-y, --yes |
Accept the selection without prompting |
--lint / --no-lint |
The oxlint plugin |
--vite |
Force the Vite plugin, even if Nuxt was detected |
--nuxt |
Force the Nuxt module |
--bundler / --no-bundler |
The vite plugin or nuxt module, auto-detected |
--fmt / --no-fmt |
vize fmt |
--typecheck / --no-typecheck |
vize check; creates tsconfig.json when absent |
--editor / --no-editor |
The .vscode/extensions.json recommendation |
--dry-run |
Print the full plan and write nothing |
--no-install |
Write configuration without installing dependencies |
--package-manager <PM> |
One of pnpm, npm, yarn, bun, vp |
After feature selection, --dry-run prints the plan and stops before file writes or dependency
installation. It still prompts unless automatic confirmation is enabled. For a non-TTY preview,
run vpx vize init --yes --dry-run. The example below uses an existing TypeScript configuration
in a Vite+ project:
[vize init] plan:
lint configured Vite+ detected, so `vp lint` reads the `lint` block in vite.config.ts and never reads .oxlintrc.json; writes vite.config.ts
bundler configured adds vize() to vite.config.ts
fmt configured uses project settings and formatter defaults
typecheck configured uses tsconfig.json and project settings
editor configured writes .vscode/extensions.json recommending ubugeeei.vize
[vize init] would create .vscode/extensions.json
[vize init] would update vite.config.ts
[vize init] would update package.json
[vize init] would add scripts: vize:lint, vize:fmt, vize:fmt:fix, vize:check
[vize init] would run: vp add -D @vizejs/vite-plugin oxlint oxlint-plugin-vize vize
Running It Twice
init is idempotent after a successful run. Once configuration and dependencies are in place,
running again with the same selection and installation options adds no duplicate plugin entry,
script, or dependency and leaves every file byte-identical:
[vize init] plan:
lint unchanged Vite+ detected, so `vp lint` reads the `lint` block in vite.config.ts and never reads .oxlintrc.json
bundler unchanged vite.config.ts already uses @vizejs/vite-plugin
fmt unchanged uses project settings and formatter defaults
typecheck unchanged uses tsconfig.json and project settings
editor unchanged .vscode/extensions.json already recommends ubugeeei.vize
[vize init] nothing to do; the project is already configured
Already-configured features stay ticked in the prompt and are labelled as such, so re-running to add one more feature does not mean re-selecting everything.
When Init Refuses To Edit
init never guesses at a build config. If it cannot safely make a config edit, it leaves that config
edit to you, reports the feature as not configured, and prints a snippet to paste. Other planned
changes, including scripts and dependency installation, may still be applied. A blocked feature
makes the command exit non-zero; review the printed plan and actual file changes before retrying.
File writes and dependency installation are separate operations. If a later step fails, earlier changes may remain. Resolve the reported error, review the changed files, and run the command again.
This matters most when adopting Vize lint support in a Vite+ project. If the config already has a
lint block and Vize integration has not been detected, init will not merge into it
automatically, because merging risks dropping settings. Existing Vize integration remains
unchanged. The following example shows the initial-adoption refusal:
[vize init] lint: NOT configured — vp lint reads the `lint` block in the Vite config, but
vite.config.ts already has a `lint` block and merging into it would risk dropping settings, so
spread createVizeLintConfig() into it by hand
import { createVizeLintConfig } from "oxlint-plugin-vize";
export default defineConfig({
lint: {
...createVizeLintConfig({
preset: "happy-path",
settings: {
helpLevel: "short",
},
}),
// keep your existing lint keys here
},
});
Note what it does not do: fall back to writing oxlint.config.ts. That would leave vp lint
reading your untouched lint block and reporting nothing, which is worse than being unconfigured.
A project that fails loudly is fixable; one that is quietly silent is not.
Other config edits have limits too. init cannot choose a lint target among several Vite configs
or safely extend a config that is not a single plain defineConfig({ ... }) call. A plugins value
that is not an array literal or an invalid .vscode/extensions.json can also prevent the relevant
config edit. Check each feature's result rather than assuming the entire run changed nothing.
Editor Support
init writes a recommendation rather than installing anything:
{
"recommendations": ["ubugeeei.vize"]
}
This is checked in, applies to everyone on the project, and changes nothing on the machine that ran
init. Vize also ships integrations for editors other than VS Code, which init lists on success:
| Editor | Integration |
|---|---|
| VS Code | ubugeeei.vize |
| Zed | editors/zed |
| Neovim | editors/nvim |
| Vim | editors/vim |
| Helix | editors/helix |
| Emacs | editors/emacs |
See VS Code and Other Editors for per-editor instructions.
Relationship To vize setup
vize setup is the older, all-or-nothing command for a Vite or Vite+
project and remains available. init adds feature selection, Nuxt, package-manager detection,
a dry run, and a non-interactive mode. Use vize init when choosing what to adopt in an existing project.
Next Steps
- Static Analysis for the lint and type-checking model
- Oxlint Plugin for preset and settings reference
- Configuration for shared project settings
- CLI for the rest of the commands