community_modules.md (9254B)
1 # Community Modules 2 3 Community Modules are a feature within QMK which allows code to be implemented by third parties, making it available for other people to import into their own builds. 4 5 These modules can provide implementations which override or enhance normal QMK processing; initialization, key processing, suspend, and shutdown are some of the provided hooks which modules may implement. 6 7 ## Adding a Community Module to your build 8 9 Community Modules have first-class support for [External Userspace](/newbs_external_userspace), and QMK strongly recommends using External Userspace for hosting keymaps and Community Modules together. 10 11 Modules must live in either of two locations: 12 13 * `<QMK_USERSPACE>/modules/` 14 * `<QMK_FIRMWARE>/modules/` 15 16 A basic module is provided within QMK itself -- `qmk/hello_world` -- which prints out a notification over [HID console](/faq_debug) after 10 seconds, and adds a new keycode, `COMMUNITY_MODULE_HELLO` (aliased to `CM_HELO`) which types `Hello there.` to the active application when the corresponding key is pressed. 17 18 To add this module to your build, in your keymap's directory create a `keymap.json` with the following content: 19 20 ```json 21 { 22 "modules": [ 23 "qmk/hello_world" 24 ] 25 } 26 ``` 27 28 If you already have a `keymap.json`, you'll need to manually merge the `modules` section into your keymap. 29 30 ::: warning 31 Community Modules are not supported by QMK Configurator. If you wish to use Community Modules, you must build your own firmware. 32 ::: 33 34 ## Adding a Community Module to your External Userspace 35 36 Module authors are encouraged to provide a git repository on GitHub which may be imported into a user's external userspace. If a user wishes to import a module repository, they can do the following: 37 38 ```sh 39 cd /path/to/your/external/userspace 40 mkdir -p modules 41 # Replace the following {user} and {repo} with the author's community module repository 42 git submodule add https://github.com/{user}/{repo}.git modules/{user} 43 git submodule update --init --recursive 44 ``` 45 46 This will ensure the copy of the module is made in your userspace. 47 48 Add a new entry into your `keymap.json` with the desired modules, replacing `{user}` and `{module_name}` as appropriate: 49 50 ```json 51 { 52 "modules": [ 53 "qmk/hello_world", 54 "{user}/{module_name}" 55 ] 56 } 57 ``` 58 59 ::: info 60 The module listed in `keymap.json` is the relative path within the `modules/` directory. So long as the module is present _somewhere_ under `modules/`, then the `keymap.json` can refer to that path. 61 ::: 62 63 ## Writing a QMK Community Module 64 65 As stated earlier, Community Module authors are strongly encouraged to provide their modules through git, allowing users to leverage submodules to import functionality. 66 67 ### `qmk_module.json` 68 69 A Community Module is denoted by a `qmk_module.json` file such as the following: 70 71 ```json 72 { 73 "module_name": "Hello World", 74 "maintainer": "QMK Maintainers", 75 "license": "GPL-2.0-or-later", 76 "features": { 77 "deferred_exec": true 78 }, 79 "keycodes": [ 80 { 81 "key": "COMMUNITY_MODULE_HELLO", 82 "aliases": ["CM_HELO"] 83 } 84 ] 85 } 86 ``` 87 88 At minimum, the module must provide the `module_name` and `maintainer` fields. 89 90 The `license` field is encouraged to indicate the terms for using and sharing the module. It is recommended to use a [SPDX license identifier](https://spdx.org/licenses/) like "`Apache-2.0`" or "`GPL-2.0-or-later`" if possible. 91 92 The `url` field may specify a URL to more information about the module. 93 94 The use of `features` matches the definition normally provided within `keyboard.json` and `info.json`, allowing a module to signal to the build system that it has its own dependencies. In the example above, it enables the _deferred executor_ feature whenever the above module is used in a build. 95 96 The `keycodes` array allows a module to provide new keycodes (as well as corresponding aliases) to a keymap. 97 98 ### `rules.mk` / `post_rules.mk` 99 100 These two files follows standard QMK build system logic, allowing for `Makefile`-style customisation as if it were present in the keyboard or keymap. 101 102 ### `<module>.c` 103 104 This file will be automatically added to the build if the filename matches the directory name. For example, the `qmk/hello_world` module contains a `hello_world.c` file, which is automatically added to the build. 105 106 ::: info 107 Other files intended to be included must use the normal method of `SRC += my_file.c` inside `rules.mk`. 108 ::: 109 110 ::: tip 111 This file should use `ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(1,0,0);` to enforce a minimum version of the API that it requires, ensuring the Community Module is built with a compatible version of QMK. The list of APIs and corresponding version is given at the bottom of this document. Note the use of commas instead of periods. 112 ::: 113 114 ### `introspection.c` / `introspection.h` 115 116 These two files hook into the keymap introspection logic -- the header is prepended before the user keymap, and the C source file is appended after the user keymap. 117 118 The header may provide definitions which are useful to the user's `keymap.c`. 119 120 The source file may provide functions which allow access to information specified in the user's `keymap.c`. 121 122 ::: warning 123 Introspection is a relatively advanced topic within QMK, and existing patterns should be followed. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/qmk). 124 ::: 125 126 ### `led_matrix_module.inc` 127 128 This file defines LED matrix effects in the same form as used with `led_matrix_kb.inc` and `led_matrix_user.inc` (see [Custom LED Matrix Effects](led_matrix#custom-led-matrix-effects)). Effect mode names are prepended with `LED_MATRIX_COMMUNITY_MODULE_`. 129 130 ### `rgb_matrix_module.inc` 131 132 This file defines RGB matrix effects in the same form as used with `rgb_matrix_kb.inc` and `rgb_matrix_user.inc` (see [Custom RGB Matrix Effects](rgb_matrix#custom-rgb-matrix-effects)). Effect mode names are prepended with `RGB_MATRIX_COMMUNITY_MODULE_`. 133 134 ### Compatible APIs 135 136 Community Modules may provide specializations for the following APIs: 137 138 | Base API | API Format | Example (`hello_world` module) | API Version | 139 |----------------------------------|-------------------------------------------|---------------------------------------------|-------------| 140 | `keyboard_pre_init` | `keyboard_pre_init_<module>` | `keyboard_pre_init_hello_world` | `0.1.0` | 141 | `keyboard_post_init` | `keyboard_post_init_<module>` | `keyboard_post_init_hello_world` | `0.1.0` | 142 | `pre_process_record` | `pre_process_record_<module>` | `pre_process_record_hello_world` | `0.1.0` | 143 | `process_record` | `process_record_<module>` | `process_record_hello_world` | `0.1.0` | 144 | `post_process_record` | `post_process_record_<module>` | `post_process_record_hello_world` | `0.1.0` | 145 | `housekeeping_task` | `housekeeping_task_<module>` | `housekeeping_task_hello_world` | `1.0.0` | 146 | `suspend_power_down` | `suspend_power_down_<module>` | `suspend_power_down_hello_world` | `1.0.0` | 147 | `suspend_wakeup_init` | `suspend_wakeup_init_<module>` | `suspend_wakeup_init_hello_world` | `1.0.0` | 148 | `shutdown` | `shutdown_<module>` | `shutdown_hello_world` | `1.0.0` | 149 | `process_detected_host_os` | `process_detected_host_os_<module>` | `process_detected_host_os_hello_world` | `1.0.0` | 150 | `default_layer_state_set` | `default_layer_state_set_<module>` | `default_layer_state_set_hello_world` | `1.1.0` | 151 | `layer_state_set` | `layer_state_set_<module>` | `layer_state_set_hello_world` | `1.1.0` | 152 | `led_matrix_indicators` | `led_matrix_indicators_<module>` | `led_matrix_indicators_hello_world` | `1.1.0` | 153 | `led_matrix_indicators_advanced` | `led_matrix_indicators_advanced_<module>` | `led_matrix_indicators_advanced_hello_world` | `1.1.0` | 154 | `rgb_matrix_indicators` | `rgb_matrix_indicators_<module>` | `rgb_matrix_indicators_hello_world` | `1.1.0` | 155 | `rgb_matrix_indicators_advanced` | `rgb_matrix_indicators_advanced_<module>` | `rgb_matrix_indicators_advanced_hello_world` | `1.1.0` | 156 | `pointing_device_init` | `pointing_device_init_<module>` | `pointing_device_init_hello_world` | `1.1.0` | 157 | `pointing_device_task` | `pointing_device_task_<module>` | `pointing_device_task_hello_world` | `1.1.0` | 158 159 160 ::: info 161 An unspecified API is disregarded if a Community Module does not provide a specialization for it. 162 ::: 163 164 Each API has an equivalent `_<module>_kb()` and `_<module>_user()` hook, as per the normal QMK [`_quantum`, `_kb`, and `_user` functions](/custom_quantum_functions#a-word-on-core-vs-keyboards-vs-keymap).