JavaScript / TypeScript SDK
import { Aside, Tabs, TabItem } from ‘@astrojs/starlight/components’;
Install
Section titled “Install”pnpm add gunsole-jsWorks in browsers and Node.js. Zero runtime dependencies.
Initialize
Section titled “Initialize”import { createGunsoleClient } from "gunsole-js";
const gun = createGunsoleClient({ projectId: "my-app", apiKey: "dev", mode: "local",});Config options
Section titled “Config options”| Option | Type | Default | Description |
|---|---|---|---|
projectId | string | required | Identifies your project in the desktop app |
apiKey | string | required | API key (use any string for local mode) |
mode | "local" | "desktop" | "cloud" | required | Determines the endpoint URL |
endpoint | string | — | Override the endpoint URL entirely |
env | string | — | Environment label (e.g. "production", "staging") |
appName | string | — | Application name, attached to every log |
appVersion | string | — | Application version, attached to every log |
defaultTags | Record<string, string> | — | Tags merged into every log entry |
batchSize | number | 10 | Number of logs to collect before auto-flushing |
flushInterval | number | 5000 | Auto-flush interval in milliseconds |
fetch | FetchFunction | globalThis.fetch | Custom fetch implementation |
isDebug | boolean | false | Disables gzip compression for debugging |
Modes and endpoints
Section titled “Modes and endpoints”| Mode | Endpoint |
|---|---|
local | http://localhost:17655 |
desktop | http://localhost:8787 |
cloud | https://api.gunsole.com |
Use local during development with the desktop app. The endpoint option overrides the mode-based URL if you need a custom address.
Logging
Section titled “Logging”Four methods, one for each level:
gun.info({ bucket: "api", message: "Request handled" });gun.debug({ bucket: "api", message: "Cache miss", context: { key: "user:123" } });gun.warn({ bucket: "api", message: "Slow query", context: { duration: 2500 } });gun.error({ bucket: "api", message: "Connection refused", tags: { db: "postgres" } });gun.log() is an alias for gun.info().
LogOptions
Section titled “LogOptions”| Field | Type | Required | Description |
|---|---|---|---|
message | string | yes | The log message |
bucket | string | yes | Category/namespace for this log |
context | Record<string, unknown> | no | Arbitrary structured data |
tags | Record<string, string> | no | Key-value pairs for filtering (string values only) |
traceId | string | no | Links related logs across operations |
What gets sent
Section titled “What gets sent”Each log entry is internally enriched before sending:
{ // from your call bucket: "api", message: "Request handled", level: "info", context: { ... }, tags: { ...defaultTags, ...yourTags }, // merged
// auto-populated timestamp: 1708214400000, // Date.now() userId: "u_123", // from setUser() sessionId: "sess_abc", // from setSessionId() env: "production", // from config appName: "my-app", // from config appVersion: "1.0.0", // from config}User and session tracking
Section titled “User and session tracking”gun.setUser({ id: "u_123", email: "ada@example.com", name: "Ada Lovelace", traits: { plan: "pro", team: "backend", },});
gun.setSessionId("sess_abc123");Once set, userId and sessionId are attached to every subsequent log. Useful for filtering logs by user in the desktop app.
Tags are flat key-value pairs (string → string) that become dynamic filters in the desktop app.
gun.info({ bucket: "api", message: "POST /users", tags: { route: "/users", method: "POST", status: "201", },});In the desktop app, you’ll see three new filter dropdowns appear: route, method, and status. Each shows the values that have been seen. No schema, no config — just send the tags and the filters show up.
Default tags
Section titled “Default tags”Tags from defaultTags in your config are merged with per-log tags. Per-log tags win on conflict.
const gun = createGunsoleClient({ projectId: "my-app", apiKey: "dev", mode: "local", defaultTags: { service: "api-server", region: "us-east-1", },});
// This log gets: { service: "api-server", region: "us-east-1", route: "/users" }gun.info({ bucket: "api", message: "Request", tags: { route: "/users" },});Batching and flushing
Section titled “Batching and flushing”Logs are buffered and sent in batches. A batch is flushed when:
- The batch reaches
batchSize(default: 10) - The
flushIntervaltimer fires (default: 5000ms) - You call
gun.flush()manually
// Force send everything nowawait gun.flush();The SDK compresses payloads with gzip by default. Set isDebug: true to send plain JSON (useful for inspecting network requests).
Error handling
Section titled “Error handling”The SDK is built to never crash your app. All internal errors are silently caught. In development (NODE_ENV === "development"), warnings are logged to the console.
Retry logic: failed HTTP requests are retried up to 3 times with exponential backoff (1s, 2s, 4s).
Global error handlers
Section titled “Global error handlers”Automatically catch unhandled errors and promise rejections:
gun.attachGlobalErrorHandlers();In the browser, this listens to window.addEventListener("error") and window.addEventListener("unhandledrejection").
In Node.js, this listens to process.on("uncaughtException") and process.on("unhandledRejection").
Captured errors are logged as error level in the global_errors bucket.
// Clean up when donegun.detachGlobalErrorHandlers();Cleanup
Section titled “Cleanup”When your app is shutting down (or a component unmounts):
gun.destroy();This flushes remaining logs, clears timers, and detaches global error handlers.
TypeScript
Section titled “TypeScript”The SDK is fully typed. Key types:
import type { GunsoleClientConfig, GunsoleClient, LogOptions, LogLevel, UserInfo, ClientMode,} from "gunsole-js";