Skip to content

@kigu/devtools-guard ​

⚠️ DARK PATTERN — EDUCATIONAL USE ONLY

This package intentionally prevents users from accessing standard browser functionality. Do not use it on public-facing websites.

A tiny, imperative utility that detects and blocks common entry points to browser developer tools.

What it does ​

  • Right-click context menu — Blocks the browser context menu.
  • Keyboard shortcuts — Intercepts F12, Ctrl+Shift+I/J/C, Cmd+Opt+I/J/U.
  • DevTools-open detection — Uses window-dimension heuristics and a debugger timing trap to detect when DevTools is opened.
  • Double-press action — Requires two shortcut presses within a time window before triggering a custom callback.

Why you should NOT use this in production ​

  1. Trivially bypassed. Disable JavaScript, use remote debugging, open DevTools via the browser menu before the page loads, or use an extension.
  2. Accessibility violation. Screen-reader users and power users rely on context menus and DevTools.
  3. Trust erosion. This pattern is overwhelmingly associated with scam sites, phishing pages, and crypto drainers. Using it signals you have something to hide.
  4. It is not security. It is obfuscation at best.

This package exists to teach you how it works so you can recognize and reverse-engineer it, not so you can copy-paste it into production.

Install ​

bash
npm install @kigu/devtools-guard

Usage ​

ts
import { guard } from "@kigu/devtools-guard";

const stop = guard({
  onContextMenuBlocked: () => {
    toast("Context menu has been disabled");
  },
  onDevToolsKeyPressed: (attempt) => {
    toast(`Press again to close (${attempt})`);
  },
  onDoublePressAction: () => {
    window.location.href = "about:blank";
  },
});

// Later — remove all listeners
stop();

React Usage ​

Although this package is framework-agnostic, you can use it inside a React component with useEffect:

tsx
import { useEffect } from "react";
import { guard } from "@kigu/devtools-guard";

function DevToolsGuard() {
  useEffect(() => {
    const stop = guard({
      onContextMenuBlocked: () => {
        console.log("Context menu has been disabled");
      },
      onDevToolsKeyPressed: (attempt) => {
        console.log(`Press again to close (${attempt})`);
      },
      onDoublePressAction: () => {
        window.location.href = "about:blank";
      },
    });

    return () => stop();
  }, []);

  return null;
}

⚠️ Remember

This is still a dark pattern even when wrapped in React. Use for educational purposes only.

API ​

`guard(options?) ​

OptionTypeDefaultDescription
onContextMenuBlocked() => void—Fired when right-click is blocked.
onDevToolsKeyPressed(attempt: number) => void—Fired when a DevTools shortcut is intercepted.
onDevToolsOpened() => void—Fired when DevTools open is detected via heuristics.
doublePressTimeoutnumber500Ms window for double-press detection.
onDoublePressAction() => void—Fired on double shortcut press.

Returns a cleanup function that removes all listeners and intervals.

License ​

MIT