Node.js
The fanar npm package works in any Node.js or TypeScript project. It sends payloads over HTTP in a fire-and-forget fashion — errors are silently swallowed so it never crashes your app.
Installation
npm install @fanar-app/fanar Basic usage
Import and call fanar() with any value. The payload type is inferred automatically.
import fanar from '@fanar-app/fanar'
// Strings and primitives → log
fanar('request received')
fanar(42)
// Objects and arrays → collapsible JSON tree
fanar({ user, orders, session })
// Error instances → stack trace with clickable frames
fanar(new Error('something went wrong'))
fanar(new TypeError('unexpected null')) Labels and colors
Chain .label() and .color() to annotate a payload. Labels appear in the header row and are searchable.
fanar('user signed up').label('auth')
fanar({ cart }).label('checkout').color('#a78bfa') Both methods must be chained synchronously — do not await between the fanar() call and the chain, or the label will be missed.
SQL queries
Use fanar.query() to send SQL with bound values and execution time. The app shows syntax highlighting and marks slow queries.
fanar.query(sql, { bindings, duration })
// Example
const start = Date.now()
const rows = await db.query('SELECT * FROM users WHERE id = ?', [userId])
fanar.query('SELECT * FROM users WHERE id = ?', {
bindings: [userId],
duration: Date.now() - start,
}) Named timers
Measure any block of code with a named timer. Call .stop() to send the elapsed time.
const t = fanar.time('render')
await renderTemplate()
t.stop() // sends duration to the app
// Inline — chain start and stop
fanar.time('db-seed').stop() fanar.measure()
Send a pre-computed duration directly, without starting a timer.
fanar.measure('import', 142) // label, duration in ms fanar.clear()
Clear all stored payloads. Equivalent to pressing ⌘K in the app or calling DELETE /api/payloads.
await fanar.clear() Request grouping
Group all payloads from the same HTTP request under a shared requestId so they appear together in the app.
Use fanar.middleware() in Express or any Connect-compatible framework:
import express from 'express'
import fanar from '@fanar-app/fanar'
const app = express()
app.use(fanar.middleware()) For non-middleware contexts (cron jobs, scripts, queue workers), use fanar.run() to wrap a block of code in a new request scope:
fanar.run(() => {
fanar('step one')
fanar('step two')
// all payloads above share the same requestId
}) Configuration
By default Fanar connects to localhost:23517. Override host and port if needed.
import { configure } from '@fanar-app/fanar/config'
configure({ host: '192.168.1.5', port: 9913 }) | Option | Default | Description |
|---|---|---|
| host | localhost | Hostname or IP of the machine running Fanar |
| port | 23517 | Port the Fanar desktop app is listening on |