golang/go · critical · Error

globalThis.performance is not available, polyfill required (

Error message

globalThis.performance is not available, polyfill required (performance.now only)

What it means

Thrown by wasm_exec.js when globalThis.performance is absent at load time. The Go wasm runtime uses performance.now() for its clock source (timers, runtime.nanotime). This is a startup self-check that fires before any Go code runs, so the failure is always at module evaluation, not later.

Source

Thrown at lib/wasm/wasm_exec.js:89

			cwd() { throw enosys(); },
			chdir() { throw enosys(); },
		}
	}

	if (!globalThis.path) {
		globalThis.path = {
			resolve(...pathSegments) {
				return pathSegments.join("/");
			}
		}
	}

	if (!globalThis.crypto) {
		throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
	}

	if (!globalThis.performance) {
		throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
	}

	if (!globalThis.TextEncoder) {
		throw new Error("globalThis.TextEncoder is not available, polyfill required");
	}

	if (!globalThis.TextDecoder) {
		throw new Error("globalThis.TextDecoder is not available, polyfill required");
	}

	const encoder = new TextEncoder("utf-8");
	const decoder = new TextDecoder("utf-8");

	globalThis.Go = class {
		constructor() {
			this.argv = ["js"];
			this.env = {};
			this.exit = (code) => {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use Node.js >= 8, where globalThis.performance is available.
  2. Polyfill before loading wasm_exec.js: const { performance } = require('node:perf_hooks'); globalThis.performance = performance;
  3. Minimal fallback: globalThis.performance = { now: () => Date.now() }; (lower resolution, acceptable for non-benchmarking use).
  4. If using a VM context, inject performance explicitly via the contextified sandbox object.

Example fix

// before
require('./wasm_exec.js'); // throws: globalThis.performance is not available

// after
const { performance } = require('node:perf_hooks');
globalThis.performance = performance;
require('./wasm_exec.js');
Defensive patterns

Strategy: validation

Validate before calling

if (typeof globalThis.performance === 'undefined' || typeof globalThis.performance.now !== 'function') {
  const { performance } = require('node:perf_hooks');
  globalThis.performance = performance;
}

Type guard

const hasPerformance = () => typeof globalThis.performance === 'object' && globalThis.performance !== null && typeof globalThis.performance.now === 'function';

Prevention

When it happens

Trigger: Loading wasm_exec.js in a JS engine with no High Resolution Time API: QuickJS without the perf module, very old Node (< 8), a `vm.createContext` that did not copy performance, or a minimal embedded runtime.

Common situations: Bundling Go wasm for a non-browser target and forgetting to polyfill timing; running tests in a sandboxed JS interpreter; migrating a Go-wasm worker from browser (which has performance) to a minimal Node script (older versions).

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/afaa0821f0536cfa. Report an issue: GitHub.