Plugins are shared libraries (.dll on Windows, .so on Linux/macOS) that extend KonsolScript with new module-style classes callable with the same MyPlugin:Method(args) syntax as built-in modules. No recompile of minks is needed.
The recommended way — load plugins directly in the script that uses them:
#include "kse_mysql" // finds kse_mysql.dll/.so in the plugin search path
#include "kse_audio"
See Var — Plugin includes for the full search-path order.
minks install <name> install plugin from current directory
minks remove <name> delete it from the user plugin dir
minks list list all installed plugins
minks install searches the current working directory for <name>.dll / .so / .dylib, then lib<name>.dll / .so / .dylib. Run it from inside the directory where you built the plugin.
Installed plugins live in ~/.minks/plugins/ (Linux/macOS) or %APPDATA%\minks\plugins\ (Windows) and are available to all scripts without any flags.
cd sample_plugin
minks install kse_sample
minks list
# kse_sample
minks --plugin-path ./my_libs script.ks
--plugin-path can be repeated. Added dirs are checked before the defaults.
minks --plugin ./myplugin.dll script.ks
minks --plugin lib1.dll --plugin lib2.dll script.ks
minks -p ./kse_mysql.so -p ./kse_audio.so game.ks
--plugin (or -p) can be repeated. Libraries are loaded in the order given before the script runs. Prefer #include "name" in scripts over this flag for portability.
PluginClass builderInclude minks_plugin.h (ships with minks). The PluginClass RAII fluent builder handles all token-stream parsing internally; you only write lambdas for each method.
#include "minks_plugin.h"
#include <iostream>
extern "C" void minks_register(Engine& e) {
PluginClass(e, "MyLib")
// .byRefMethod — last script arg is the outVar; SDK writes result there.
// args[] inside the lambda contains only the INPUT arguments.
.byRefMethod("Greet", [](auto args) -> Value {
return Value(std::string("Hello, ") + toString(args[0]) + "!");
})
// .voidMethod — side-effects only; no receiver variable needed
.voidMethod("Log", [](auto args) {
std::cout << toString(args[0]) << "\n";
})
.byRefMethod("Add", [](auto args) -> Value {
return Value(toDouble(args[0]) + toDouble(args[1]));
});
// PluginClass destructor fires here, registering "MyLib" with the engine.
}
From KonsolScript:
Var:String greeting;
MyLib:Greet("world", greeting);
Konsol:Print(greeting); // Hello, world!
MyLib:Log("debug info"); // void — no receiver needed
Var:Number sum;
MyLib:Add(3, 7, sum);
Konsol:Print(sum); // 10
| Builder call | Output convention | Description |
|---|---|---|
.byRefMethod("Name", fn) |
Last script arg is the outVar | fn receives input args; its return Value is written to the caller's pre-declared variable |
.voidMethod("Name", fn) |
None | fn returns nothing; no variable is written |
Plugins have no _ret path. Every non-void plugin method must use .byRefMethod.
Inside your lambda, args is std::vector<Value>. Use these free helpers (from kse_types.hpp):
| Helper | Type extracted |
|---|---|
toDouble(args[N]) |
Number (double) |
toString(args[N]) |
String |
toBool(args[N]) |
Boolean |
Return values: Value(double), Value(std::string), Value(bool).
# Windows
g++ -std=c++17 -shared -I<minks_dir> -o myplugin.dll myplugin.cpp
# Linux / macOS
g++ -std=c++17 -shared -fPIC -I<minks_dir> -o myplugin.so myplugin.cpp
Link additional libraries after myplugin.cpp:
g++ -std=c++17 -shared -fPIC -I../minks -o kse_mysql.so kse_mysql.cpp -lmariadb
<minks_dir> is the directory containing minks_plugin.h, kse.hpp, and kse_types.hpp.
sample_plugin/kse_sample.cpp exposes a Sample class with six byRefMethod entries and one voidMethod. Build, install, and use:
# from sample_plugin/
make
minks install kse_sample # searches cwd for kse_sample.dll/.so
# In your .ks script:
#include "kse_sample"
Or for a quick test without installing (explicit load by path):
minks --plugin sample_plugin\kse_sample.dll tests\20_plugin.ks # Windows
minks --plugin ./sample_plugin/kse_sample.so tests/20_plugin.ks # Linux
// 20_plugin.ks — Demo script for the sample plugin
//
// Install once, then run:
// minks install kse_sample (from inside sample_plugin/)
// minks tests/20_plugin.ks
//
// Or load explicitly without installing:
// minks --plugin sample_plugin\kse_sample.dll tests\20_plugin.ks (Windows)
// minks --plugin ./sample_plugin/kse_sample.so tests/20_plugin.ks (Linux)
#include "kse_sample"
Konsol:Print("=== Sample Plugin ===");
// Version check
Var:String version;
Sample:Version(version);
Konsol:Print("plugin version: ${version}");
// Hello (void — prints directly, no receiver needed)
Sample:Hello("world");
Sample:Hello("MINKS");
// Arithmetic
Var:Number result;
Sample:Add(3, 4, result);
Konsol:Print("Add(3, 4) = ${result}");
Sample:Multiply(6, 7, result);
Konsol:Print("Multiply(6, 7) = ${result}");
// Use result in expression
Sample:Add(10, 20, result);
Var:Number sum = result;
Sample:Multiply(sum, 2, result);
Konsol:Print("(10+20)*2 = ${result}");
// String ops
Var:String s;
Sample:Upper("hello from plugin", s);
Konsol:Print("Upper = ${s}");
Sample:Repeat("ab", 5, s);
Konsol:Print("Repeat(ab, 5) = ${s}");
// IsPrime
Konsol:Print("--- IsPrime ---");
Var:Number count = 0;
Var:Boolean isPrime;
for (Var:Number n = 2; n <= 30; n++) {
Sample:IsPrime(n, isPrime);
if (isPrime) {
Konsol:Print("${n} is prime");
count++;
}
}
Konsol:Print("primes found: ${count}");
// Combine with built-ins
Var:String upper;
Sample:Upper("minks plugin system", upper);
Var:Number len;
String:Len(upper, len);
Konsol:Print("length of uppercased string: ${len}");
#include "kse_sample"
Var:String v;
Sample:Version(v);
Konsol:Print(v);
Var:Number n;
Sample:Add(10, 20, n);
Konsol:Print(n);
Var:String u;
Sample:Upper("hello from include", u);
Konsol:Print(u);
Plugins can declare named exception classes that scripts catch by type — the same try / catch / finally syntax used for built-in exceptions.
A plugin registers its exception type once in minks_register:
registerPluginException(e, "MySQLException");
Then throws it from any method:
throwPluginException("MySQLException", mysql_error(conn), (double)mysql_errno(conn));
The caught instance exposes two fields (see Object — Exception):
| Field | Type | Description |
|---|---|---|
e.message |
String | Human-readable error description |
e.code |
Number | Numeric error code (0 if unused) |
catch (Exception e) is the generic catch-all. More specific types (MySQLException, CurlException, etc.) must be named exactly.
minks install auto-setup)Ship a kse_<name>.json file alongside your .dll / .so. When a user runs minks install <name>, minks reads the manifest and auto-runs the right package manager to install your native library dependency before copying your plugin to the user plugin directory.
{
"name": "myplugin",
"version": "1.0.0",
"description": "One-line description of what the plugin does",
"maintainer": "Your Name <you@example.com>",
"license": "MIT",
"library": "kse_myplugin",
"apt": "libmything-dev",
"dnf": "libmything-devel",
"brew": "mything",
"msys2": "$MINGW_PACKAGE_PREFIX-mything",
"windows": "Download from https://example.com/mything"
}
| Field | Required | Description |
|---|---|---|
name |
yes | Short plugin name (what users type in minks install <name>) |
version |
yes | Semantic version string |
description |
yes | One-line description |
maintainer |
yes | Author contact in "Name <email>" format |
license |
yes | SPDX license identifier (e.g. "MIT", "Apache-2.0") |
library |
yes | Base name of the plugin file without extension (e.g. "kse_myplugin") |
apt |
no | Debian/Ubuntu package name for apt install |
dnf |
no | Fedora/RHEL package name for dnf install |
brew |
no | Homebrew formula name for brew install |
msys2 |
no | MSYS2 package name for pacman -S; $MINGW_PACKAGE_PREFIX is resolved from the environment |
windows |
no | Hint string printed to the user on native Windows (download URL or instructions) |
Omit install fields (apt, dnf, brew, msys2, windows) for plugins that have no external library dependency. If no manifest is present, minks install copies the plugin file only, without running any package manager.
minks_plugin.hEditors using clangd may flag 'kse.hpp' file not found or 'minks_plugin.h' file not found inside sample_app/ or sample_plugin/ source files. This is a false positive — clangd does not read those directories' Makefile and therefore does not pick up the -I.. flag. The make build compiles correctly. Add a compile_commands.json or a .clangd config with CompileFlags: Add: [-I..] to suppress it.
| Plugin | Description |
|---|---|
| curl | HTTP client — GET, POST, PUT, DELETE |
| sqlite | SQLite database (no external dependency) |
| mysql | MySQL / MariaDB database |
| pg | PostgreSQL database |
| redis | Redis client — strings, hashes, lists, sets |
| zip | Zip archive read/write |
| crypto | AES-256, SHA-512, HMAC-SHA256, PBKDF2, CSPRNG |
| ws | WebSocket client (non-blocking) |
| jwt | JWT sign, verify, decode (HS256) |
| net | LAN TCP networking |