6.8 KiB
Community Modules
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.
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.
Adding a Community Module to your build
Community Modules have first-class support for External Userspace, and QMK strongly recommends using External Userspace for hosting keymaps and Community Modules together.
Modules must live in either of two locations:
<QMK_USERSPACE>/modules/<QMK_FIRMWARE>/modules/
A basic module is provided within QMK itself –
qmk/hello_world – which prints out a notification over HID console 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.
To add this module to your build, in your keymap’s directory create a
keymap.json with the following content:
{
"modules": [
"qmk/hello_world"
]
}If you already have a keymap.json, you’ll need to
manually merge the modules section into your keymap.
Community Modules are not supported by QMK Configurator. If you wish to use Community Modules, you must build your own firmware.
Adding a Community Module to your External Userspace
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:
cd /path/to/your/external/userspace
mkdir -p modules
# Replace the following {user} and {repo} with the author's community module repository
git submodule add https://github.com/{user}/{repo}.git modules/{user}
git submdule update --init --recursiveThis will ensure the copy of the module is made in your userspace.
Add a new entry into your keymap.json with the desired
modules, replacing {user} and {module_name} as
appropriate:
{
"modules": [
"qmk/hello_world",
"{user}/{module_name}"
]
}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.
Writing a QMK Community Module
As stated earlier, Community Module authors are strongly encouraged to provide their modules through git, allowing users to leverage submodules to import functionality.
qmk_module.json
A Community Module is denoted by a qmk_module.json file
such as the following:
{
"module_name": "Hello World",
"maintainer": "QMK Maintainers",
"features": {
"deferred_exec": true
},
"keycodes": [
{
"key": "COMMUNITY_MODULE_HELLO",
"aliases": ["CM_HELO"]
}
]
}At minimum, the module must provide the module_name and
maintainer fields.
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.
The keycodes array allows a module to provide new
keycodes (as well as corresponding aliases) to a keymap.
rules.mk /
post_rules.mk
These two files follows standard QMK build system logic, allowing for
Makefile-style customisation as if it were present in the
keyboard or keymap.
<module>.c
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.
Other files intended to be included must use the normal method of
SRC += my_file.c inside rules.mk.
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.
introspection.c /
introspection.h
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.
The header may provide definitions which are useful to the user’s
keymap.c.
The source file may provide functions which allow access to
information specified in the user’s keymap.c.
Introspection is a relatively advanced topic within QMK, and existing patterns should be followed. If you need help please open an issue or chat with us on Discord.
Compatible APIs
Community Modules may provide specializations for the following APIs:
| Base API | API Format | Example (hello_world module) |
API Version |
|---|---|---|---|
keyboard_pre_init |
keyboard_pre_init_<module> |
keyboard_pre_init_hello_world |
0.1.0 |
keyboard_post_init |
keyboard_post_init_<module> |
keyboard_post_init_hello_world |
0.1.0 |
pre_process_record |
pre_process_record_<module> |
pre_process_record_hello_world |
0.1.0 |
process_record |
process_record_<module> |
process_record_hello_world |
0.1.0 |
post_process_record |
post_process_record_<module> |
post_process_record_hello_world |
0.1.0 |
housekeeping_task |
housekeeping_task_<module> |
housekeeping_task_hello_world |
1.0.0 |
suspend_power_down |
suspend_power_down_<module> |
suspend_power_down_hello_world |
1.0.0 |
suspend_wakeup_init |
suspend_wakeup_init_<module> |
suspend_wakeup_init_hello_world |
1.0.0 |
shutdown |
shutdown_<module> |
shutdown_hello_world |
1.0.0 |
process_detected_host_os |
process_detected_host_os_<module> |
process_detected_host_os_hello_world |
1.0.0 |
An unspecified API is disregarded if a Community Module does not provide a specialization for it.
Each API has an equivalent _<module>_kb() and
_<module>_user() hook, as per the normal QMK _quantum,
_kb, and _user functions.