Volar Plugin
Directives and macros are compile-time transforms: your code runs without any editor tooling. The vue-jsx/volar plugin is optional — install it only when you want that syntax to be understood by your editor and by command-line type checking.
The plugin adds type support for:
- Directives and
ref— see Directives for which directives the plugin covers. - Macros —
defineModel,defineSlots,defineExpose, anddefineStyle. Off by default; opt in with themacrosoption, and see Macros.
The same module serves two setups. Pick the one that matches where your TSX lives.
TSX Files: TS Macro
For .tsx files, install TS Macro and create ts-macro.config.ts:
import vueJsx from 'vue-jsx/volar'
export default {
plugins: [vueJsx()],
}When macros are enabled in the Vite plugin, enable the macro transform here too and keep the options consistent with the Vite configuration. See Macros:
import vueJsx from 'vue-jsx/volar'
export default {
plugins: [vueJsx({ macros: true })],
}Command-Line Type Checking
Install @ts-macro/tsc and use tsmc in place of tsc:
pnpm add -D @ts-macro/tsc{
"scripts": {
"typecheck": "tsmc --noEmit"
}
}tsmc reads the same ts-macro.config.ts, so no extra configuration is needed.
SFC Files: Vue Language Tools
.vue files are served by Vue Language Tools — the official Vue extension and vue-tsc — not by TS Macro. Register the same module as a Vue Language Tools plugin in tsconfig.json:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "vue-jsx"
},
"vueCompilerOptions": {
"plugins": ["vue-jsx/volar"]
}
}The plugin runs on every <script> block that uses TSX, so both <script setup lang="tsx"> and <script lang="tsx"> are covered. Command-line type checking uses the vue-tsc you already have — the plugin runs in the editor and under vue-tsc alike:
{
"scripts": {
"typecheck": "vue-tsc --noEmit"
}
}TIP
Type checking an SFC project with tsmc doesn't work: TS Macro doesn't parse .vue files. Keep tsmc for .tsx files and use vue-tsc for SFCs.
Options
Directive support is always on. ref and macros are the knobs, and both setups take the same shape — as the factory argument in ts-macro.config.ts, or under vueCompilerOptions['vue-jsx'] in tsconfig.json:
{
"vueCompilerOptions": {
"plugins": ["vue-jsx/volar"],
"vue-jsx": {
"macros": true
}
}
}| Option | Default | Description |
|---|---|---|
directives | always enabled | Type support for v-if, v-for, v-slot, and v-model. |
ref | true | Set false to skip it, or an object to configure the alias. |
macros | false | Set true or an options object to enable macro syntax. |
WARNING
Enabling macros here only affects type checking. The transform that makes them work at runtime is configured in the Vite plugin — keep the two in sync, as described in Macros.
Related Pages
- Directives — what each directive compiles to, and which ones the plugin types.
- Macros — enabling the macro transform in the Vite plugin.
- Extending the JSX Types — augment the JSX namespace that the plugin's generated code resolves against.