@zerogpu/browser-extension-sdk
v0.1.7
Published
ZeroGPU device-side SLM runtime SDK for browsers and Chrome (MV3) extensions
Readme
ZeroGPU Browser SDK
Device-side JavaScript SDK that downloads a small language model (SLM), registers the device with the ZeroGPU orchestrator, opens a WebSocket for tasks, and executes on-device summarization.
Building a Chrome extension?
Chrome Manifest V3 forbids remotely-hosted code, so the <script>/loader path
below can't be used. Instead, install the package and vendor the runtime into your
extension:
npm install @zerogpu/browser-extension-sdk
npx zerogpu init # vendors the runtime + scaffolds the offscreen glueSee the full Chrome Extension developer guide (install, validate, and keep the SDK up to date).
Installation
npm installBuild
npm run buildThe build produces:
- ESM (
dist/zerogpu-browser-sdk.esm.js) and CJS (dist/zerogpu-browser-sdk.cjs) bundles for npm consumers. - A UMD bundle (
dist/zerogpu-browser-sdk.umd.js) plus an immutable, content-hashed copy underdist/v/for CDN distribution. dist/loader.js— the stable bootstrap apps embed (see UMD via<script>).dist/manifest.json— points the loader at the current hashed core bundle and records the build version.
Tests
npm run testLint
npm run lintUsage
ESM
import { initZeroGpuSdk } from '@zerogpu/browser-extension-sdk';
await initZeroGpuSdk({
// Optional Telegram user ID or custom app user ID
appUserId: 'telegram-user-1234',
// Sent as header: x-edge-operator-key
edgeOperatorKey: 'your-edge-operator-key',
// Override default settings
overrides: {
orchestrator: {
// Each deployment bakes in its own orchestrator at build time
// (develop/staging/production). Override only for internal testing.
baseUrl: 'https://devices.zerogpu.ai'
},
telemetry: {
// Enable/disable detailed console logs
enableConsoleLogs: true,
// Request geolocation permission (default: false)
locationData: true,
// Request camera permission (default: false) - *Not yet implemented*
cameraData: false
}
}
});UMD via <script> (always-latest loader)
Embed the loader URL — dist/loader.js — and you never have to think about
SDK versions again. The loader resolves and injects the latest published core
bundle at runtime, so an integrated app stays up to date with zero effort:
no version pinning, no ?v= cache-buster to bump.
<script
async
src="https://js-sdk.zerogpu.ai/dist/loader.js"
edgeOperatorKey="your-edge-operator-key"
enableConsoleLogs="true"
></script>The SDK auto-initializes when edgeOperatorKey is present
(the loader forwards every attribute to the core bundle).
For manual initialization, embed the loader without keys and call
ZeroGpuSdk.initZeroGpuSdk(...). The loader installs a small queueing stub, so
calls made before the core bundle finishes loading are replayed automatically:
<script async src="https://js-sdk.zerogpu.ai/dist/loader.js"></script>
<script>
ZeroGpuSdk.initZeroGpuSdk({
edgeOperatorKey: 'your-edge-operator-key'
});
</script>How it works: loader.js and manifest.json are served fresh (short TTL +
stale-while-revalidate); the manifest points at an immutable, content-hashed
core bundle (dist/v/zerogpu-browser-sdk.<hash>.umd.js) cached for a year. A new
release simply repoints the manifest at a new hash — and rollback is the same
operation in reverse. If the manifest is ever unreachable, the loader falls back
to the stable dist/zerogpu-browser-sdk.umd.js bundle.
Loading the core bundle directly (
dist/zerogpu-browser-sdk.umd.js) still works but pins the app to whatever build is live at load time — prefer the loader so updates are automatic.
Configuration Options
InitOptions
| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| appUserId | string | undefined | Optional user identifier (e.g. Telegram ID) for telemetry. |
| edgeOperatorKey | string | undefined | Operator key forwarded to /register as x-edge-operator-key. The orchestrator resolves the project from this key. |
| overrides | Partial<SdkConfig> | {} | Deep merge overrides for internal config. |
SdkConfig Overrides
You can override any part of the configuration. Common overrides:
orchestrator.baseUrl: URL of the ZeroGPU orchestration API.slm.modelRepoId: Hugging Face repo id used by Transformers.js (default:Xenova/t5-small).slm.modelUrl: Base URL that hosts the model assets (e.g., your CDN).slm.sampleSummaryText: Text used for the on-device self-test before registration.telemetry.locationData: Iftrue, SDK attempts to gather GPS coordinates (triggers permission prompt).telemetry.enableConsoleLogs: Force console logging on/off (defaultfalse).
Local Testing
Dashboard + Demo (Vite)
The Vite app under sdk/dashboard-app serves both:
/— ZeroGPU Edge SDK Demo/dashboard— ZeroGPU Fleet dashboard (analytics)
It also proxies API calls so the browser avoids CORS:
/api/*->API_UPSTREAM(defaulthttp://localhost:4000)/analytics/*->ANALYTICS_UPSTREAM(defaulthttp://localhost:5000)
cd sdk
npm run dashboard:devBuild/preview:
cd sdk
npm run dashboard:build
npm run dashboard:previewEnv config:
- Copy
sdk/dashboard-app/.env.exampletosdk/dashboard-app/.env.localand edit values. - By default it uses
/api+/analyticsso Vite can proxy and avoid browser CORS. - The demo page (
/) can also read optional defaults fromVITE_ZGPU_SDK_KEYandVITE_ZGPU_PROJECT_ID(recommended via.env.local, not committed).
Testing against a non-production orchestrator
Each deployment bakes in its own orchestrator at build time — develop, staging, or
production (https://devices.zerogpu.ai) — via the ZGPU_ORCHESTRATOR_BASE_URL build
env var set by the GitHub deploy workflows. For internal testing against a develop or
local orchestration API, override orchestrator.baseUrl directly:
import { initZeroGpuSdk } from '@zerogpu/browser-extension-sdk';
await initZeroGpuSdk({
edgeOperatorKey: 'your-edge-operator-key',
overrides: {
orchestrator: {
// e.g. https://dev.devices.zerogpu.ai or http://localhost:6000
baseUrl: 'http://localhost:6000'
},
telemetry: {
enableConsoleLogs: true // Enable detailed logging
}
}
});SDK Demo Page
Use the built-in demo page served by Vite at http://localhost:8000/ (it loads the SDK from /dist/zerogpu-browser-sdk.esm.js).
Self-Hosting the Model
If you want to serve the SLM artifacts from your own CDN (e.g., Cloudflare R2), download the Hugging Face assets and preserve the folder structure:
t5-small/
├── config.json
├── generation_config.json
├── tokenizer.json
├── tokenizer_config.json
├── special_tokens_map.json
├── spiece.model
└── onnx/
├── encoder_model_quantized.onnx
└── decoder_model_merged_quantized.onnxDownload commands
mkdir -p t5-small/onnx
cd t5-small
BASE_META="https://huggingface.co/Xenova/t5-small/resolve/main"
BASE_ONNX="https://huggingface.co/Xenova/t5-small/resolve/main/onnx"
curl -L -o config.json "$BASE_META/config.json"
curl -L -o generation_config.json "$BASE_META/generation_config.json"
curl -L -o tokenizer.json "$BASE_META/tokenizer.json"
curl -L -o tokenizer_config.json "$BASE_META/tokenizer_config.json"
curl -L -o special_tokens_map.json "$BASE_META/special_tokens_map.json"
curl -L -o spiece.model "$BASE_META/spiece.model"
curl -L -o onnx/encoder_model_quantized.onnx "$BASE_ONNX/encoder_model_quantized.onnx"
curl -L -o onnx/decoder_model_merged_quantized.onnx "$BASE_ONNX/decoder_model_merged_quantized.onnx"Upload the t5-small/ directory to your CDN unchanged and ensure responses include permissive CORS headers (Access-Control-Allow-Origin: *). Then override the SDK config:
await initZeroGpuSdk({
edgeOperatorKey: 'your-edge-operator-key',
overrides: {
slm: {
modelUrl: 'https://cdn.example.com/models/t5-small'
}
}
});slm.modelRepoId remains Xenova/t5-small so Transformers.js can reference the original repo, while the SDK rewrites every network request to your CDN.
Flow
initZeroGpuSdkresolves configuration (env defaults + overrides).- Device fingerprint + metadata are collected.
- Required SLM artifacts are downloaded to IndexedDB and loaded into Transformers.js. Timing metrics are recorded.
- The SDK calls the orchestrator
/registerendpoint with device + model metadata. A shell-friendly cURL string is logged. - The orchestrator responds with a
wsUrl. The SDK opens a WebSocket, sends ahello, and listens forsummary_requestmessages. - Each
summary_requestexecutes against the on-device SLM (single flight enforced) and responds withsummary_responsecontaining the summarized text and rich metadata (timings, device info, model info). - If the WebSocket closes or errors, the SDK marks the state as
error. Reloading the host app re-initializes the SDK.
