V Verino
GitHub
One core, seven frameworks, zero dependencies

Stop wasting time building OTP inputs, start using Verino engine

One invisible input captures SMS autofill, password managers, and paste. One pure state machine drives React, Vue, Svelte, Alpine.js, Vanilla JS, Web Components, and React Native.

Live demo

Type any 6 digits

Powered by @verino/vanilla, zero runtime dependencies

8

packages, one core

1,330+

tests passing

100%

core coverage

0

runtime dependencies

Frameworks

Same behavior, every framework

Pick a tab. This is the real adapter running, not a screenshot.

Type any 6 digits

Type any 6 digits

Type any 6 digits

Type any 6 digits

Type any 6 digits

Type any 6 digits

const otp = useOTP({ length: 6 })

<TextInput
  {...otp.hiddenInputProps}
  style={StyleSheet.absoluteFill}
/>
{otp.getSlots().map((slot) => (
  <View style={styles.slot}>
    <Text>{slot.value}</Text>
  </View>
))}

Native SMS autofill on iOS and Android. Can't run inside a browser, so this one's a code sample instead of a live demo. Try it in the Expo example.

Scenarios

One adapter, every scenario

Same @verino/vanilla instance, reconfigured live. Including the built-in countdown and resend row.

Type the code to see it complete

Architecture

Built around one architectural decision

Six glued-together inputs break autofill. Verino uses one.

<input opacity:0 inset:0 z-index:1>  ← real input
[div][div][div][div][div][div]       ← decoration

One real input, zero hacks

A single transparent input sits over purely decorative slot divs. The browser only ever sees one field, so SMS autofill, password managers, and IME all work natively.

Native SMS autofill

`autocomplete="one-time-code"` on the web, `textContentType="oneTimeCode"` and `autoComplete="sms-otp"` on React Native. Wired in automatically, every adapter.

Zero runtime dependencies

@verino/core has no DOM access and no dependencies at all. Every adapter imports only from the core, never from each other.

Fully accessible by default

Proper ARIA roles, labelled groups, and screen reader support come from using one real input, not from extra ARIA plumbing bolted on after.

Framework native, not ported

Each adapter is written for its framework: real Vue refs, a real Svelte store and action, a real React hook. Nothing is a wrapped port of another framework’s version.

Tested like it matters

1,330+ tests across 19 suites, Playwright E2E on chromium, firefox, webkit, and mobile chrome, and 100% statement, branch, function, and line coverage on the core.

Packages

Eight packages, one core

Pick the adapter for your stack. They all share the same behavior. Click a row to copy its install command.