Vize

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, and oxlint.config.ts. It does not discover oxlint.config.mjs, .js, .cjs, .mts, or .cts. If your project holds one of those, init reports 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