Building a Module
A module is packaged automation you can install, share, and sell. It's just a folder of files. Only two are required; the rest are optional and add UI, docs, or structure. Bundling one for yourself is free and needs no account.
The two required files
Every module needs exactly these two:
ksl.json — the manifest
Metadata and permissions. The minimum:
{
"name": "app-watcher",
"version": "1.0.0",
"description": "Relaunches an app if it ever closes.",
"author": "your-name",
"entry": "main.ksl",
"capabilities": ["process", "notify"]
}
Common optional fields: license, keywords, homepage, min_keybind (minimum app version), ui (an App UI file, see below), and ui_window: true (open that UI in its own window instead of the Modules tab).
> capabilities must list every permission your code uses, and nothing more. Over-broad requests are the most common reason a module is sent back in review.
main.ksl — the entry script
The code that runs, named by the manifest's entry field:
#! requires: process, notify
on_load {
on_interval(5000, fn() {
if !process_exists("notepad.exe") {
run("notepad.exe")
notify("Relaunched Notepad")
}
})
}Optional files
Add any of these as your module grows:
- More `.ksl` files — split helpers into their own scripts (e.g.
utils.ksl, or alib/folder) and pull them in withimport. - **
*.test.ksl(or atests/folder)** — headless tests that run underkslc test. - **
settings.html+*.js— an App UI**: a small settings/config page shown in the Modules tab (or its own window withui_window: true). Point the manifest'suifield at the HTML file. - `README.md` — long-form description; auto-populates your marketplace listing.
- `CHANGELOG.md` — version history.
- `LICENSE.md` (or
.txt) — your license text. - `assets/` — an
icon.pngand screenshots for the listing.
A fuller module might look like:
app-watcher/
├── ksl.json # manifest (required)
├── main.ksl # entry script (required)
├── lib/helpers.ksl # extra KSL, imported by main
├── main.test.ksl # headless tests
├── settings.html # App UI (referenced by ksl.json "ui")
├── README.md # listing description
├── CHANGELOG.md # version history
├── LICENSE.md # license
└── assets/icon.png # listing icon
Bundle and test
Validate and run the headless tests before you share it:
keybind ksl validate ./app-watcher
kslc test ./app-watcher
Then bundle the folder into a single .kbm file from the app (Settings → Create a Module…), or install it directly for your own use. Publishing to the marketplace is a separate, one-time author step — see the Native Scene UI guide for building richer in-module UI, or AI Agents & MCP if you want a connected agent like Claude to call specific functions in your module.