JavaScript Plugins & Extensibility
Kalc can be extended with custom mathematical functions, specialized physical units, and formula templates written in JavaScript and bundled into .kalcplugin packages.
Extensions run inside Apple's native JavaScriptCore framework, isolated within a secure sandbox.
The .kalcplugin Bundle Structure
A .kalcplugin package is a directory (or compressed .zip archive) ending with .kalcplugin:
Finance.kalcplugin/
├── manifest.json # Plugin metadata, signatures, and templates
├── plugin.js # JavaScriptCore implementation using the kalc bridge
└── README.md # Documentation and usage instructions1. The manifest.json Schema
The manifest declares metadata, function signatures, and formula templates. Kalc parses this file to automatically populate autocomplete suggestions, documentation hover popovers, and the formula template browser:
{
"id": "com.kalc.finance",
"name": "Finance & Wealth Extensions",
"version": "1.0.0",
"author": "Kalc Team",
"description": "Retirement future value, compound interest, and loan calculators.",
"functions": [
{
"name": "futureValue",
"signature": "futureValue(principal, rate, monthly, years)",
"detail": "Calculates future investment value under monthly contributions.",
"parameters": [
{ "name": "principal", "description": "Initial starting balance" },
{ "name": "rate", "description": "Annual return percentage (e.g. 7% or 0.07)" },
{ "name": "monthly", "description": "Monthly recurring contribution" },
{ "name": "years", "description": "Investment horizon in years" }
],
"examples": [
"futureValue($10k, 7%, 500, 20)",
"futureValue($50k, 8.5%, $1200, 25)"
]
}
],
"templates": [
{
"id": "mortgage_amortization",
"title": "Mortgage Amortization",
"category": "Finance",
"description": "Calculates monthly mortgage payments and total interest.",
"template": "loan = $500,000\nrate = 4.25%\nyears = 30\npmt(loan, rate, years)\ntotal repayment on loan for years at rate\n"
}
]
}2. The kalc JavaScript Bridge API
Inside plugin.js, the global kalc object exposes methods to register functions, custom variables, and units:
kalc.addFunction(name, callback)
Registers a custom JavaScript function callable directly from expressions:
// plugin.js
kalc.addFunction("doubleValue", function(val) {
return val * 2;
});
kalc.addFunction("futureValue", function(principal, rate, monthly, years) {
// Normalizes percentage if passed as decimal or percent scalar
var r = (rate > 1) ? (rate / 100) : rate;
var monthlyRate = r / 12;
var months = years * 12;
// FV = P * (1 + r)^n + PMT * [((1 + r)^n - 1) / r]
var fvPrincipal = principal * Math.pow(1 + monthlyRate, months);
var fvAnnuity = monthly * ((Math.pow(1 + monthlyRate, months) - 1) / monthlyRate);
return fvPrincipal + fvAnnuity;
});kalc.setVariable(name, value)
Exports a global custom variable accessible across all document buffers:
kalc.setVariable("standardVat", { double: 0.077, unitId: "percent" });
kalc.setVariable("goldOunceUsd", { double: 2650.00, unitId: "USD" });kalc.addUnit(definition)
Registers a new physical or conceptual unit into UnitCatalog:
kalc.addUnit({
id: "parsec",
names: ["parsec", "pc"],
baseUnitId: "m",
ratio: 3.085677581491367e16
});kalc.registerPlugin(manifest)
Registers the complete manifest object programmatically at runtime.
3. Sandbox Security Model
To protect user privacy and system integrity, KalcPlugins enforces strict security boundaries:
- No Filesystem Access: Extensions cannot read, write, or enumerate files on disk.
- No Process Execution: Plugins cannot invoke shell binaries (
bash,zsh), spawn child processes, or run command-line tools. - No Outbound Networking: The
JSContextdoes not exposefetch,XMLHttpRequest, or raw TCP/UDP socket APIs. - Pure Functional Computation: Plugins operate as pure transform functions, accepting inputs from Kalc and returning numeric or string values.
4. Official Reference Plugins
Kalc ships with three official first-party reference plugins located in apps/macos/Extensions/:
1. Finance.kalcplugin
futureValue(principal, rate, monthly, years): Retirement and portfolio compounding.totalInvested(principal, monthly, years): Net capital contributions.interestEarned(principal, rate, monthly, years): Net investment gains.compound(principal, rate, years): Lump-sum compound growth.
2. AustraliaTax.kalcplugin
australiaTax(income): Evaluates Australian ATO progressive individual tax brackets, low-income tax offsets, and the 2% Medicare levy.australiaNetIncome(income): Net take-home salary after statutory withholding.
3. CanadaTax.kalcplugin
canadaTax(income): Evaluates Canadian federal tax brackets and Ontario provincial baseline rates.canadaNetIncome(income): Canadian net annual take-home salary.
5. Installing & Managing Plugins
- Open Preferences (
⌘ ,) and navigate to the Plugins tab. - Drag and drop any
.kalcpluginfolder or archive onto the window to install it. - Alternatively, click "Open Plugins Directory" to view installed bundles in:bash
~/Library/Application Support/Kalc/extensions/ - Use the toggle switches in preferences to enable or disable plugins dynamically without restarting the application.