oxc-project/oxc · warning · OxcDiagnostic

`model` definition is deprecated. You may use the Vue 3-comp

Error message

`model` definition is deprecated. You may use the Vue 3-compatible `modelValue`/`update:modelValue` though.

What it means

Diagnostic from oxlint's vue/no-deprecated-model-definition rule (since oxlint 1.63.0), Vue 3-compat variant. It fires when allowVue3Compat: true is configured and a `model` option exists but does not match the exact forwards-compatible shape — model: { prop: 'modelValue', event: 'update:modelValue' } (kebab-case model-value accepted). The message points at the modelValue/update:modelValue alternative while still flagging the non-compat definition.

Source

Thrown at crates/oxc_linter/src/rules/vue/no_deprecated_model_definition.rs:25

    ast::{Expression, ObjectExpression, ObjectPropertyKind},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{
    AstNode,
    context::LintContext,
    rule::{DefaultRuleConfig, Rule},
    utils::is_vue_component_options_object,
};

fn deprecated_model_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`model` definition is deprecated.").with_label(span)
}

fn vue3_compat_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(
        "`model` definition is deprecated. You may use the Vue 3-compatible `modelValue`/`update:modelValue` though.",
    )
    .with_label(span)
}

#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
struct NoDeprecatedModelDefinitionConfig {
    /// Allow `model: { prop: 'modelValue', event: 'update:modelValue' }` (or
    /// the kebab-case `model-value` variant) which is forwards-compatible with
    /// Vue 3's `v-model`.
    allow_vue3_compat: bool,
}

#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema)]
pub struct NoDeprecatedModelDefinition(NoDeprecatedModelDefinitionConfig);

declare_oxc_lint!(

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Reshape the option to the exact compat pair: model: { prop: 'modelValue', event: 'update:modelValue' }
  2. Better: drop the model option and migrate fully to the modelValue prop with update:modelValue emits
  3. Re-check the kebab-case variant if the template uses model-value

Example fix

// before
model: {
  prop: 'value',
  event: 'input',
},
// after (compat shape)
model: {
  prop: 'modelValue',
  event: 'update:modelValue',
}
Defensive patterns

Strategy: validation

Validate before calling

# verify compat shape: prop must be modelValue, event update:modelValue
grep -rnA3 "model: *{" --include='*.vue' src | grep -E "prop:|event:"

Prevention

When it happens

Trigger: Config sets "vue/no-deprecated-model-definition": ["error", { "allowVue3Compat": true }] and the component's model option uses a different prop/event pair, e.g. { prop: 'value', event: 'input' }.

Common situations: Teams adopting the compat escape hatch during staged migration but only partially renaming props; the remaining old-shaped model options get this softer diagnostic instead of the generic one.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/4c391c1c4582cd85. Report an issue: GitHub.