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

eyeswitch

v1.0.12

Published

Head-tracking monitor focus switcher — look at a screen, it gets focus

Readme

eyeswitch

Look at a screen. It gets focus.

npm npm downloads license platform website

eyeswitch uses your webcam and TensorFlow.js to track where your head is pointing, then automatically moves macOS focus to whichever monitor you're looking at — no keyboard shortcut, no clicking, no magic.


Requirements

  • macOS (uses CoreGraphics + Accessibility APIs)
  • Node.js ≥ 18
  • Xcode Command Line Tools — xcode-select --install
  • A webcam

Installation

npm install -g eyeswitch

The native helper binary compiles automatically on install. If it fails:

npm run build:helper

Grant two permissions (one-time):

| Permission | Where | |---|---| | Camera | System Settings → Privacy & Security → Camera | | Accessibility | System Settings → Privacy & Security → Accessibility → enable your terminal app |


Quick start

eyeswitch doctor      # check everything is set up
eyeswitch calibrate   # look at each monitor when prompted
eyeswitch             # start tracking

Press p to pause/resume. Ctrl+C to stop.


Commands

eyeswitch — start tracking

Options:
  --sensitivity <level>    Preset: low | medium | high
  --no-click               Warp cursor only, no synthetic click
  --dry-run                Log gaze without switching focus
  --verbose                Print yaw/pitch values on every frame
  --camera <index>         Camera index (default: 0)
  --calibration-file <path>  Custom path to calibration JSON
  --calibrate              Force recalibration on startup

eyeswitch calibrate

Look at each screen and press Enter — eyeswitch samples your gaze for ~8 seconds per monitor and saves the result.

eyeswitch calibrate               # calibrate all monitors
eyeswitch calibrate --monitor 2   # recalibrate only monitor 2 (1-based)

eyeswitch doctor

Checks the native helper, camera, accessibility permission, calibration data, and TF.js model:

  ✓  Native helper binary
  ✓  Accessibility permission
  ✓  Camera access
  ✓  Calibration data          2 monitors calibrated
  ✓  TF.js model

eyeswitch config get [key]

Print the current config (or a single value).

eyeswitch config get
eyeswitch config get smoothingFactor

eyeswitch config set <key> <value>

Persist a config value to ~/.config/eyeswitch/config.json.

eyeswitch config set smoothingFactor 0.4
eyeswitch config set switchCooldownMs 300

eyeswitch status

Show whether eyeswitch is calibrated and which monitor is currently focused.

eyeswitch reset

Delete saved calibration data.

eyeswitch calibration export

Export calibration data to stdout or a file.

eyeswitch calibration export > ~/cal-backup.json
eyeswitch calibration export -o ~/cal-backup.json

eyeswitch calibration import <file>

Import calibration from a JSON file.

eyeswitch calibration import ~/cal-backup.json

Configuration

All values live in ~/.config/eyeswitch/config.json. Edit with eyeswitch config set or directly.

| Key | Default | Description | |---|---|---| | smoothingFactor | 0.3 | EMA smoothing — 0 = raw, closer to 1 = very smooth | | switchCooldownMs | 500 | Minimum ms between focus switches | | hysteresisFactor | 0.25 | Bias toward staying on the current monitor (0–1) | | minFaceConfidence | 0.4 | Minimum detection confidence to process a frame | | cameraIndex | 0 | Which webcam to use | | targetFps | 30 | Frame capture rate | | verticalSwitching | false | Enable pitch-based switching for top/bottom monitor layouts |

Sensitivity presets

| Preset | smoothingFactor | hysteresisFactor | switchCooldownMs | |---|---|---|---| | low | 0.5 | 0.40 | 800 ms | | medium | 0.3 | 0.25 | 500 ms (default) | | high | 0.1 | 0.10 | 200 ms |

eyeswitch --sensitivity high   # snappier switching
eyeswitch --sensitivity low    # more stable, fewer accidental switches

Troubleshooting

| Problem | Fix | |---|---| | Focus doesn't switch | Check Accessibility permission — eyeswitch doctor | | Camera not found | Try --camera 1 if you have multiple webcams | | Switching feels jittery | Use --sensitivity low or eyeswitch config set switchCooldownMs 800 | | Slow to detect face | Lower minFaceConfidenceeyeswitch config set minFaceConfidence 0.3 | | npm run build:helper fails | Run xcode-select --install first | | "Native helper not available" | Run npm run build:helper manually | | Wrong monitor gets focus | Recalibrate — eyeswitch calibrate |


How it works

  1. Your webcam captures frames via node-webcam
  2. TensorFlow.js + MediaPipe FaceMesh extracts 468 3D facial landmarks per frame
  3. Yaw and pitch are computed from jaw-outline and nose-tip landmarks (works with glasses)
  4. An EMA filter smooths the pose to cut down on jitter
  5. A calibration map translates gaze angles to the nearest monitor using Euclidean distance with hysteresis
  6. The native ObjC helper (eyeswitch-helper) uses CoreGraphics to warp the cursor and the Accessibility API to fire a synthetic click

Platform support

| Platform | Status | |---|---| | macOS | Full support | | Linux | Not supported (native helper is macOS-only) | | Windows | Not supported |


Development

git clone https://github.com/Abhijitam01/eyeswitch.git
cd eyeswitch
npm install
npm run build
npm test

To iterate on the native ObjC helper:

npm run build:helper

Project structure

src/
  index.ts                  CLI entry point (Commander.js)
  cli.ts                    Output helpers (chalk, ora)
  config.ts                 Config schema, load/save, sensitivity presets
  types.ts                  Shared TypeScript interfaces
  camera/
    frame-capture.ts        Webcam → FrameBuffer
  face/
    face-detector.ts        TF.js MediaPipe FaceMesh wrapper
    pose-estimator.ts       Landmarks → yaw/pitch with EMA smoothing
  calibration/
    calibration-manager.ts  Sample collection, persistence, gaze→monitor mapping
    sample-aggregator.ts    Immutable median aggregator for calibration samples
  monitor/
    focus-switcher.ts       Calls native helper to switch focus
    monitor-detector.ts     Queries monitor layout via native helper
    monitor-mapper.ts       Maps gaze to MonitorLayout using calibration data
  native/
    native-bridge.ts        Cross-platform TypeScript wrapper for the native helper
    helper/
      eyeswitch-helper.m    macOS native helper (CoreGraphics, Accessibility)
      eyeswitch-helper-win.c  Windows native helper (Win32 user32/gdi32)