Skip to content

Releases: jolynstudios/freehop

0.1.0-alpha.6 — Your TURN relay stays the last resort

Choose a tag to compare

@nillo nillo released this 10 Oct 08:25

Your own TURN relay (turn, opt-in since alpha.5) now stays the last resort after it connects a call. A pair it carries keeps checking for a cheaper route, moves to a direct route or a gateway as soon as one works, and then releases the relay. Only the browser client changed: gates, Freehop's TURN server and the ticket format are as in alpha.5, and integrations that don't configure turn behave exactly as before.

What's new

  • Leaving the relay: while the application's TURN relay carries a pair, the side that restarts ICE (the impolite one, as for every restart) checks for a cheaper route with the relay still configured, so the call keeps its route when nothing better works. It checks after timing.turnUpgradeMs (60 s by default), then at doubling intervals up to maxRetryMs (5 minutes), and within seconds when a gateway the pair could use appears.
  • Release: once another route has held for two media checks, the relay leaves the pair's ICE servers on both sides and one more ICE restart ends its allocations. If that route fails later, the ladder runs again with TURN last.
  • timing.turnUpgradeMs: the first check, in milliseconds (default 60000). stats().counters reports turnProbes and turnReleases.
  • Tests: test/turn-upgrade.test.mjs, four new laddergate scenarios, and test/browser/turn-upgrade.mjs in npm run test:browsers (--browser= picks the engine).

Cost

Less relay traffic for the same calls: a pair moves off your relay as soon as a cheaper route works and gives its allocations back. A check costs one ICE restart with fresh TURN allocations, after a minute and then at most every 5 minutes. If the cheaper route breaks later, that pair has no media until the ladder reaches TURN again, about 7 to 20 seconds; keeping the relay on standby would avoid that gap but keep its allocations open.

Install this release

npm install freehop@alpha

Published on npm under the alpha tag; pin it with npm install freehop@0.1.0-alpha.6. The attached archive is the published package; its SHA-256 is in SHA256SUMS.

The wire format is unchanged, so alpha.5 and alpha.6 clients share calls. A pair moves off the relay when its impolite side runs alpha.6; the relay's allocations are released completely when both sides do.

Validation

  • Full npm run ship: 208 unit tests; export, type, documentation, contract and ladder gates; Chromium/Firefox/WebKit calls, multi-gate outage recovery, ticket rotation, the example app, the TURN rung, and leaving the relay again.
  • laddergate: the 19 scenarios stamped for alpha.5 are byte-identical. Four new ones cover a pair that stays on the relay, one that moves to a direct route and back to TURN when that route breaks, one that moves to a gateway appearing mid-call, and the polite side.
  • Two Chromium peers on one machine, first limited to relayed candidates: a check with nothing better kept the call on the relay with no gap in the audio. Once every candidate was allowed, both moved to a direct route by themselves, again with no audio gap; the relay forwarded 0 bytes afterwards and its allocations ended about 70 s later. A variant without the final restart left one allocation open.
  • Packed archive installed into an isolated consumer: browser Bundler/NodeNext and Node-only strict compilation, every entry point imported, a ticket round trip with turn, and gate and TURN startup/close.

Work in progress

Firefox through the application TURN relay. In the relay-only browser setup, Firefox gets no audio in one direction through the application relay (the TURN server drops it for a missing permission), also with alpha.5. Chromium connects through it, and Firefox through desktop gateways and host nodes passed the home-lab tests.

Not yet verified

Leaving the relay was tested with Chromium on one machine, not on real networks or in WebKit. Port prediction's success case is still unverified, as in alpha.5.

Website · Paths · Client options · Test results

0.1.0-alpha.5 — Opt-in last resorts before unreachable

Choose a tag to compare

@nillo nillo released this 09 Oct 19:44

Calls that would end unreachable can now try two opt-in last resorts first: your own TURN relay and port prediction. A new NAT check tells your app which kind of NAT each user is behind. All three are off by default, so integrations that don't opt in behave exactly as in alpha.4.

What's new

  • turn: your own TURN relay, tried last. A call it carries reports relay with via: 'turn'. Tickets can carry it: createAuthority({ turn }) takes the servers, or a function that mints short-lived credentials per ticket. session.refresh() and session.setTurn() rotate them. Gates and peers can never supply the application's TURN servers.
  • portPrediction (off by default): when a peer's NAT hands out ports in order, try its next ports once (at most 16 candidates per ICE generation) before reporting unreachable. Random NATs are never predicted.
  • classifyNat: learns from the browser's own STUN results whether this endpoint's NAT keeps one port (eim), hands them out in order (sequential) or picks them at random, shares that with peers and reports it as stats().nat.
  • Release gates: laddergate replays 19 path-ladder scenarios against traces recorded from the unmodified ladder; contractgate freezes the public API, wire constants, ticket format and the client markers downstream apps check. Both run in npm run ship and CI.
  • NAT lab in Docker: lab/docker.sh <scenario|qualify> runs the Linux NAT lab in a disposable container, including on macOS.
  • Example app: FREEHOP_TURN_URLS, FREEHOP_TURN_USERNAME and FREEHOP_TURN_CREDENTIAL turn on the TURN last resort.

