JSPM

@xlock/node

0.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q60188F
  • License MIT

x-lock bot protection — invisible middleware for Express, Fastify, Koa, Next.js, and Hono

Package Exports

  • @xlock/node
  • @xlock/node/express
  • @xlock/node/fastify
  • @xlock/node/hono
  • @xlock/node/koa
  • @xlock/node/next

Readme

@xlock/node

Invisible bot protection middleware for Node.js. Drop-in replacement for reCAPTCHA, Turnstile, and hCaptcha — no visual challenges, no user friction.

Supports Express, Fastify, Koa, Next.js, and Hono.

Install

npm install @xlock/node

Quick Start

Express

import { xlockMiddleware } from "@xlock/node/express";

app.use("/api/auth", xlockMiddleware({
  siteKey: "sk_...",
  flows: [
    {
      slug: "login",
      name: "Login",
      flowType: "auth",
      match: [{ method: "POST", pathPattern: "/api/auth/login" }],
    },
  ],
}));

Fastify

import { xlockPlugin } from "@xlock/node/fastify";

fastify.register(xlockPlugin, {
  siteKey: "sk_...",
  routes: ["/api/auth/*"],
});

Next.js

// middleware.ts
import { withXlock } from "@xlock/node/next";

export const middleware = withXlock({
  siteKey: process.env.NEXT_PUBLIC_XLOCK_SITE_KEY!,
  flows: [
    {
      slug: "checkout",
      match: [{ method: "POST", pathPattern: "/api/checkout" }],
    },
  ],
});

export const config = { matcher: ["/api/:path*"] };

Hono

import { xlockMiddleware } from "@xlock/node/hono";

app.use("/api/auth/*", xlockMiddleware({ siteKey: "sk_..." }));

Koa

import { xlockMiddleware } from "@xlock/node/koa";

router.post("/api/auth/login", xlockMiddleware({ siteKey: "sk_..." }), loginHandler);

Direct Verification

import { verify } from "@xlock/node";

const result = await verify("https://api.x-lock.dev", "sk_...", token, {
  method: "POST",
  path: "/api/login",
  flowHint: "login",
});
if (result.blocked) {
  console.log("Blocked:", result.reason);
}

Configuration

All middleware accepts these options:

Option Type Default Description
siteKey string XLOCK_SITE_KEY env Your x-lock site key
apiUrl string https://api.x-lock.dev x-lock API endpoint
failOpen boolean true Allow requests through on API errors
flows Flow[] [] SDK-canonical flow declarations used to attach flowHint

SDK-Canonical Flows

Declare flows in code, then register the module with the x-lock control plane:

import { defineFlowModule, registerFlowModule } from "@xlock/node";

await registerFlowModule({
  apiKey: process.env.XLOCK_API_KEY!,
  ...defineFlowModule({
    siteKey: process.env.XLOCK_SITE_KEY!,
    appName: "web",
    moduleVersion: "2026.04.14",
    flows: [
      {
        slug: "login",
        name: "Login",
        flowType: "auth",
        match: [{ method: "POST", pathPattern: "/api/login" }],
      },
      {
        slug: "checkout",
        name: "Checkout",
        flowType: "payment",
        match: [{ method: "POST", pathPattern: "/api/checkout" }],
      },
    ],
  }),
});

Notes:

  • Registration goes to the control plane at https://x-lock.cloud/api/sdk/flow-modules/register.
  • Use a service account API key with the flows:write scope.
  • Runtime enforcement still goes to https://api.x-lock.dev.
  • The dashboard renders registered modules read-only; flow structure stays canonical in code.

How It Works

  1. Your frontend loads the x-lock script (invisible to users)
  2. x-lock runs proof-of-work + behavioral analysis in the background
  3. The script attaches a token to requests via the x-lock header
  4. This middleware verifies the token server-side before your route handler runs

No CAPTCHAs. No clicking fire hydrants. No Google tracking.

Migrating from reCAPTCHA

- const { RecaptchaEnterpriseServiceClient } = require("@google-cloud/recaptcha-enterprise");
+ import { xlockMiddleware } from "@xlock/node/express";

- app.post("/login", async (req, res) => {
-   const score = await recaptcha.assessToken(req.body.token);
-   if (score < 0.5) return res.status(403).json({ error: "Bot detected" });
-   // handle login
- });
+ app.post("/login", xlockMiddleware({ siteKey: "sk_..." }), (req, res) => {
+   // handle login — x-lock already verified the request
+ });

License

MIT