{"id":11079,"library":"imask","title":"IMask.js","description":"IMask.js is a robust vanilla JavaScript input mask library that dynamically formats user input in form fields, ensuring data consistency and improving user experience. It supports a wide array of mask types including pattern, number, date, range, enum, and dynamic masks, and allows for custom definitions and repeating blocks. The library is currently in active development, with version 7.6.1 being the latest stable release, featuring frequent minor updates to address bugs and introduce enhancements like autofix options and improved IME support. A key differentiator is its framework-agnostic core, accompanied by dedicated plugins for popular frameworks such as React, Vue, Angular, Svelte, and Solid, enabling consistent masking behavior across various JavaScript ecosystems. It has no external dependencies and is designed for broad browser compatibility.","status":"active","version":"7.6.1","language":"javascript","source_language":"en","source_url":"https://github.com/uNmAnNeR/imaskjs","tags":["javascript","inputmask","input","mask","typescript"],"install":[{"cmd":"npm install imask","lang":"bash","label":"npm"},{"cmd":"yarn add imask","lang":"bash","label":"yarn"},{"cmd":"pnpm add imask","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While CJS is supported since v7.2.0, ESM `import` is the recommended modern approach. The `require` syntax might lead to issues with tree-shaking or module resolution in some bundlers.","wrong":"const IMask = require('imask');","symbol":"IMask","correct":"import IMask from 'imask';"},{"note":"For optimal tree-shaking and to reduce bundle size, specific mask types (like `Number`, `Date`, `PatternMasked`) should be imported for their side-effects via path imports (e.g., `imask/masked/number`). This populates the `IMask` factory with the necessary mask definitions.","wrong":"import { Number } from 'imask'; // Number, Date, etc., are not directly exported for tree-shaking\nimport IMask, { Number } from 'imask';","symbol":"Masked options (e.g., Number, Date)","correct":"import IMask from 'imask';\nimport 'imask/masked/number'; // for number mask\n// or specific masks like import 'imask/masked/date';\nconst element = document.getElementById('my-input');\nconst mask = IMask(element, { mask: Number });"},{"note":"Constructors for specific masked classes (e.g., `MaskedPattern`, `MaskedNumber`) are typically accessed as properties of the main `IMask` object after their respective modules have been imported (which usually happens implicitly with the main `imask` import, or explicitly for tree-shaking).","wrong":"import { MaskedPattern } from 'imask';\nimport { MaskedPattern } from 'imask/masked/pattern';","symbol":"IMask.Masked options (e.g., IMask.MaskedPattern)","correct":"import IMask from 'imask';\nconst patternMasked = IMask.MaskedPattern({ mask: '+{7}(000)000-00-00' });"}],"quickstart":{"code":"import IMask from 'imask';\n\ndocument.addEventListener('DOMContentLoaded', () => {\n  const phoneInput = document.getElementById('phone-input');\n  if (phoneInput) {\n    const phoneMask = IMask(phoneInput, {\n      mask: '+{7}(000)000-00-00',\n      lazy: false, // show placeholder from start\n      placeholderChar: '_'\n    });\n    \n    // Example of accessing values\n    phoneInput.addEventListener('blur', () => {\n      console.log('Masked Value:', phoneMask.value);\n      console.log('Unmasked Value:', phoneMask.unmaskedValue);\n    });\n  }\n\n  const currencyInput = document.getElementById('currency-input');\n  if (currencyInput) {\n    const currencyMask = IMask(currencyInput, {\n      mask: Number,\n      thousandsSeparator: ' ',\n      scale: 2, // digits after point\n      signed: false, // disallow negative\n      padFractionalZeros: true, // if true, then pads zeros at end to the length of scale\n      normalizeZeros: true, // appends or removes zeros at the end of the fractional part of a number\n      mapToRadix: ['.', ','], // to change radix point for `.` or `,` from keyboard\n      radix: '.', // fractional delimiter\n      autofix: true // automatically fix incomplete input\n    });\n  }\n});\n\n// To make this runnable in a browser, you'd need HTML like:\n// <input type=\"text\" id=\"phone-input\" placeholder=\"+7(___)___-__-__\">\n// <input type=\"text\" id=\"currency-input\" placeholder=\"0.00\">","lang":"typescript","description":"This quickstart demonstrates setting up two common masks: a phone number using a pattern mask and a currency input using a number mask. It highlights basic initialization, options like `lazy` and `placeholderChar`, and how to access `value` and `unmaskedValue`."},"warnings":[{"fix":"Update import paths from `import 'imask/esm/masked/some-mask'` to `import 'imask/masked/some-mask';`.","message":"Starting from `v7.1.2`, the explicit `esm` part in import paths for specific mask modules can be skipped. This means `import 'imask/esm/masked/number'` should now be `import 'imask/masked/number';`. While the old path might still work due to compatibility, updating is recommended.","severity":"breaking","affected_versions":">=7.1.2"},{"fix":"Ensure your build system correctly handles ESM modules. For CJS environments, explicit `require('imask/cjs/some-path')` might be necessary, though `import IMask from 'imask'` should generally resolve correctly if `package.json` `exports` map correctly.","message":"In `v7.1.1`, the `type: \"module\"` was set for all packages except Angular. This change primarily affects CommonJS environments or older build setups, potentially leading to module resolution issues if not configured correctly for ESM. `v7.2.0` later added a `cjs` build, mitigating some of these issues but requiring awareness.","severity":"breaking","affected_versions":">=7.1.1"},{"fix":"Ensure all HTML input elements intended for `IMask.js` have `type=\"text\"`.","message":"When applying `IMask` to an input element, always use `type=\"text\"`. Other input types (e.g., `type=\"number\"`, `type=\"tel\"`) are not officially supported and may lead to unexpected behavior or conflicts with native browser input handling.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use side-effect imports for specific masked types: `import IMask from 'imask'; import 'imask/masked/number';`.","message":"For optimal tree-shaking and reduced bundle size, individual mask types (e.g., `Number`, `Date`) should be imported via their specific paths (e.g., `import 'imask/masked/number'`) rather than attempting to destructure them from the main `imask` import. The latter will pull in the entire library.","severity":"gotcha","affected_versions":">=6.0.0"},{"fix":"Interact with the `IMask` instance (e.g., `mask.updateOptions()`, `mask.value = '...'`) to control the masked input. Use `onAccept` or `onComplete` callbacks for events. If modifying the underlying DOM element directly, ensure changes are synchronized or considered in the context of `IMask`'s internal handling.","message":"IMask operates by creating an internal 'masked input' layer. Directly manipulating the original HTML input element's properties (like `disabled` state or classes) dynamically via JavaScript or a framework's data binding might not reflect on the visible masked input. Events should also be attached to the `IMask` instance callbacks.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When using `RegExp` or `Function` masks, design them to validate intermediate states gracefully. For complex cases, `Pattern` or `Function` masks are often more suitable, or implement custom `validate` callbacks that handle partial inputs.","message":"Intermediate validation states for complex masks like `Date` or `RegExp` can be tricky. A mask like `/^123$/` will only validate the complete string '123' and prevent any input until it matches perfectly. Always consider intermediate values for masks, otherwise, input might not be possible.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `IMask` is imported as `import IMask from 'imask';` at the top of your module or that the `<script src=\"https://unpkg.com/imask\"></script>` tag is placed before any script attempting to use `IMask` in a global context.","cause":"The IMask library script was not loaded or initialized before attempting to use it, or it's not correctly imported in an ESM context.","error":"IMask is not defined"},{"fix":"Always initialize IMask using the main factory function: `const mask = IMask(element, options);` Do not try to directly construct `IMask.InputMask` or similar internal components. Ensure your bundler is configured correctly if tree-shaking is aggressively removing parts of `imask`.","cause":"This error can occur in specific build environments (e.g., production bundles) where the `InputMask` component might not be correctly exposed or tree-shaken, or when trying to instantiate it directly in a way not intended by the library.","error":"TypeError: IMask.InputMask is not a constructor"},{"fix":"For React/Vue plugins, ensure you are on the latest minor version. In `v7.6.0`, `onAccept` is now only called on init if the value changes, which might affect validation logic. Always refer to the specific plugin documentation for correct lifecycle and prop handling. Ensure `ref` is passed correctly in React hooks if needed.","cause":"Framework-specific plugins might have nuances. For React hooks (`useIMask`), issues can arise if the `value` prop is not handled correctly, or if `onAccept` is not called as expected. Old versions might not apply the mask on initial value set.","error":"Value not updating or mask not applying on component mount (React/Vue)"},{"fix":"Test copy/paste functionality thoroughly with your specific mask configuration. For number masks, ensure `thousandsSeparator` and `radix` options are correctly set to match expected input formats. Consider implementing a custom `prepare` callback to normalize pasted values if default behavior is insufficient.","cause":"IMask's internal handling of pasted input might not correctly interpret non-mask characters or resolve complex formatting variations during paste operations. This is especially noticeable with localized number formats.","error":"Copy/paste doesn't work as expected with complex masks (e.g., numbers with separators)"}],"ecosystem":"npm"}