Back to docs

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

bash
bizzoptima login

If you don't have an account yet, sign up from the developer hub or via CLI:

bash
# Install CLI globally
npm install -g bizzoptima-cli

# Log in (or create account at developers.bizzoptima.com)
bizzoptima login

2 — Initialize a module

bash
bizzoptima init my-module
cd my-module
npm install

The CLI generates the full structure with manifest v2, a working React component and TypeScript config:

bash
my-module/
├── src/
│   └── index.tsx        ← component + BizzOptimaModules declaration
├── manifest.json        ← metadata, permissions, security
├── package.json
├── tsconfig.json
└── .bizzmodignore

3 — The manifest.json

The v2 manifest declares required capabilities, inter-module access restrictions and marketplace metadata:

json
{
  "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:

tsx
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:

tsx
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

bash
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:

bash
bizzoptima sign
# → Uploads .bizzmod to the server
# → Receives signed bundle (signature.json injected)
# → Overwrites local file

8 — Publish

bash
bizzoptima publish
# → Uploads to Firebase Storage
# → Creates Firestore document in developer_modules
# → Submits for review by BizzOptima team

Once approved, your module appears in the marketplace for users on compatible plans.