Included files

Hi, my keymap file is getting long. I am thinking of having separate files for my behaviors, macros, and mouse configurations. Is it just a matter of creating the files in the same config folder where the keymap is, then writing an include at the top of the keymap file?
3 Replies
TyperAI
TyperAI3w ago
Yep, you’ve got the right idea!
ZMK uses devicetree source overlays (.keymap is just one of them), and you can absolutely split things out into multiple files for easier organization. For example:
- behaviors.dtsi
- macros.dtsi
- mouse.dtsi
As long as those extra files are in your config/ folder in your ZMK config repo, you can bring them into your keymap like this at the top of your corne.keymap (or lily58.keymap):
#include "behaviors.dtsi"
#include "macros.dtsi"
#include "mouse.dtsi"
#include "behaviors.dtsi"
#include "macros.dtsi"
#include "mouse.dtsi"
A few notes:
- Order can matter! If your behaviors/macros are referenced inside your keymap, include them before you reference them.
- Stick with .dtsi as the extension for partial include files — that’s the convention.
- Make sure there are no duplicate node labels or compatible values being defined across files (you can only define a node once).
This is a common way to keep your keymap clean and modular.
If you’d like, I can walk you through a suggested folder structure or give a small working example. Want me to sketch that out?
John
JohnOP3w ago
yes please yes please yes please
TyperAI
TyperAI3w ago
Great! Here’s a simple way to structure your ZMK config/ repo so things stay neat and modular:
config/
├── corne.keymap # your main keymap
├── behaviors.dtsi # custom behaviors
├── macros.dtsi # macros
├── mouse.dtsi # mouse keys or sensors
└── ... other config files
config/
├── corne.keymap # your main keymap
├── behaviors.dtsi # custom behaviors
├── macros.dtsi # macros
├── mouse.dtsi # mouse keys or sensors
└── ... other config files
Example corne.keymap
// Pull in your other files first
#include "behaviors.dtsi"
#include "macros.dtsi"
#include "mouse.dtsi"

&keymap {
default_layer {
bindings = <
&macro_hello &myspecial &kp A
&mmv MOVE_LEFT &mmv MOVE_RIGHT &kp B
>;
};
};
// Pull in your other files first
#include "behaviors.dtsi"
#include "macros.dtsi"
#include "mouse.dtsi"

&keymap {
default_layer {
bindings = <
&macro_hello &myspecial &kp A
&mmv MOVE_LEFT &mmv MOVE_RIGHT &kp B
>;
};
};
behaviors.dtsi
/ {
behaviors {
myspecial: myspecial {
compatible = "zmk,behavior-momentary";
label = "MYSPCL";
#binding-cells = <1>;
bindings = <&kp C>;
};
};
};
/ {
behaviors {
myspecial: myspecial {
compatible = "zmk,behavior-momentary";
label = "MYSPCL";
#binding-cells = <1>;
bindings = <&kp C>;
};
};
};
macros.dtsi
/ {
macros {
macro_hello: macro_hello {
compatible = "zmk,behavior-macro";
label = "HELLO";
#binding-cells = <0>;
bindings = <&kp H &kp E &kp L &kp L &kp O>;
};
};
};
/ {
macros {
macro_hello: macro_hello {
compatible = "zmk,behavior-macro";
label = "HELLO";
#binding-cells = <0>;
bindings = <&kp H &kp E &kp L &kp L &kp O>;
};
};
};
mouse.dtsi
/ {
behaviors {
mmv: mmv {
compatible = "zmk,behavior-mouse-move";
label = "MOUSE_MOVE";
#binding-cells = <2>;
};
};
};
/ {
behaviors {
mmv: mmv {
compatible = "zmk,behavior-mouse-move";
label = "MOUSE_MOVE";
#binding-cells = <2>;
};
};
};
--- ⚡ Tips: - Use .dtsi for includes (they’re like “partials”).
- File names don’t matter for ZMK, only the #include reference.
- Keep node labels unique across files (macro_hello, myspecial, etc.).
This way your corne.keymap stays focused on layout, while the other files hold definitions. Much easier to maintain in the long run.
Want me to also show you how this would look if you add layers across multiple files?

Did you find this page helpful?