Cost

Nothing changes unless you opt in. classifyNat and portPrediction need no server. A turn relay carries only calls that would otherwise fail: about 50 MB per hour of two-way audio, or about 330 MB per hour with video at Freehop's caps. Its bandwidth is yours; a provider's free tier, or Freehop's own TURN server on a machine you already run, can keep that at zero.

Install this release

npm install freehop@alpha

Published on npm under the alpha tag; pin it with npm install freehop@0.1.0-alpha.5. The attached archive is the published package; its SHA-256 is in SHA256SUMS.

Validation

  • Full npm run ship: 201 unit tests; export, type, documentation, contract and ladder gates; Chromium/Firefox/WebKit calls, multi-gate outage recovery, ticket rotation, the example app, and a two-Chromium call that can only connect through the app's TURN relay. CI passed on Node 22.
  • NAT lab (Docker, Chromium, one run each): all 12 existing scenarios took the same routes as before. Two strict NATs (over UDP) and two UDP-blocked peers (over TCP) connect as relay via turn. Random NATs are never predicted. Two newly documented limits, home router ↔ strict NAT and UDP-blocked ↔ home router, stay unreachable by default.
  • coturn's turnutils_uclient against Freehop's TURN server: UDP 800/800 and TCP 800/800, 0 lost.
  • Packed archive installed into an isolated consumer: browser Bundler/NodeNext and Node-only compilation with the new option types, runtime imports, a ticket round trip with turn, and gate and TURN startup/close.

Not yet verified

Port prediction's success case, a NAT that hands out ports in order, cannot be simulated with Linux NAT and has not been tested on real carrier networks, so portPrediction stays off by default.

Website · Paths · Client options · Test results

0.1.0-alpha.4 — Typed SDK and refreshed docs

Choose a tag to compare

@nillo nillo released this 07 Oct 17:22

Freehop now includes TypeScript declarations across all 15 public package entry points. Browser and Node consumers get typed options, tickets, sessions, event payloads, stats and backend APIs. The runtime remains JavaScript and existing runtime imports stay compatible.

The website and documentation have also been refreshed around small meeting rooms, calls inside apps, shared workspaces, desktop collaboration and community rooms. Hopper and the live call demo remain the working examples. The site now follows your system theme, offers manual light/dark selection, fixes the results/calculator contrast issues, and uses consistent sans-serif typography informed by Refero research.

Install this release

npm install freehop@alpha

Distribution: published on npm under the alpha tag. Pin this version with npm install freehop@0.1.0-alpha.4.

The original GitHub archive remains attached. The npm package updates its README and SDK installation instructions; runtime and declaration files are byte-identical.

Validation

  • Full npm run ship: 173 unit tests, export checks, strict type consumers, documentation checks, Chromium/Firefox/WebKit calls, multi-gate outage recovery, ticket rotation and the example app.
  • TypeScript 6 and 7 consumer checks; actual Electron 44.6.0 declarations accepted by the helper.
  • Packed archive installed into an isolated consumer; browser Bundler/NodeNext and Node-only compilation, runtime imports, ticket round trip, gate and TURN startup/close passed.
  • Root package audit: no reported vulnerabilities. Website audit gate passed with its existing reviewed, unpatched build-tool advisory allowance.
  • Production site build, light/dark responsive layouts, automated WCAG AA checks, system preference changes and saved manual overrides passed.

Website · TypeScript guide · Use cases

The previous site is retained in the archive/pre-rebrand-2026-10-07 tag.

Freehop 0.1.0-alpha.3

Freehop 0.1.0-alpha.3 Pre-release
Pre-release

Choose a tag to compare

@nillo nillo released this 06 Oct 12:06

What's new

  • Added session.setPeerMuted(peerId, muted) for local, per-member audio mute. It applies to audio tracks already playing and to tracks that arrive later, while leaving video unaffected.
  • Muting stays local to the listener: the sender is not notified. A temporary disconnect preserves the mute; a final departure clears it.
  • Updated the SDK documentation and examples for the new API.

Install

npm install freehop@alpha

The alpha npm tag points to 0.1.0-alpha.3; the default latest tag remains on 0.1.0-alpha.1.

Verification

  • The full ship pipeline passed: 173 unit tests, export and documentation checks, plus Chromium, Firefox, and WebKit browser suites.
  • The npm-published tarball was downloaded and checked: it contains setPeerMuted and matches the release candidate checksum.

Freehop remains alpha software. The home-lab network matrix is described in RESULTS.md; it has not been rerun for this revision.