form-honeypot-guard weekly downloads statistics
By MrLouisWright (2 listings) · npm · Webpack plugins
Block form spam bots without a captcha: honeypot + signed timing tokens + JS proof + optional Altcha-style proof-of-work + rate limiting. Webpack 5 and Vite plugins, a <2 kB client, Express/Fastify/Next/SvelteKit/Remix/Astro helpers, and a React wrapper.
form-honeypot-guard has 164 recorded weekly downloads on npm.
About form-honeypot-guard
form-honeypot-guard
Block form spam bots without a captcha. It layers cheap checks that most bots fail and real people never notice:
- an off-screen, accessible honeypot field with a randomised, realistic name
- an HMAC-signed timestamp token, so submissions can't come too fast, too late, tampered with or replayed
- a JS proof field that only a real browser fills in (configurable for progressive enhancement)
- light interaction signals: keypress, pointer and focus counts
- optional content heuristics (link spam, URLs in name fields, spam keywords, unexpected scripts)
- sliding-window rate limiting per IP (and optionally per email or fingerprint), with a correct
429andRetry-After - optional proof-of-work (Altcha-style, privacy-friendly — no captcha vendor) for stronger bot resistance
The webpack plugin is the main way in. It adds the honeypot markup to your built HTML at build time, injects the tiny client runtime, randomises field names on every build and writes a manifest so client and server use the same names. There's also a Vite plugin, plus server helpers for Express/Connect, Fastify, Next.js, SvelteKit, Remix, Astro and any Web Fetch runtime (Netlify, Vercel, Cloudflare, Deno, Bun), plus an optional React wrapper. Zero runtime dependencies, Node ≥ 18, dual ESM + CommonJS (import / require), TypeScript types in dist/*.d.ts (generated in CI via npm run build). Tests live under test/ and run in GitHub Actions CI.
Install
npm i form-honeypot-guard
npx form-honeypot-guard secret # generate FORM_GUARD_SECRET
Quick start: webpack (recommended)
Mark the forms you want to protect with data-guard (or use forms: 'all'):
<form data-guard method="post" action="/contact">
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<button>Send</button>
</form>
// webpack.config.js (CommonJS works: the plugin ships a CJS build)
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { FormGuardPlugin } = require('form-honeypot-guard/webpack');
module.exports = {
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new FormGuardPlugin({
forms: 'form[data-guard]', // or 'all'
secretEnv: 'FORM_GUARD_SECRET', // the server reads the secret from this env var
minTime: 3000,
manifestPath: 'server/form-guard.manifest.json',
}),
],
};
// ESM config
import { FormGuardPlugin } from 'form-honeypot-guard/webpack';
What happens on each build:
- Every emitted HTML file is scanned, whether it came from html-webpack-plugin or is a plain
.htmlasset (copy-webpack-plugin, custom loaders). Matching forms get the honeypot markup, an empty token field anddata-fg-guardedin the HTML, so the trap is there before any JavaScript loads. - The client runtime (about 1.3 kB gzipped) is emitted as
form-guard.[contenthash:8].jsand added as a<script defer>. When html-webpack-plugin is installed it goes through HWP's own tag pipeline (alterAssetTagGroups). HWP isn't required. Passinline: trueto inline the runtime instead. - Field names are randomised per build (
middle_name_28e1,fg_t_5b57f4, …) and written toform-guard.manifest.json(plusmanifestPathif you set it). The manifest holds names and timings only, never the secret. - The virtual module
form-guard/configexposes the same manifest to your bundle:import { fields } from 'form-guard/config'. - Warnings appear in
compilation.warningsfor guarded forms that don't usemethod="post", have noaction, or already contain a field with the honeypot's name.
It hooks compilation.hooks.processAssets at PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE + 1, so it runs right after html-webpack-plugin. Names are generated once per plugin instance, which keeps watch-mode rebuilds and the persistent cache stable. Pass seed for reproducible names across builds. In development mode it logs what it guarded through webpack's infrastructure logger.
Then the server:
import express from 'express';
import { expressGuard, cleanFields } from 'form-honeypot-guard';
const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(expressGuard({ manifest: 'server/form-guard.manifest.json', paths: ['/contact'] }));
app.post('/contact', (req, res) => {
sendEmail(cleanFields(req.body, { manifest: 'server/form-guard.manifest.json' }));
res.redirect('/thanks');
});
app.use(express.static('dist'));
expressGuard also serves GET /__form-guard/token. The runtime fetches a fresh signed token from it when the page loads.
Vite
// vite.config.js
import { formGuard } from 'form-honeypot-guard/vite';
export default { plugins: [formGuard({ forms: 'form[data-guard]' })] };
Uses transformIndexHtml to add the honeypot markup and the inlined runtime, serves form-guard/config as a virtual module and emits form-guard.manifest.json in the build.
Express / Connect…
Description from the npm listing.
- honeypot
- spam
- form
- anti-spam
- captcha
- captcha-alternative
- altcha
- proof-of-work
- bot
- bot-protection
- webpack
- webpack-plugin
- vite
- vite-plugin
- express
- fastify
- nextjs
- sveltekit
- remix
- astro
README badge
Show your rank in a README or on your website. The badge updates automatically.
Charts
Images: 30d · 1y · all time · 1600×900 dark
Adoption over time
7/30/90-day growth
Ranking history
Listing placement
Listing placement
Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.
Each band is one page of 20. Weekly downloads on a linear scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.
Recent observations
Full history (1)Similar npm Webpack plugins plugins
All 20 form-honeypot-guard alternativesData source
Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.
Listing: https://www.npmjs.com/package/form-honeypot-guard. First seen Oct 21, 2026; last successful collection Oct 23, 2026. See the methodology.