A lightweight TypeScript library for masking and formatting input values.
Open the playground to try Vue and React masking examples in a browser.
# npm
npm install unimask
# yarn
yarn add unimask
# bun
bun add unimask
import { createMaskProcessor } from "unimask";
const maskProcessor = createMaskProcessor("(###) ###-####");
const result = maskProcessor("12345678");
console.log(result.formatted); // Output: (123) 456-78
console.log(result.placeholder); // Output: (123) 456-78##
const maskProcessor = createMaskProcessor(["+1 (###) ###-####", "###-###-####"]);
const result1 = maskProcessor("1234567890");
const result2 = maskProcessor("1234567");
console.log(result1.formatted); // Output: 123-456-7890
console.log(result2.formatted); // Output: 123-4567
It will automatically switch between masks based on the input value. Also order of masks does not matter, it will use from less to most complicated.
const maskProcessor = createMaskProcessor((value: string) => {
return value.startsWith("+") ? "+1 (###) ###-####" : "###-###-####";
});
const result1 = maskProcessor("1234567890");
const result2 = maskProcessor("+12345678901");
console.log(result1.formatted); // Output: 123-456-7890
console.log(result2.formatted); // Output: +1 (234) 567-8901
It will return formatted string but will not trim the excess characters.
const maskProcessor = createMaskProcessor("(###) ###-####", { trim: false });
const result = maskProcessor("12345678");
const result2 = maskProcessor("12345678901234567890");
console.log(result.formatted); // Output: (123) 456-78
console.log(result2.formatted); // Output: (123) 456-78901234567890
createMaskProcessor(mask: MaskInput, options?: MaskProcessorOptions) Creates a mask processor function.
MaskInput
Type alias for the mask input:
type MaskInput = string | string[] | ((value: string, lastChar: string, cursorPos: number) => string);
MaskProcessorOptions
Type alias for the mask processor options:
type MaskProcessorOptions = {
trim?: boolean;
};
MaskProcessorResult Type alias for the result of the mask processor function:
type MaskProcessorResult = {
formatted: string; // The formatted value based on the mask (just filled characters)
placeholder: string; // The placeholder value based on the mask (with filled and unfilled characters)
cursorPosition: number; // The cursor position after formatting
};
The following tokens are supported in the mask:
#: Digit (0-9).a: Alphabetic character in lowercase (a-z).A: Alphabetic character in uppercase (A-Z).S: Alphabetic character (a-zA-Z).X: Alphanumeric character (0-9, a-z, A-Z).*: Any character.!: Escape character. The next character will be treated as a literal character and will not be masked.Other characters in the mask are treated as literals and will be included in the formatted value.
<template>
<input v-model="value" v-unimask="'(###) ###-####'" />
</template>
<script setup lang="ts">
import { vUnimask } from "unimask/vue";
import { ref } from "vue";
const value = ref("");
</script>
<template>
<input :value="value" @input="onInput" />
</template>
<script setup lang="ts">
import { useUnimask } from "unimask/vue";
const { value, onInput } = useUnimask("(###) ###-####");
</script>
If you have any questions or suggestions, feel free to open an issue or pull request.
Copyright (c) 2025 by Dmytro Shevchenko