{"id":12029,"library":"simple-keyboard","title":"Simple-Keyboard: JavaScript Virtual Keyboard","description":"Simple-Keyboard is a robust, lightweight, and highly customizable JavaScript virtual keyboard library designed for web applications. Currently at version 3.8.133, it maintains a stable release cadence with frequent updates addressing bugs and adding features. Key differentiators include broad browser compatibility (down to IE11 with specific bundles), built-in TypeScript support since v3.0.0, and a modular architecture allowing extensions for autocorrect, input masks, and key navigation. It is designed to be framework-agnostic, easily integrating into vanilla JavaScript, React, Angular, and Vue projects, providing an on-screen input solution suitable for touchscreens, kiosks, and general web input fields.","status":"active","version":"3.8.133","language":"javascript","source_language":"en","source_url":"https://github.com/hodgef/simple-keyboard","tags":["javascript","es6","digital","keyboard","onscreen","virtual","screen-keyboard","component","typescript"],"install":[{"cmd":"npm install simple-keyboard","lang":"bash","label":"npm"},{"cmd":"yarn add simple-keyboard","lang":"bash","label":"yarn"},{"cmd":"pnpm add simple-keyboard","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `SimpleKeyboard` class is exported as a default. Since v3.7.0, ESM output is available. For CommonJS, `require('simple-keyboard')` directly returns the class.","wrong":"import { SimpleKeyboard } from 'simple-keyboard';","symbol":"SimpleKeyboard","correct":"import SimpleKeyboard from 'simple-keyboard';"},{"note":"This is the TypeScript interface for configuring the keyboard options, useful for type-checking your configuration object.","symbol":"KeyboardOptions","correct":"import type { KeyboardOptions } from 'simple-keyboard';"},{"note":"Imports the basic default styling for the keyboard. For modern browsers, `index.modern.css` is also available. Custom themes typically override these styles.","symbol":"CSS Styles","correct":"import 'simple-keyboard/build/css/index.css';"}],"quickstart":{"code":"import SimpleKeyboard from 'simple-keyboard';\nimport 'simple-keyboard/build/css/index.css';\n\n// Create a target input element in your HTML: <input class=\"input\" value=\"\" />\n// And a container for the keyboard: <div class=\"simple-keyboard\"></div>\n\nconst inputElement = document.querySelector('.input') as HTMLInputElement;\n\nconst keyboard = new SimpleKeyboard({\n  onChange: (input: string) => onChange(input),\n  onKeyPress: (button: string) => onKeyPress(button),\n  input: inputElement || undefined, // Pass the input element or its selector\n  theme: 'hg-theme-default hg-layout-default',\n  layout: {\n    default: [\n      'q w e r t y u i o p',\n      'a s d f g h j k l',\n      '{shift} z x c v b n m {backspace}',\n      '{numbers} {space} {ent}'\n    ],\n    shift: [\n      'Q W E R T Y U I O P',\n      'A S D F G H J K L',\n      '{shift} Z X C V B N M {backspace}',\n      '{numbers} {space} {ent}'\n    ],\n    numbers: [\n      '1 2 3',\n      '4 5 6',\n      '7 8 9',\n      '{abc} 0 .'\n    ]\n  }\n});\n\nfunction onChange(input: string) {\n  if (inputElement) {\n    inputElement.value = input;\n  }\n  console.log('Input changed:', input);\n}\n\nfunction onKeyPress(button: string) {\n  console.log('Button pressed:', button);\n\n  if (button === '{shift}' || button === '{lock}') {\n    handleShift();\n  }\n  if (button === '{numbers}' || button === '{abc}') {\n    handleLayoutChange(button);\n  }\n}\n\nfunction handleShift() {\n  const currentLayout = keyboard.options.layoutName;\n  const newLayout = currentLayout === 'default' ? 'shift' : 'default';\n  keyboard.setOptions({ layoutName: newLayout });\n}\n\nfunction handleLayoutChange(button: string) {\n  const newLayout = button === '{numbers}' ? 'numbers' : 'default';\n  keyboard.setOptions({ layoutName: newLayout });\n}","lang":"typescript","description":"Initializes simple-keyboard with a custom layout, demonstrating how to handle input changes, key presses, and dynamically switch between 'default', 'shift', and 'numbers' layouts."},"warnings":[{"fix":"Review and adjust your CSS rules targeting `layoutCandidates` if their appearance changed unexpectedly after upgrading.","message":"As of `simple-keyboard` v3.5.0, the `display` option's styling rules were extended to also affect `layoutCandidates` box items. This could lead to unexpected visual changes if you previously relied on separate styling for these elements.","severity":"breaking","affected_versions":">=3.5.0"},{"fix":"If you need backspace functionality, ensure your layout uses the `{backspace}` button. For forward delete, `{delete}` is now standard.","message":"In `simple-keyboard` v3.1.0, the `{delete}` button's functionality was changed to perform forward deletion (deleting characters *after* the caret). If your application used a button named `{delete}` and expected it to behave like a backspace, its behavior will have changed.","severity":"breaking","affected_versions":">=3.1.0"},{"fix":"Update any custom modules to adhere to the new function-based structure, directly accepting the `keyboard` instance. Consult the official documentation for updated module creation guidelines.","message":"Version 3.0.0 of `simple-keyboard` introduced a simplified module architecture. Custom modules are now simple functions that receive the `keyboard` instance as a parameter, replacing previous module integration patterns. Existing custom modules will require refactoring.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"For modern applications, prefer `import SimpleKeyboard from 'simple-keyboard';`. For Node.js CommonJS environments, `const SimpleKeyboard = require('simple-keyboard');` should work. Ensure your build tooling (e.g., Webpack, Rollup) is configured for proper dual ESM/CJS package resolution.","message":"Prior to v3.7.0, `simple-keyboard` primarily provided CommonJS modules. From v3.7.0 onwards, an ESM output (`index.modern.esm.js`) is included. Mixing import styles (e.g., using `require` in an ESM context) or incorrect module resolution for versions `>=3.7.0` can lead to runtime errors.","severity":"gotcha","affected_versions":">=3.7.0"},{"fix":"Verify your TypeScript configuration, particularly `typeRoots` or `paths` settings, if you encounter type resolution errors after upgrading to v3.4.0 or later.","message":"In `simple-keyboard` v3.4.0, the TypeScript type definitions were relocated from `build/types` directly to the `build` directory. This internal change could potentially affect projects with highly customized `tsconfig.json` configurations or those relying on absolute paths to type declaration files.","severity":"gotcha","affected_versions":">=3.4.0"},{"fix":"For IE11 compatibility, explicitly target `simple-keyboard/build/index.js` in your `<script>` tag or bundler configuration, rather than `index.modern.js` or ESM builds.","message":"`simple-keyboard` supports IE11 but requires using the `index.js` bundle. The `index.modern.js` bundle (introduced in v3.3.0) and ESM outputs are optimized for modern browsers and will not function correctly in IE11.","severity":"gotcha","affected_versions":">=3.3.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using a default import: `import SimpleKeyboard from 'simple-keyboard';`. For CommonJS, `const SimpleKeyboard = require('simple-keyboard');` should correctly resolve the default export.","cause":"Attempting to instantiate `SimpleKeyboard` using incorrect import syntax (e.g., named import for a default export) or incorrect CommonJS `require` for ESM interop.","error":"TypeError: SimpleKeyboard is not a constructor"},{"fix":"Ensure `simple-keyboard` initialization code is executed only in a client-side (browser) environment. For SSR applications, use dynamic imports with a `typeof window !== 'undefined'` check or a dedicated SSR solution to defer client-side code.","cause":"`simple-keyboard` is a DOM-dependent library. This error occurs when attempting to initialize or interact with the keyboard in a non-browser environment, such as during Server-Side Rendering (SSR) without proper hydration or a mocked DOM.","error":"ReferenceError: document is not defined"},{"fix":"Add a type assertion to `HTMLInputElement` and ensure the element exists before passing it: `document.querySelector('.input') as HTMLInputElement;` then check if `inputElement` is not `null` before passing, or pass the CSS selector string directly to `input`.","cause":"In TypeScript, `document.querySelector` can return `null` or a generic `Element`, neither of which directly satisfies `simple-keyboard`'s `input` option (which expects `string | HTMLInputElement`).","error":"Argument of type 'HTMLElement | null' is not assignable to parameter of type 'string | HTMLInputElement'"}],"ecosystem":"npm"}