Skip to content

Fix macstats native addon load in GPU API route (Apple Silicon)#884

Open
wasawi wants to merge 1 commit into
ostris:mainfrom
wasawi:fix/macstats-getbuiltinmodule
Open

Fix macstats native addon load in GPU API route (Apple Silicon)#884
wasawi wants to merge 1 commit into
ostris:mainfrom
wasawi:fix/macstats-getbuiltinmodule

Conversation

@wasawi

@wasawi wasawi commented Jun 15, 2026

Copy link
Copy Markdown

Problem

On Apple Silicon, the GPU monitor in the UI always shows 0 for temperature, utilization, power, and fan speed.

The /api/gpu route loads the native macstats addon with:

import { createRequire } from 'module';
...
const nativeRequire = createRequire(import.meta.url);
const ms = nativeRequire('macstats');

When next build bundles the server route, it strips the createRequire import (the minified output becomes let a=(void 0)("macstats")) and rewrites import.meta.url to an internal bundle path. So the require throws (TypeError: (void 0) is not a function, or MODULE_NOT_FOUND), the catch swallows it with console.warn('macstats not available', ...), and every stat falls back to 0.

The addon itself is installed and working — require('macstats') succeeds outside the bundle.

Fix

Reach createRequire through process.getBuiltinModule('module') — a runtime call the bundler cannot strip (Node ≥ 22.3; the UI ships Node 23) — and resolve from process.cwd() (the ui/ folder, which is the server's working directory) so node_modules/macstats is found reliably:

const nativeRequire = process.getBuiltinModule('module').createRequire(process.cwd() + '/package.json');
const ms = nativeRequire('macstats');

Verification

On an M3 Max, /api/gpu before the fix returned temperature: 0, utilization.gpu: 0, power.draw: 0 plus a macstats not available warning on every request. After the fix it returns live values during a training run:

{"temperature":72,"utilization":{"gpu":100,"memory":79},"power":{"draw":20.49}}

with zero warnings.

🤖 Generated with Claude Code

The /api/gpu route loaded the native `macstats` addon via
`import { createRequire } from 'module'` + `createRequire(import.meta.url)`.
The Next.js server bundler strips that import (compiling `createRequire` to
`(void 0)`) and rewrites `import.meta.url` to an internal bundle path, so on
macOS the require always threw and the route silently returned 0 for GPU
temperature, utilization, power, and fan speed.

Use `process.getBuiltinModule('module')` (Node >=22.3) — a runtime call the
bundler can't touch — and resolve from `process.cwd()` (the ui/ folder) so
node_modules/macstats is found reliably. GPU stats now populate correctly on
Apple Silicon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants