{"id":15376527,"url":"https://github.com/tomayac/js-input-masking","last_synced_at":"2026-02-07T15:11:13.197Z","repository":{"id":49045111,"uuid":"381326437","full_name":"tomayac/js-input-masking","owner":"tomayac","description":null,"archived":false,"fork":false,"pushed_at":"2021-09-07T08:56:54.000Z","size":37,"stargazers_count":39,"open_issues_count":1,"forks_count":2,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-02-02T00:32:17.244Z","etag":null,"topics":["input-mask","input-masking","inputmask","intl","intl-inputmask"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomayac.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-29T10:31:18.000Z","updated_at":"2023-12-20T09:45:29.000Z","dependencies_parsed_at":"2022-09-09T02:51:39.931Z","dependency_job_id":null,"html_url":"https://github.com/tomayac/js-input-masking","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomayac%2Fjs-input-masking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomayac%2Fjs-input-masking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomayac%2Fjs-input-masking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomayac%2Fjs-input-masking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomayac","download_url":"https://codeload.github.com/tomayac/js-input-masking/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245931897,"owners_count":20695964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["input-mask","input-masking","inputmask","intl","intl-inputmask"],"created_at":"2024-10-01T14:08:05.168Z","updated_at":"2026-02-07T15:11:08.179Z","avatar_url":"https://github.com/tomayac.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Input Masking 🎭\n\n**Author:** Thomas Steiner ([tomac@google.com](mailto:tomac@google.com),\n[@tomayac](https://twitter.com/tomayac))\n\n**Last updated:** 2021-09-07\n\n## The problem\n\nBy _\"restricting input using preformatted input masks (telephone number,\nbirthday, Social Security number), or even auto-correcting input by appending or\nremoving unnecessary characters\"_ [_cf._\n[Klimczak](https://books.google.es/books?id=xMJOm4ppCkYC\u0026printsec=frontcover\u0026dq=editions:OTpjPvHq_7MC\u0026hl=en\u0026sa=X\u0026redir_esc=y#v=onepage\u0026q=input%20masks\u0026f=false)],\n**input masking** helps users enter information in forms more correctly, and\nexisting data can be formatted adequately. Many implementations of input masking\n[exist in user land](https://bashooka.com/coding/javascript-input-mask-libraries/),\nproving that there is a true need for this feature.\n\n## A beginning of a proposal\n\nThis proposal is to gauge interest in making input masking part of the language,\nmaybe as a new interface of `Intl`. Here're some code snippets that show what\nthis could look like in practice:\n\n- **Globally agreed-on** input mask:\n\n  ```js\n  // 16 digits.\n  new Intl.InputMask(\"credit-card-number\").format(\"4012888888881881\");\n  // \"4012 8888 8888 1881\"\n\n  // 15 digits.\n  new Intl.InputMask(\"credit-card-number\").format(\"378282246310005\");\n  // \"3782 822463 10005\"\n  ```\n\n- **Locale-aware input mask** with customization options:\n  ```js\n  new Intl.InputMask(\"phone-number\", {\n    locale: \"de-DE\",\n    countryCode: \"leadingPlus\",\n    areaCode: \"leadingZero\",\n    groupSize: 2,\n  }).format(\"00494012345678\");\n  // \"+49 (0)40 12 34 56 78\"\n  ```\n- Fully **custom input mask** with a mask function:\n\n  ```js\n  new Intl.InputMask(\"custom\", {\n    maskFunction: (input) =\u003e input.toLowerCase().replaceAll(\" \", \"\"),\n  }).format(\"No Spaces No Uppercase\");\n  // \"nospacesnouppercase\"\n  ```\n\n## Polyfill\n\nWork on a polyfill that implements this proposal has started in\n[tomayac/js-input-masking-polyfill](https://github.com/tomayac/js-input-masking-polyfill).\nYou can see `Intl.InputMask` in action in the\n[demo](https://tomayac.github.io/js-input-masking-polyfill/demo/).\n\n## Isomporhic JS™\n\nMaking this part of the language would allow people to use this on\nthe **client** and the **server**.\n\n### On the client\n\nFor example, a **client-side implementation** could use this as follows (note\nthat the `type=\"tel\"` of the `\u003cinput\u003e` does not mean the input value is\n_\"automatically validated to a particular format before the\nform can be submitted, because formats for telephone numbers vary so much around\nthe world\"_ [_cf._\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/tel#:~:text=the%20input%20value%20is%20not%20automatically%20validated%20to%20a%20particular%20format%20before%20the%20form%20can%20be%20submitted%2C%20because%20formats%20for%20telephone%20numbers%20vary%20so%20much%20around%20the%20world.)]):\n\n```html\n\u003clabel for=\"phone\"\u003eEnter your phone number:\u003c/label\u003e\n\u003cinput type=\"tel\" id=\"phone\" name=\"phone\" /\u003e\n```\n\n```js\nconst formatPhoneNumber = (value) =\u003e {\n  return new Intl.InputMask(\"phone-number\", {\n    locale: \"de-DE\",\n    countryCode: \"leadingPlus\",\n    areaCode: \"leadingZero\",\n    groupSize: 2,\n  }).format(value);\n};\n\ndocument.querySelector(\"#phone\").addEventListener(\"input\", (e) =\u003e {\n  e.target.value = formatPhoneNumber(e.target.value);\n});\n```\n\n### On the server\n\nFor a **server-side implementation**, this could look as follows:\n\n```bash\nSELECT phone FROM users_legacy;\n# Returns a mix of formats from a legacy dataset:\n# 00494012345678\\n+494012345678\\n04012345678\n```\n\n```js\nconst formatPhoneNumber = (value) =\u003e {\n  return new Intl.InputMask(\"phone-number\", {\n    locale: \"de-DE\",\n    countryCode: \"leadingPlus\",\n    areaCode: \"leadingZero\",\n    groupSize: 2,\n  }).format(value);\n};\n\n// Express.js YOLO example.\napp.get(\"/phones\", (req, res) =\u003e {\n  const rawPhones = getPhoneNumbersFromLegacyDB();\n  const formattedPhonesHTML = rawPhones\n    .map((rawPhone) =\u003e {\n      return formatPhoneNumber(rawPhone);\n    })\n    .join(\"\u003cbr\u003e\");\n  res.send(formattedPhonesHTML);\n});\n```\n\n## Alternatives\n\nJust leaving this to the user land is an obvious alternative. The ecosystem of\ninput masking libraries is alive, and great implementations exist. Pulling any\nof those in comes at a cost for each locale that's needed though, and the\nweight of the particular input masking library itself.\n\nAnother alternative would be to add new (and smarter) input types. A recent\nexample is the\n[`input[type=currency]`](https://discourse.wicg.io/t/proposal-input-type-currency/5398)\nproposal. The declarative burden for advanced formatting needs is not to be\nunderestimated, though (see the above `countryCode` and `areaCode` examples).\nThis also does not solve the issue on the server side.\n\n## Feedback\n\nFeedback on this early-stage idea is welcome. Please\n[open a new Issue](https://github.com/tomayac/js-input-masking/issues).\n\n## Acknowledgements\n\nI'm thankful for the contributions from:\n\n- [@charmander](https://github.com/charmander)\n- [@tomByrer](https://github.com/tomByrer)\n- [@hemanth](https://github.com/hemanth)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomayac%2Fjs-input-masking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomayac%2Fjs-input-masking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomayac%2Fjs-input-masking/lists"}