npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

signalk-lift-header

v0.1.0

Published

Signal K plugin that detects wind lifts and headers while beating and notifies you when to consider tacking.

Readme

signalk-lift-header

A Signal K server plugin that detects wind lifts and headers while you are beating to windward, and notifies you when a sustained header suggests it may be time to tack.

What it does

While close-hauled, the plugin watches true wind direction against a rolling baseline and works out, for your current tack, whether the wind is lifting you (letting you point higher) or heading you (knocking you down). When a shift is large enough and holds long enough, it raises a Signal K notification.

The detection is tack-aware: the same wind veer is a lift on one tack and a header on the other, and the plugin accounts for that automatically.

How it works

  1. Tack is derived from the true wind angle (TWD − heading): wind from starboard ⇒ starboard tack.
  2. A baseline wind direction is kept as a rolling circular average over a configurable window (vector-averaged, so it is correct across the 359°→1° wrap). The baseline deliberately excludes the most recent sustained duration of samples — it represents the wind before the shift being evaluated — so a genuine persistent header stays detectable instead of being silently absorbed as "the new normal."
  3. The shift is the current wind direction relative to that baseline (veer = positive, back = negative).
  4. Lift/header = shift × sign(TWA). Positive is a lift, negative is a header.
  5. It only runs when you are actually beating (true wind angle inside a configurable cone) and moving (above a minimum speed), and it resets the baseline on a tack change so the swing across the tack is not reported as a shift.

Requirements

  • Signal K server (Node.js 20+)
  • The boat must publish true wind direction on environment.wind.directionTrue and heading on navigation.headingTrue (these are the defaults; both source paths are configurable).

Apparent-wind-only boats: if your instruments only provide apparent wind, install a plugin such as signalk-derived-data to compute environment.wind.directionTrue first. Deriving true wind from apparent is intentionally out of scope here.

Installation

From the Signal K App Store, search for Lift / Header Detector (once published).

For development, link it into your server:

npm install
npm run build
npm link
cd ~/.signalk
npm link signalk-lift-header

Then enable and configure it under Server → Plugin Config.

Configuration

| Option | Default | Meaning | | --- | --- | --- | | True wind direction path | environment.wind.directionTrue | Source path for true wind direction | | Heading path | navigation.headingTrue | Source path for heading | | Boat speed path | navigation.speedThroughWater | Source path for speed gating | | Baseline window (seconds) | 120 | Rolling period for the wind baseline | | Shift threshold (degrees) | 10 | Magnitude that counts as a lift/header | | Sustained duration (seconds) | 30 | How long a shift must hold before notifying | | Beating cone (degrees) | 60 | Only active when |TWA| is within this | | Minimum boat speed (knots) | 1 | Detector idles below this speed | | Notify on sustained headers | true | Fire a notification on headers | | Notify on sustained lifts | true | Fire a notification on lifts | | Notification methods | visual, sound | Signal K notification methods |

Dashboard

The plugin ships a self-contained webapp served by the Signal K server at http://{server}:3000/signalk-lift-header (it also appears in the server's Webapps menu as Lift / Header).

It shows a tack-aware lift/header gauge — needle to the right (green) for a lift, to the left (red) for a header — with the current magnitude, tack, signed wind shift (veer/back), live true wind direction, and the rolling baseline. A banner appears on a sustained header ("consider tacking"). There is a Night mode (red-on-black, to protect night vision) and the page auto-reconnects to the server.

The webapp has no external dependencies (no CDN), so it works fully offline at sea. It subscribes to the plugin's own Signal K paths over the streaming API.

Emitted Signal K paths

| Path | Units | Description | | --- | --- | --- | | navigation.sailing.tack | "port" / "starboard" | Current tack | | environment.wind.directionTrue.reference | rad | Rolling baseline wind direction | | navigation.sailing.windShift | rad | Signed shift vs baseline (+ veer) | | navigation.sailing.liftHeader | rad | Signed lift/header (+ lift, − header) | | notifications.navigation.sailing.windShift | — | Notification on sustained lift/header |

All angles are emitted in radians, per the Signal K convention.

Development

npm install
npm run build   # compile src -> plugin/
npm test        # compile and run the detector unit tests

The detection math lives in src/detector.ts as pure functions and a small stateful class, kept separate from the server glue in src/index.ts so the sign conventions can be unit-tested without a running server.

License

Apache-2.0