Module SDK — Complete guide
Create, build, sign and publish your first BizzOptima module with the official CLI.
The BizzOptima Module SDK lets you build complete business extensions that integrate natively into the desktop app. Each module is a self-contained signed IIFE bundle distributed via the marketplace.
Prerequisites
- Node.js 20+
- A BizzOptima developer account
- Knowledge of React and TypeScript
1 — Create a developer account
bizzoptima loginIf you don't have an account yet, sign up from the developer hub or via CLI:
# Install CLI globally
npm install -g bizzoptima-cli
# Log in (or create account at developers.bizzoptima.com)
bizzoptima login2 — Initialize a module
bizzoptima init my-module
cd my-module
npm installThe CLI generates the full structure with manifest v2, a working React component and TypeScript config:
my-module/
├── src/
│ └── index.tsx ← component + BizzOptimaModules declaration
├── manifest.json ← metadata, permissions, security
├── package.json
├── tsconfig.json
└── .bizzmodignore3 — The manifest.json
The v2 manifest declares required capabilities, inter-module access restrictions and marketplace metadata:
{
"id": "my-module",
"name": "My Module",
"version": "1.0.0",
"author": "Your Name",
"license": "MIT",
"minAppVersion": "1.0.0",
"entryPoint": "dist/index.js",
"permissions": [
"db:read",
"db:write",
"events:subscribe",
"events:emit"
],
"sensitiveData": false,
"trustedCallers": []
}4 — Write the module
Each module receives a BizzOptimaModuleAPI instance scoped to its moduleId. Use the SDK React hooks:
import { ModuleRoot, useDB, useToast, usePermission } from '@bizzoptima/module-sdk';
function MyScreen() {
const { data: items, loading } = useDB('SELECT * FROM my_items');
const toast = useToast();
const canWrite = usePermission('db:write');
return (
<div>
{loading ? 'Loading…' : items.map(i => <div key={i.id}>{i.name}</div>)}
{canWrite && (
<button onClick={() => toast('Success', { type: 'success' })}>
Action
</button>
)}
</div>
);
}
// Global declaration (loaded by the desktop app)
window.BizzOptimaModules['my-module'] = {
manifest: { id: 'my-module', name: 'My Module', version: '1.0.0' },
init(api) {
// setup: DB migrations, event subscriptions, inter-module bridges
},
Screen() {
return <ModuleRoot api={window.__BIZZOPTIMA_API__}><MyScreen /></ModuleRoot>;
},
};5 — Inter-module security
For modules handling sensitive data (payments, health), restrict incoming calls with trustedCallers in the manifest and createSecureHandler in code:
import { createSecureHandler, createPaymentGuard } from '@bizzoptima/module-sdk';
// In init():
const guardPayment = createPaymentGuard(api, {
allowedCallers: ['quick_cashier', 'sales'],
});
api.interModule.expose(
'processPayment',
createSecureHandler(
async (params, caller) => {
guardPayment(caller); // throws if caller not authorized
// ... payment logic
},
{ moduleId: 'my-module', allowedCallers: ['quick_cashier', 'sales'] },
),
);6 — Build
bizzoptima build
# → Compiles TypeScript with tsc
# → Creates my-module-1.0.0.bizzmod (zip)7 — Cloud signing
Signing is performed by the BizzOptima server with the Ed25519 private key. Your developer account must be active:
bizzoptima sign
# → Uploads .bizzmod to the server
# → Receives signed bundle (signature.json injected)
# → Overwrites local file8 — Publish
bizzoptima publish
# → Uploads to Firebase Storage
# → Creates Firestore document in developer_modules
# → Submits for review by BizzOptima teamOnce approved, your module appears in the marketplace for users on compatible plans.