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() => voidFired when right-click is blocked.
onDevToolsKeyPressed(attempt: number) => voidFired when a DevTools shortcut is intercepted.
onDevToolsOpened() => voidFired when DevTools open is detected via heuristics.
doublePressTimeoutnumber500Ms window for double-press detection.
onDoublePressAction() => voidFired on double shortcut press.

Returns a cleanup function that removes all listeners and intervals.

License

MIT