core23/antispam-bundle
A Symfony bundle for stopping form spam with honeypots, submission timers, banned scripts, markup and phrases, plus URL counting. Configure reusable anti-spam profiles and apply them to any form. Compatible with PHP 8.2+ and Symfony 6.4, 7.x and 8.x.
Architecture fit
The framing of "Laravel/PHP package" does not survive contact with the artifact. This is a Symfony bundle, not a Laravel package, and the distinction is not cosmetic:
Bundle subclass, a DependencyInjection extension, container tags, and auto-wiring conventions that Laravel's service container does not implement.symfony/form extensions and form event subscribers, symfony/options-resolver for profile config, symfony/http-foundation for request inspection, and symfony/translation for messages. Laravel has no Form component, no form events, and no equivalent extension registry.ServiceProvider, no publishable config file, no facade, no middleware registered into Laravel's HTTP kernel, and no Blade/Livewire/Inertia integration. Installing it via Composer into a Laravel app would either fail or produce dead code that never fires.The only thing that maps to our stack is the detection strategy catalog — honeypot fields, time-based submission traps, banned scripts (Cyrillic/Arabic), banned markup (HTML/BBCode), banned phrases, and URL-count heuristics — plus the profile-based configuration model that groups them per form. That is a design pattern, and a small one: a few hundred lines of heuristics and config. The leverage a TPM gets from this package is that it validates the pattern and gives us a documented, tested reference, not that it gives us an installable dependency.
Integration feasibility
Direct integration into our Laravel estate: not feasible without a rewrite, and a rewrite means we are no longer adopting the package. Viable paths, ranked:
throttle middleware and RateLimiter, custom FormRequest validation rules, a maintained honeypot package such as spatie/laravel-honeypot, and optionally Cloudflare Turnstile on high-risk public forms. This delivers the same outcome with first-class support for our stack.Explicitly rejected: running Symfony components standalone inside Laravel. The DI wiring and form integration assume a full Symfony kernel; the maintenance cost dwarfs the benefit.
Technical risk
nucleos/NucleosAntiSpamBundle, the package coordinate given is core23/antispam-bundle, and every README badge points to omines/antispam-bundle. That is a fork of a fork with the original vendor's README intact. Fork drift, unmerged upstream fixes, and unclear canonical ownership are all live.Key questions before any commitment
core23, nucleos, or omines? Is this fork intended for public consumption, and is the upstream actively maintained?Stack fit
Poor, and this should be stated plainly to stakeholders rather than hedged. Symfony-only coupling to form events and the HTTP kernel, against a Laravel estate built on service providers, a middleware pipeline, FormRequest validation, and Blade/Livewire/Inertia forms — there are no shared extension points. The fit that is good is conceptual: the profile-based configuration model and the separation of independent, testable mechanisms are directly transposable onto Laravel's middleware and validation primitives.
Migration path
There is no migration path in the usual sense, because there is nothing to migrate from. The realistic path is a port:
config/antispam.php.throttle, RateLimiter, spatie/laravel-honeypot), use it and do not port the equivalent heuristic.Compatibility
The README claims PHP 8.2+ and Symfony 6.4 LTS, 7.4 LTS, and 8.x. That matrix is irrelevant to our Laravel runtime except as a signal that the upstream is reasonably current. What matters is that the pattern is framework-agnostic and the code is not.
Sequencing
Maintenance
Low code churn, high ownership burden. If we depend on the package rather than the pattern, plan to pin the version, read the source, and budget for becoming the maintainer of a fork — zero dependents means no upstream pressure to fix what breaks us. If we port the pattern, we own a small, well-understood surface, which is the preferable position. Either way, the rule content (phrases, scripts, URL thresholds) needs an owner and a review cadence; uncurated lists are the most likely cause of silent failure.
Support
No vendor, no SLA, no support contract, no compliance attestations. Internal support load is dominated not by the library but by false-positive triage — users who were blocked and complained. That needs a triage path and a way to whitelist or replay a blocked submission, or the support queue becomes the real cost centre.
Scaling
The heuristics are cheap: string matching, timing checks, and counters. The scaling concern is state, not CPU. Time traps and rate limits need a shared cache or store (Redis) across instances, or they degrade unpredictably behind a load balancer. Banned-phrase and URL matching scale linearly with traffic and form size, which is fine at our volume. Multi-tenant or per-region deployments need per-environment config, which the profile model supports cleanly.
Failure modes
Ramp-up
Negligible for using the Symfony bundle (we cannot), moderate for porting the pattern (a competent Laravel engineer, days not weeks), and low for stakeholders to reason about because the mechanisms are well-known and the config is declarative. The real ramp-up is organisational: agreeing the friction budget, defining the false-positive threshold that triggers rollback, and assigning an owner for rule curation. Those decisions, not the code, determine whether this succeeds.
How can I help you explore Laravel packages today?