Desktop

The Desktop API allows mods to add custom widgets to the game desktop. Widgets are rendered inside sandboxed iframes with full SDK access via window.HackhubSDK.

Import

import { Desktop } from "@hotbunny/hackhub-content-sdk";

Functions

Desktop.addWidget(widget: DesktopWidget)

Adds a custom widget to the desktop. The widget’s HTML file is loaded from the mod’s file system and rendered in a sandboxed iframe.

Desktop.addWidget({
    id: "clock-widget",
    src: "widgets/clock.html",
    width: 200,
    height: 100,
    position: { x: 50, y: 50 },
    transparent: true,
});

Desktop.removeWidget(id: string)

Removes a previously added widget by its ID.

Desktop.removeWidget("clock-widget");

Desktop.getWidgets(): DesktopWidget[]

Returns all mod-added desktop widgets.

const widgets = Desktop.getWidgets();
console.log(`${widgets.length} widgets on desktop`);

Desktop.isAppInstalled(app: string): boolean

Whether an app is installed on this save, by the name the desktop knows it (e.g. "Kisscord"). Most apps are unlocked as the player progresses, so ask before sending something to one.

Desktop.getInstalledApps(): string[]

Every app installed on this save, by name.

Desktop.setAppBadge(app: string, count: number)

Shows a count on one of your own apps: on its taskbar, dock or panel button and on its desktop shortcuts, on every OS. Use it for what waits for the player in the app (unread messages, jobs to collect).

  • app is your app’s AppName. Only your own mod’s apps can be badged.
  • count is rounded down to a whole number. 0 hides the badge; above 99 it reads “99+”.
  • The count stays until you set it again or the mod is turned off. It is not saved: set it again when your mod loads.
Desktop.setAppBadge("Inbox", unread.length);

From the app’s own HTML:

<script>
    HackhubSDK.Desktop.setAppBadge("Inbox", 0); // the player opened the app
</script>

DesktopWidget Interface

Property Type Required Description
id string Yes Unique identifier for the widget
src string Yes Path to HTML file relative to mod root
width number Yes Widget width in pixels
height number Yes Widget height in pixels
position { x: number; y: number } No Pixels from the desktop’s top-left corner. Unset: the widget joins the OS’s widget column (top right on RabbitOS) under the Objectives widget, no wider than the column
transparent boolean No Transparent background (default: true)

Widget HTML File

Widget HTML files are loaded from your mod’s directory. Inside the widget, you have access to the full SDK through window.HackhubSDK.

File Structure

my-mod/
├── manifest.json
├── index.ts
└── widgets/
    └── clock.html

Example: widgets/clock.html

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            margin: 0;
            font-family: monospace;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }
        #clock {
            font-size: 2rem;
            background: rgba(0, 0, 0, 0.5);
            padding: 1rem 2rem;
            border-radius: 8px;
            backdrop-filter: blur(10px);
        }
    </style>
</head>
<body>
    <div id="clock">--:--:--</div>
    <script>
        setInterval(() => {
            document.getElementById('clock').textContent =
                new Date().toLocaleTimeString();
        }, 1000);
    </script>
</body>
</html>

Accessing the SDK

Inside widget HTML files, the full HackhubSDK is available on window.HackhubSDK:

<script>
    const sdk = window.HackhubSDK;

    // Use any SDK API
    sdk.UI.toast("Widget loaded!");
    sdk.Events.on("Terminal.Ping", (data) => {
        document.getElementById("status").textContent = `Pinged: ${data.ip}`;
    });

    // Storage (scoped to your mod)
    const count = sdk.Storage.get("visitCount") || 0;
    sdk.Storage.set("visitCount", count + 1);
</script>

Example: System Monitor Widget

index.ts (mod entry):

import { Desktop } from "@hotbunny/hackhub-content-sdk";

Desktop.addWidget({
    id: "sys-monitor",
    src: "widgets/monitor.html",
    width: 220,
    height: 120,
    position: { x: 20, y: 400 },
    transparent: true,
});

widgets/monitor.html:

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            margin: 0;
            background: linear-gradient(135deg, rgba(0,0,0,0.7), rgba(20,20,40,0.7));
            color: #0f0;
            font-family: monospace;
            padding: 12px;
            font-size: 12px;
            border-radius: 6px;
        }
    </style>
</head>
<body>
    <div>CPU: <span id="cpu">0</span>%</div>
    <div>MEM: <span id="mem">0</span> MB</div>
    <div>Mod: <span id="mod"></span></div>
    <script>
        document.getElementById('mod').textContent = HackhubSDK.modId;

        setInterval(() => {
            document.getElementById('cpu').textContent = Math.floor(Math.random() * 100);
            document.getElementById('mem').textContent = Math.floor(Math.random() * 8000);
        }, 2000);
    </script>
</body>
</html>