Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Verbs Laravel Package

hirethunk/verbs

Verbs is a Laravel-friendly event sourcing package for PHP artisans that keeps the benefits of event sourcing while cutting boilerplate and jargon. Model behavior as verbs, record events, and build projections with a clean, approachable API.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Event Sourcing Paradigm: Verbs aligns perfectly with Laravel’s ecosystem, offering a declarative event-sourcing approach that abstracts complexity while maintaining flexibility. Its "verb-first" philosophy (actions over nouns) complements Laravel’s Eloquent and Livewire integration, reducing boilerplate for domain-driven design (DDD) patterns.
  • State Management: The package’s state-first model (where states are derived from events) fits well with Laravel’s ORM, though it requires a mental shift from traditional CRUD. The snapshot store optimizes read performance, which is critical for high-traffic applications.
  • Laravel Synergy: Native support for Livewire, Queues, and Octane (via wormhole time manipulation) ensures seamless integration with Laravel’s reactivity and concurrency models. The verb() helper and macroable pending events reduce coupling with Laravel’s service container.

Integration Feasibility

  • Database Schema: Verbs introduces three core tables (verb_events, verb_snapshots, verb_states), which can coexist with existing Laravel migrations. The package provides artisan commands for schema generation, but manual adjustments may be needed for complex schemas (e.g., multi-tenant setups).
  • Event Handling: Supports Laravel’s event system (via Event::dispatch()) and custom listeners, but requires explicit configuration for cross-cutting concerns (e.g., logging, analytics). The fire() method’s replay safety is a standout feature for auditability.
  • Testing: Built-in event store testing utilities and time-wormhole support simplify time-sensitive tests, though legacy test suites may need refactoring to adopt the event-sourcing mindset.

Technical Risk

  • Learning Curve: Event sourcing introduces new abstractions (e.g., State, PendingEvent, Verb), which may require team upskilling. The documentation is strong, but complex domains (e.g., financial systems) will need custom validation logic.
  • Performance Overheads:
    • Write Path: Event appends and snapshot updates add latency (~10–30ms per event, depending on DB). Benchmark with your workload.
    • Read Path: Snapshots optimize reads, but event replay during state reconstruction can be costly for large event histories. Consider projection tables for read-heavy use cases.
  • Concurrency: The package handles optimistic locking via last_event_id, but distributed transactions (e.g., across microservices) require additional coordination (e.g., sagas).
  • Legacy Code: Migrating from traditional ORM to event sourcing requires strategic adoption. Start with bounded contexts (e.g., orders, payments) to isolate risk.

Key Questions

  1. Domain Suitability:
    • Is event sourcing justified for your use case? (e.g., audit trails, CQRS, temporal queries).
    • How will you handle event versioning if the schema evolves?
  2. Infrastructure:
    • What’s your database strategy for snapshots vs. events? (e.g., PostgreSQL JSONB vs. MySQL JSON).
    • How will you manage event storage growth? (e.g., pruning old events, partitioning).
  3. Team Readiness:
    • Do developers understand event-driven workflows? If not, budget for training.
    • How will you test event handlers in isolation vs. integration?
  4. Operational Impact:
    • How will you monitor event processing? (e.g., dead-letter queues, replay failures).
    • What’s your rollback strategy if events are corrupted?

Integration Approach

Stack Fit

  • Laravel Core: Verbs is Laravel-native, with first-class support for:
    • Eloquent Models: States can extend Illuminate\Database\Eloquent\Model.
    • Livewire: Real-time state updates via livewire:commit.
    • Queues: Async event processing with dispatch().
    • Octane: Low-latency event handling via wormhole time manipulation.
  • Dependencies:
    • PHP 8.1+: Required for union types, attributes, and enums.
    • Doctrine Collections: Used for state serialization (included via spatie/array-to-object).
    • Bits 0.3+: For ID generation (snowflake/UUID). Customize via id_type config.
  • Compatibility:
    • Laravel 11–13: Officially supported. Laravel 10 is deprecated.
    • Frameworks: Works with Symfony components but lacks native support for non-Laravel apps.

Migration Path

  1. Pilot Phase:
    • Start with a non-critical module (e.g., notifications, analytics).
    • Use dual-writes (ORM + Verbs) to compare behaviors.
  2. Schema Migration:
    • Run php artisan verbs:install to generate tables.
    • For existing apps, backfill events from audit logs or write a migration.
  3. Codebase Refactor:
    • Replace direct model updates with verb() calls.
    • Convert services to emit events instead of mutating state directly.
    • Example:
      // Before (ORM)
      $order->update(['status' => 'shipped']);
      
      // After (Verbs)
      verb()->ship($order->id);
      
  4. Testing Strategy:
    • Unit Tests: Mock PendingEvent and verify state transitions.
    • Integration Tests: Test event replays with Verbs::replay().
    • E2E Tests: Validate Livewire/Queue interactions.

Compatibility Considerations

  • Third-Party Packages:
    • Laravel Scout: Events can trigger reindexing, but requires custom listeners.
    • Cashier/Invoices: Use event listeners to sync with Verbs states.
    • Nova/Livewire: States can be exposed via custom resources.
  • Legacy Systems:
    • REST APIs: Use projection tables to serve traditional responses.
    • GraphQL: Leverage snapshots for efficient queries.
  • Caching:
    • Verbs uses LRU caching for states, but Redis should be configured for distributed setups.

Sequencing

  1. Phase 1: Foundation (2–4 weeks)
    • Set up Verbs in a new Laravel project or sandbox.
    • Implement 1–2 bounded contexts (e.g., user profiles, orders).
    • Document event schemas and state transitions.
  2. Phase 2: Integration (4–8 weeks)
    • Migrate critical workflows (e.g., payments, subscriptions).
    • Build projection tables for read models.
    • Integrate with Livewire/Queues/Octane.
  3. Phase 3: Optimization (Ongoing)
    • Tune snapshot intervals (e.g., every 10 events).
    • Implement event pruning for old data.
    • Add monitoring for failed events.

Operational Impact

Maintenance

  • Boilerplate Reduction:
    • Verbs eliminates repetitive CRUD code, but introduces event definition boilerplate (e.g., Verb, State classes).
    • Artisan commands (verbs:make:verb, verbs:make:state) streamline generation.
  • Dependency Updates:
    • Monitor Bits, Doctrine Collections, and Laravel compatibility.
    • Custom ID generators (e.g., snowflake) may need updates.
  • Debugging:
    • Event replay simplifies debugging, but stack traces may be less intuitive.
    • Use Verbs::debug() to inspect state transitions.

Support

  • Community:
    • GitHub Discussions and Slack are active, but commercial support is limited (MIT license).
    • Stack Overflow tags: laravel-verbs, event-sourcing.
  • Troubleshooting:
    • Common Issues:
      • Concurrency conflicts: Resolve with last_event_id checks.
      • Serialization errors: Ensure events implement Serializable or use #[Serializable].
      • Snapshot desync: Verify verb:replay works as expected.
    • Logs: Enable VERBS_LOG=1 for verbose output.

Scaling

  • Horizontal Scaling:
    • Stateless Workers: Verbs works well with queue workers (e.g., Horizon).
    • Octane: Supports high concurrency with wormhole time isolation.
  • Database Scaling:
    • Read Replicas: Snapshots can be served from replicas; events require strong consistency.
    • Sharding: Partition events by aggregate root ID (e.g., user_id).
  • Performance Tuning:
    • Snapshot Frequency: Balance storage vs. replay cost (e.g., snapshot every 5 events).
    • Event Batching: Use Verbs::batch() for bulk operations.
    • Caching: Cache frequently accessed states (
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai