General-purpose SDK for building browser extensions and Tampermonkey/Greasemonkey userscripts for fishtank.live.
npm install ftl-ext-sdkimport { site, chat, ui, socket } from 'ftl-ext-sdk';Implementation Bounty Open. Reward: ₣1,000 Site Tokens.
Support planned. The SDK currently uses ES module exports and needs a UMD/IIFE bundle with window.FTL for userscript environments.
import { site, chat, ui, socket, events } from 'ftl-ext-sdk';
import { io } from 'socket.io-client';
import * as msgpackParser from 'socket.io-msgpack-parser';
site.whenReady(async () => {
// Connect to the chat WebSocket (token: null = anonymous)
await socket.connect(io, msgpackParser, { token: null });
// Log all chat messages
chat.messages.onMessage((msg) => {
console.log(`[${msg.role || 'user'}] ${msg.username}: ${msg.message}`);
});
// React to modal events
events.onModalEvent((action, detail) => {
console.log(`Modal ${action}:`, detail?.modal);
});
ui.toasts.notify('Extension loaded!', { type: 'success' });
});Socket listeners start automatically when you register a callback — no manual setup step needed.
| Module | Description |
|---|---|
site |
Detect site version, ready state, and the logged-in user |
socket |
Socket.IO connection to the fishtank.live WebSocket server |
archives |
Season archive listings, signed watch URLs, and schedule helpers |
chat.messages |
Normalised chat, TTS, and SFX events from Socket.IO |
chat.rooms |
Subscribe to Season Pass and Season Pass XL rooms |
chat.input |
Helpers for the chat input field |
events |
Open, close, and observe site modals |
ui.modals |
Inject content into site modals |
ui.keyboard |
Register keyboard shortcuts that respect input focus |
ui.toasts |
Show your own toast notifications |
ui.toastObserver |
Watch the site's own toasts (admin messages, item drops) |
ui.download |
Trigger browser file downloads |
player |
Video element and stream/room name resolution |
dom |
Stable element selectors and DOM observation helpers |
storage |
Namespaced localStorage wrapper |
transport |
Cross-origin fetch layer (used by ui.download) |
react |
Walk the React fiber tree (advanced) |
debug |
Toggle SDK lifecycle logging |
See also:
- Firefox Compatibility — required reading if you target Firefox
- Raw Socket Data — quirks of the underlying socket events if you bypass
chat.messages
npm install
npm run build # Builds dist/ftl-ext-sdk.bundle.js
npm run watch # Rebuild on changessrc/
├── core/ — Low-level: React fiber, Socket.IO, DOM, events, storage, transport
├── archives/ — Season archive API: listings, signed watch URLs, schedule helpers
├── chat/ — Chat observation (DOM + Socket.IO), input helpers
├── player/ — Video player, stream/room name resolution
├── ui/ — Keyboard shortcuts, modals, toasts, toast observer, downloads
└── adapters/ — Site-version-specific configuration (current + classic stub)
- Non-destructive — Never modify the site's own connections, state, or event handlers
- Extension-store friendly — No monkey-patching, no remote code, no eval
- Fail silently — Missing elements return null, never throw in production paths
- Namespaced DOM — All injected elements use
data-ftl-sdkattributes - Performance-aware — No persistent body-level MutationObservers (the site generates thousands of chat mutations per second)
MIT