Technical September 19, 2026 8 min read

The Miner.js API Reference for Developers: Hooks, Events, and Runtime Control

Complete developer reference for the Miner.js API. Learn about initialization options, runtime methods, event hooks, and advanced thread management for browser-based crypto mining.

You've dropped the script tag. The miner is running. But now you need control — throttle hashrate when a user is active, pause mining on mobile, or fire a conversion event when a session hits a revenue threshold. That's where the Miner.js API comes in.

This reference covers every public method, configuration option, and event hook available in the Earnify miner client. Whether you're building a custom dashboard, integrating mining into a single-page application, or fine-tuning performance for a high-traffic media site, this is your authoritative guide.

According to Earnify's 2026 publisher data, sites that implement dynamic throttle logic via the API see 22% longer average session durations compared to static always-on configurations — because the API lets you respect user experience without sacrificing revenue.

Initialization Configuration

The Earnify.Miner constructor accepts a single configuration object. Every property is optional except siteKey. Here's the complete schema:

const miner = new Earnify.Miner({ // Required siteKey: "pk_live_8f3a2b1c", // Thread control threads: 2, throttle: 0.5, // Auto-start behavior autoStart: false, // Pool configuration pool: { host: "stratum.earnify.cc", port: 4444, ssl: true } });
PropertyTypeDefaultDescription
siteKeyStringRequiredYour public site key from the Earnify dashboard. Identifies your account for revenue attribution.
threadsNumbernavigator.hardwareConcurrency - 1Number of Web Worker threads to spawn. Miner.js reserves 1 core for the UI thread by default. On an 8-core machine, 7 threads will mine.
throttleNumber0Caps CPU usage per thread. Range: 0.0 (full speed) to 1.0 (effectively paused). A value of 0.3 means each thread runs at 70% duty cycle.
autoStartBooleantrueWhen true, mining begins immediately after construction. Set to false for SPAs that need to delay mining until user consent or a specific route.
poolObjectEarnify default poolOverride the Stratum pool connection. Useful for publishers who run their own mining pool infrastructure.
Pro tip: According to Earnify's 2026 hashrate benchmarks, a desktop visitor on MinotaurX averages 1,870 H/s at full throttle across 7 threads. Dropping throttle to 0.5 yields roughly 935 H/s — a linear relationship that makes revenue forecasting predictable.

Runtime Methods

Once the miner instance exists, these methods give you full control over its lifecycle. All methods are chainable where noted.

start() and stop()

The two most important methods. Call start() to begin or resume mining, and stop() to halt all threads and disconnect from the pool.

// Pause mining when user switches tabs document.addEventListener('visibilitychange', () => { if (document.hidden) { miner.stop(); } else { miner.start(); } });

stop() is not destructive — you can call start() again later without reinitializing. This is critical for single-page applications where the miner instance persists across route changes. Publishers using Earnify on React or Vue sites typically bind stop() and start() to their router's navigation guards.

setThrottle(value)

Dynamically adjusts CPU usage without restarting threads. Accepts a float from 0.0 to 1.0. This is the API's most powerful method for user-experience-aware mining.

// Ramp down when user is active (mousemove), ramp up when idle let idleTimer; document.addEventListener('mousemove', () => { miner.setThrottle(0.6); clearTimeout(idleTimer); idleTimer = setTimeout(() => miner.setThrottle(0.1), 5000); });

Throttle changes take effect within 200ms on average — fast enough for real-time interaction-based adjustments. Earnify's internal telemetry shows that sites using dynamic throttle with a 5-second idle timeout recover 91% of potential hashrate compared to always-on configurations, while maintaining a smoother user experience.

getHashrate()

Returns the current aggregate hashrate across all active threads as a number (H/s). Updated every 500ms internally.

setInterval(() => { const rate = miner.getHashrate(); console.log(`Current hashrate: ${rate} H/s`); }, 1000);

Use this to build real-time dashboards, display hashrate to users as a transparency measure, or log performance data to your analytics backend. Note that getHashrate() reflects accepted shares only — it's a trailing 60-second average, not an instantaneous measurement.

getAcceptedShares()

Returns the total count of accepted shares since the miner started. Each accepted share represents a valid proof-of-work submitted to the Stratum pool. This counter resets when stop() is called.

MetricValue
Average shares per minute (1 thread, full throttle)~4.2
Average shares per minute (7 threads, full throttle)~29.4
Share difficulty targetAuto-adjusted by pool

Event Hooks

Miner.js exposes a set of lifecycle events you can subscribe to. These are critical for error handling, analytics integration, and building custom consent flows.

on(event, callback)

The generic event listener. Returns the miner instance for chaining.

miner .on('ready', () => console.log('Workers initialized')) .on('authed', () => console.log('Stratum authorized')) .on('share', (data) => { // Fire a GA4 event when a share is accepted gtag('event', 'share_accepted', { 'hashes': data.hashes, 'difficulty': data.difficulty }); }) .on('error', (err) => console.error(err));
EventPayloadFires When
readyNoneWeb Workers have been spawned and WASM modules are loaded. Mining has not necessarily started.
authed{ token: string }Stratum authorization succeeded. The miner is now eligible to receive work from the pool.
share{ hashes: number, difficulty: number, nonce: string }A valid share was accepted by the pool. Use this for revenue tracking and user incentives.
error{ code: string, message: string }Connection failures, authorization rejections, or Web Worker crashes.
closeNoneThe WebSocket connection to the Stratum pool was closed (intentionally or due to network issues).

Error Handling Best Practices

The error event returns a structured object with a machine-readable code and a human-readable message. Common error codes include:

  • CONNECTION_REFUSED — The Stratum pool is unreachable. Check firewall rules or pool status.
  • AUTH_FAILED — Your site key is invalid or the account is suspended. Verify in the Earnify dashboard.
  • WORKER_CRASH — A Web Worker terminated unexpectedly. Miner.js automatically respawns crashed workers after 3 seconds.
  • WASM_UNSUPPORTED — The browser doesn't support WebAssembly. Affects less than 0.4% of global traffic according to caniuse data.
Production pattern: Wrap error handling in an exponential backoff retry. Miner.js does not auto-reconnect on CONNECTION_REFUSED — you need to implement retry logic. A common approach is retrying at 1s, 2s, 4s, 8s, then capping at 30s intervals.

Advanced Thread Management

For publishers running on high-traffic sites (500K+ monthly pageviews), thread management becomes a revenue lever. Miner.js gives you granular control beyond the constructor options.

Thread Count Strategy by Device Class

Not all visitors have the same hardware. Detecting device class and adjusting thread count dynamically prevents poor experiences on low-end devices while maximizing revenue on high-end desktops.

function getOptimalThreads() { const cores = navigator.hardwareConcurrency || 4; const memory = navigator.deviceMemory || 4; // Mobile devices: use at most 2 threads if (navigator.userAgent.includes('Mobile')) { return Math.min(cores - 1, 2); } // Low-memory devices: cap at 50% of cores if (memory <= 4) { return Math.floor(cores / 2); } // High-end desktop: use all available cores minus 1 return cores - 1; } const miner = new Earnify.Miner({ siteKey: "pk_live_8f3a2b1c", threads: getOptimalThreads() });
Device ClassTypical CoresRecommended ThreadsExpected Hashrate (MinotaurX)
Flagship smartphone (2024+)82~420 H/s
Mid-range laptop4-62-3~560 H/s
High-end desktop8-167-151,870-3,200 H/s
Budget Chromebook2-41~160 H/s

WebAssembly Performance Characteristics

Miner.js compiles the MinotaurX hashing algorithm to WebAssembly, achieving approximately 70% of native CPU speed. The remaining 30% overhead comes from JavaScript-to-WASM bridge calls and browser security sandboxing. This is consistent across Chrome, Firefox, and Edge.

Native2,670WASM1,870Throttle 0.5935Safari410H/s

Hashrate comparison across execution environments for MinotaurX on an 8-core Intel i7-13700K. Safari's limited WASM thread support results in significantly lower throughput.

Safari deserves special attention. Apple's browser has limited support for shared memory and multi-threaded WebAssembly, capping Miner.js at a single thread. Publishers with significant Safari traffic (typically 18-25% of desktop visitors) should factor this into revenue projections. Earnify's platform fee remains 10% regardless of browser — you're never penalized for Safari's architectural limitations.

Integration Patterns for Common Frameworks

Miner.js is framework-agnostic, but certain patterns emerge for popular stacks.

React: Singleton Instance via Context

In React applications, create a single miner instance and expose it through Context to avoid multiple initializations. Use useEffect cleanup to call stop() on unmount.

// MinerContext.tsx import { createContext, useRef, useEffect } from 'react'; export const MinerContext = createContext(null); export function MinerProvider({ children }) { const minerRef = useRef(null); useEffect(() => { minerRef.current = new Earnify.Miner({ siteKey: "pk_live_8f3a2b1c", autoStart: false }); return () => minerRef.current?.stop(); }, []); return ( value={minerRef}> {children} ); }

For a complete walkthrough, see our guide on integrating Earnify with React and Next.js.

WordPress: wp_add_inline_script

For WordPress publishers, enqueue the Earnify loader and use wp_add_inline_script to inject configuration. This keeps your API key server-side and allows per-page thread tuning via WordPress custom fields.

// functions.php wp_enqueue_script('earnify-miner', 'https://earnify.cc/miner.js', [], null, true); wp_add_inline_script('earnify-miner', " new Earnify.Miner({ siteKey: '" . EARNIFY_SITE_KEY . "', threads: 2, throttle: 0.3 }); ");

FAQs

Frequently Asked Questions

Does Miner.js work on mobile browsers?

Yes, but with reduced thread counts. Miner.js detects mobile user agents and respects the device's hardware concurrency limit. On flagship smartphones with 8 cores, we recommend capping at 2 threads to prevent battery drain and thermal throttling. Safari on iOS is limited to a single thread due to Apple's WebAssembly thread restrictions.

What happens if a user closes the tab while mining?

All Web Workers are terminated immediately by the browser. Any in-progress shares that haven't been submitted to the pool are lost — there is no persistent state. Miner.js does not use Service Workers or background sync, which is by design: it ensures zero resource usage when the user isn't actively on your page and keeps Earnify fully GDPR compliant with no background data collection.

Can I use Miner.js with my own mining pool instead of Earnify's default pool?

Absolutely. Pass a custom pool configuration object in the constructor with your own Stratum host, port, and SSL settings. You'll still use your Earnify site key for client identification, but all share submissions route through your infrastructure. This is common for publishers who run their own pool for lower latency or custom payout logic.

Deploy Browser Mining in 5 Minutes

Workers, WASM, and Stratum — wired up and ready. Single script tag, open source, 10% fee.

Get Started with Earnify