How to Set Up vue3-otp-input with TypeScript

You can integrate vue3-otp-input into a Vue 3 TypeScript project by installing the package, importing the component with proper typing, and using InstanceType<typeof VOtpInput> to access exposed methods like clearInput and fillInput.

Setting up vue3-otp-input with TypeScript requires minimal configuration because the package ships with native TypeScript definitions. This lightweight OTP component works seamlessly with Vue 3's Composition API and provides full type safety for props, events, and imperative method calls.

Installation

Install the package via your preferred package manager:


# pnpm (recommended)

pnpm i vue3-otp-input

# npm

npm i vue3-otp-input

# yarn

yarn add vue3-otp-input

For CDN usage without a build step, add the script before mounting your Vue app:

<script src="https://unpkg.com/vue3-otp-input"></script>

The CDN version includes pre-compiled JavaScript and requires no TypeScript configuration.

Component Registration

You can register vue3-otp-input either locally within a single component or globally across your application.

Local Registration

Local registration provides better tree-shaking and is the recommended approach for TypeScript projects:

<script setup lang="ts">
import { ref } from 'vue'
import VOtpInput from 'vue3-otp-input'  // Default export from src/index.ts

const otpRef = ref<InstanceType<typeof VOtpInput> | null>(null)
const bindValue = ref('')

function onComplete(value: string) {
  console.log('OTP completed:', value)
}

function onChange(value: string) {
  console.log('OTP changed:', value)
}
</script>

<template>
  <v-otp-input
    ref="otpRef"
    v-model:value="bindValue"
    :num-inputs="6"
    input-type="letter-numeric"
    :should-auto-focus="true"
    @on-complete="onComplete"
    @on-change="onChange"
  />
</template>

Global Registration

For applications requiring the component across multiple routes, register it in your entry file:

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import VOtpInput from 'vue3-otp-input'

const app = createApp(App)
app.component('v-otp-input', VOtpInput)
app.mount('#app')

TypeScript Implementation Patterns

Typed Component References

Access the component's imperative API by typing the template ref with InstanceType<typeof VOtpInput>. This provides IntelliSense for the exposed methods defined in src/components/vue3-otp-input.vue:

const otpComponent = ref<InstanceType<typeof VOtpInput> | null>(null)

// Access exposed methods
otpComponent.value?.clearInput()      // Clears all inputs and resets focus
otpComponent.value?.fillInput('1234') // Programmatically fills the OTP

Event Handling with Type Safety

The component emits three typed events that you can handle with proper string signatures:

  • update:value – Emitted on every change for v-model synchronization
  • on-change – Fires when the OTP value changes, passing the current string
  • on-complete – Fires when the user fills the last input, passing the complete OTP string
<script setup lang="ts">
const handleChange = (value: string) => {
  // value is fully typed as string
  console.log('Current OTP:', value)
}

const handleComplete = (value: string) => {
  // Trigger API verification here
  console.log('Submitting OTP:', value)
}
</script>

<template>
  <v-otp-input
    @on-change="handleChange"
    @on-complete="handleComplete"
  />
</template>

Working with Exposed Methods

The component exposes two imperative methods via defineExpose in src/components/vue3-otp-input.vue:

clearInput()

Resets the internal OTP array, clears the display, and returns focus to the first input field.

const clearOtp = () => {
  otpRef.value?.clearInput()
}

fillInput(value: string)

Programmatically populates the OTP inputs with a provided string. The method distributes characters across the individual input fields and updates the internal state.

const autoFillOtp = (code: string) => {
  otpRef.value?.fillInput(code)
}

Architecture Overview

Understanding the internal structure helps with advanced customization and debugging TypeScript issues.

Component Separation

The library splits functionality across two files:

State Management

The wrapper maintains an internal otp array (ref<string[]>) synchronized with the value prop via watchers. When props.value changes externally, the watcher in vue3-otp-input.vue repopulates the internal array, ensuring the component reacts to programmatic updates.

Focus and Navigation

The activeInput index tracks which input currently holds focus. Helper functions focusInput, focusNextInput, and focusPrevInput manage focus movement, while focusOrder handles edge cases when shouldFocusOrder is enabled, ensuring sequential entry even if the user clicks out of order.

Summary

  • Install vue3-otp-input via npm, pnpm, or yarn to get full TypeScript definitions out of the box.
  • Register the component locally for tree-shaking benefits or globally for application-wide availability.
  • Type your template refs with InstanceType<typeof VOtpInput> to access clearInput and fillInput with full IntelliSense.
  • Handle typed events (on-change, on-complete) to respond to user input and completion states.
  • Understand the internal architecture: the wrapper manages state and focus while SingleOtpInput handles the DOM interactions.

Frequently Asked Questions

How do I get autocomplete for the OTP input methods in TypeScript?

Use InstanceType<typeof VOtpInput> when declaring your template ref. This provides full type definitions for the exposed methods clearInput and fillInput, as well as all component props and events.

Can I use vue3-otp-input with the Options API instead of Composition API?

Yes. While the component itself is built with the Composition API, you can consume it in Options API components by importing it normally and using ref in your data() function to access the component instance. The TypeScript types remain fully compatible.

Why is my v-model:value not syncing when I programmatically update the OTP?

Ensure you are updating the bound value with a string that matches the expected format. The component watches props.value and repopulates the internal otp array automatically. If you need immediate visual updates, use the fillInput method exposed on the component ref instead of mutating the bound value directly.

Does vue3-otp-input support server-side rendering (SSR)?

Yes, the component is compatible with SSR frameworks like Nuxt 3. Since it relies on standard Vue 3 features and does not access browser-only APIs during setup, it renders correctly on the server. However, the auto-focus feature (shouldAutoFocus) only activates on the client side after hydration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →