Angular 17+ ⚡ standalone OTP/PIN input component — beautifully styled with SCSS, built for ReactiveForms, and optimized for speed & DX.
- 🧩 Plug & Play — drop-in standalone component (no NgModule needed)
- 📱 Mobile-friendly — supports
one-time-code
autofill & numeric keypad - 🎯 Customizable — length, numeric-only, mask character, autocomplete
- ⌨️ Smart UX — paste detection, arrow navigation, backspace handling
- ♿ Accessible — ARIA labels & roles built-in
- 🎨 Theme-ready — tweak with CSS variables
- ✅ Forms-ready — works seamlessly with Reactive & Template-driven forms
npm install ngxsmk-otp-input
👉 Requires Angular v17+
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
import { OtpInputComponent } from 'ngxsmk-otp-input';
@Component({
selector: 'app-demo',
standalone: true,
imports: [ReactiveFormsModule, OtpInputComponent],
template: `
<form [formGroup]="form" (ngSubmit)="submit()">
<h2>🔑 Enter OTP</h2>
<ngxsmk-otp-input
formControlName="code"
[length]="6"
[numeric]="true"
[mask]="false"
(changed)="onChanged($event)"
(completed)="onCompleted($event)">
</ngxsmk-otp-input>
<button type="submit">Verify</button>
</form>
`
})
export class DemoComponent {
form = new FormGroup({
code: new FormControl('', [Validators.required, Validators.minLength(6)])
});
onChanged(v: string) { console.log('Changed:', v); }
onCompleted(v: string) { console.log('Completed:', v); }
submit() { console.log('Form:', this.form.value); }
}
Input | Type | Default | Description |
---|---|---|---|
length |
number |
6 |
Number of OTP boxes |
numeric |
boolean |
true |
Only allow 0-9 digits |
mask |
boolean |
false |
Mask entered characters |
maskChar |
string |
• |
Character to show when masking |
autocomplete |
'one-time-code' | 'otp' | 'off' |
'one-time-code' |
Input autocomplete hint |
isInvalid |
boolean |
false |
Marks invalid styling |
idPrefix |
string |
'ngxsmk-otp' |
Input element id prefix |
Output | Type | Fires When |
---|---|---|
changed |
string |
OTP value changes |
completed |
string |
All boxes filled with valid input |
ngxsmk-otp-input {
--ngx-otp-border: #e5e7eb;
--ngx-otp-focus: #8b5cf6;
--ngx-otp-bg: #f9fafb;
--ngx-otp-fg: #1f2937;
--ngx-otp-invalid: #ef4444;
}
ng build ngxsmk-otp-input
Output: dist/ngxsmk-otp-input/
cd dist/ngxsmk-otp-input
npm publish --access public
If you like this project, give it a ⭐ on GitHub and share with others!
Made with ❤️ by developers for developers — because OTP inputs shouldn’t be painful.