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).
appis your app’sAppName. Only your own mod’s apps can be badged.countis rounded down to a whole number.0hides 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>