Weave 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

Ux Turbo Laravel Package

symfony/ux-turbo

Symfony UX Turbo integrates Hotwire Turbo into Symfony apps so you get single-page-app speed and feel without writing JavaScript. It also works with Mercure to broadcast DOM updates to all connected users in real time.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Symfony-Native Integration: Seamlessly integrates with Symfony’s core components (Twig, Doctrine, Mercure) without requiring a full frontend overhaul. Leverages Symfony’s dependency injection, routing, and templating systems, reducing architectural friction.
  • Hybrid Architecture Support: Enables a progressive enhancement approach, allowing gradual adoption of Turbo features (e.g., Turbo Frames for isolated components before full-page transitions).
  • Mercure Synergy: Tight coupling with Symfony Mercure enables real-time updates via Server-Sent Events (SSE), bridging the gap between Turbo’s client-side transitions and server-driven reactivity. As of v3.6.0, this also supports Mercure protocol 1.0 through turbo_stream_from(), keeping the real-time path aligned with current Mercure deployments.
  • Twig-Centric: Extends Twig with custom components (<twig:Turbo:Stream>, <twig:Turbo:Frame>) and functions (turbo_stream_from(), turbo_is_frame_request()), aligning with Symfony’s templating philosophy.

Integration Feasibility

  • Low Barrier to Entry: Requires minimal frontend changes—Turbo works with vanilla JavaScript or existing asset pipelines (e.g., StimulusBundle). No need for Webpack/ESBuild if using the default setup.
  • Backend-First: Primarily a backend library; frontend changes are declarative (e.g., adding data-turbo-* attributes to HTML elements). Ideal for teams with stronger PHP than JavaScript expertise.
  • Symfony Version Lock: Hard dependency on Symfony 7.4+ and PHP 8.4 (as of v3.x). Requires upgrading if using older versions, but the migration path is straightforward (see Integration Approach).
  • Mercure Dependency: For real-time features, requires symfony/mercure-bundle ^0.6+ and Mercure ^0.9 (updated in v3.6.0; previously ^0.4.1+). This also unlocks Mercure protocol 1.0 support. It remains an additional moving part but enables powerful use cases like live notifications.

Technical Risk

  • Breaking Changes: v3.0+ removed backward compatibility layers (e.g., deprecated TurboStreamListenRendererInterface). Teams using older Symfony UX packages (e.g., symfony/ux-turbo-mercure) must migrate to mercure-bundle. v3.6.0 improves this: the TurboStreamListenRenderer deprecation is now only triggered when the service is actually used, reducing noisy upgrade warnings and making deprecation triage safer.
  • JavaScript Module System: v2.13+ uses ES Modules (type: module in package.json), which may require adjustments to existing asset pipelines or browser support considerations.
  • Turbo’s Limitations: Not a full SPA replacement—complex client-side state management (e.g., Redux) or highly dynamic UIs may still require complementary tools (e.g., Alpine.js, HTMX).
  • SEO/Progressive Enhancement: While Turbo supports fallback routes, ensuring accessibility and SEO for disabled JavaScript requires careful implementation (e.g., testing with data-turbo="false").
  • Asset Mapper Compatibility: Earlier versions conflicted with symfony/asset-mapper 8.2+; v3.6.0 resolves this conflict, reducing integration risk for projects on the modern asset mapper pipeline.

Key Questions

  1. Symfony Version Compatibility:

    • Are we on Symfony 7.4+ and PHP 8.4+? If not, what’s the upgrade path and risk?
    • How will we handle deprecated APIs (e.g., turbo_stream_listen()) in existing code? (Note: v3.6.0 only raises the TurboStreamListenRenderer deprecation when the service is used, so unused references will no longer pollute logs.)
  2. Frontend Strategy:

    • Do we need to adopt ES Modules (type: module) for Turbo’s JS, or can we use a CDN?
    • How will we integrate Turbo with existing JavaScript (e.g., Stimulus, jQuery)?
  3. Real-Time Requirements:

    • Do we need Mercure for live updates, or can we start with Turbo’s built-in EventSource?
    • Are we on symfony/mercure-bundle ^0.6+ / Mercure ^0.9, or does upgrading affect our Mercure hub/protocol configuration? (Protocol 1.0 is now supported in turbo_stream_from().)
    • How will we secure Mercure topics (e.g., authentication, authorization)?
  4. Performance:

    • What’s our baseline for page load times? Could Turbo’s JS overhead impact performance?
    • How will we measure the impact of Turbo Frames on server load (e.g., partial renders)?
  5. Team Skills:

    • Does the team have experience with Turbo/Hotwire or similar tools (e.g., HTMX)?
    • How will we train developers on Turbo’s conventions (e.g., data-turbo-* attributes)?
  6. Fallbacks:

    • How will we handle users without JavaScript (e.g., feature detection, graceful degradation)?
    • Are there critical paths that must work without Turbo?
  7. Long-Term Maintenance:

    • How will we monitor Turbo’s compatibility with future Symfony/Stimulus updates?
    • What’s our rollback plan if Turbo introduces breaking changes?

Integration Approach

Stack Fit

  • Symfony Core: Fully compatible with Symfony 7.4+ (recommended) and 6.4+ (with some deprecations). Leverages:
    • Twig: Custom components and functions for streaming responses.
    • Doctrine: Broadcasts entity changes for real-time updates.
    • Mercure: Optional but powerful for live collaboration (e.g., chat, live edits). Bundle ^0.6+ / Mercure ^0.9 supported, including Mercure protocol 1.0.
    • StimulusBundle: Replaces WebpackEncore for asset management (v2.9+).
  • Frontend:
    • Vanilla JS: Turbo works out-of-the-box with no build step.
    • Stimulus: For enhanced interactivity (e.g., modals, transitions).
    • Alpine.js/HTMX: Can coexist for more complex UIs.
  • Database: Doctrine ORM for broadcasting entity changes (e.g., @Broadcast attribute).

Migration Path

  1. Assessment Phase:

    • Audit existing routes, controllers, and templates for Turbo compatibility.
    • Identify high-impact use cases (e.g., forms, modals, infinite scroll).
    • Test with a non-critical feature (e.g., a "quick view" modal).
  2. Setup:

    composer require symfony/ux-turbo symfony/mercure-bundle:^0.6  # if needed
    
    • Configure symfony/ux-turbo in config/bundles.php:
      Symfony\UX\Turbo\TurboBundle::class => ['all' => true],
      Symfony\UX\MercureBundle\MercureBundle::class => ['all' => true],
      
    • Update assets/controllers.json to enable the mercure-turbo-stream controller (if using Mercure).
  3. Incremental Adoption:

    • Phase 1: Turbo Frames
      • Replace static includes with <turbo-frame> tags.
      • Example: Convert a "user profile" partial into a frame:
        <turbo-frame id="user_profile">
            {% include 'user/profile.html.twig' %}
        </turbo-frame>
        
      • Update the controller to return a TurboStreamResponse:
        use Symfony\UX\Turbo\TurboBundle;
        
        public function updateProfile(Request $request): Response
        {
            // ... update logic
            if (TurboBundle::STREAM_FORMAT === $request->getPreferredFormat()) {
                return $this->render('user/_profile.stream.html.twig', ['user' => $user]);
            }
            return $this->render('user/profile.html.twig', ['user' => $user]);
        }
        
    • Phase 2: Progressive Enhancement
      • Add data-turbo attributes to links/forms:
        <a href="/posts/1" data-turbo="true">View Post</a>
        <form data-turbo="true">...</form>
        
    • Phase 3: Real-Time Updates (Optional)
      • Integrate Mercure for live broadcasts:
        <turbo-mercure-stream-source src="{{ path('mercure') }}" topics="{{ mercureHubUrl }}topic/posts">
        
        • Annotate entities with @Broadcast:
          #[Broadcast]
          class Post {}
          
  4. Testing:

    • Verify Turbo Frames render correctly with Accept: text/vnd.turbo-stream.html.
    • Test JavaScript-disabled fallbacks (e.g., data-turbo="false").
    • Monitor Mercure topic subscriptions for real-time updates.
    • Validate turbo_stream_from() against your Mercure hub protocol (1.0 now supported).

Compatibility

  • Symfony Ecosystem:
    • Works with Symfony’s asset mapper (v2.9+), and v3.6.0 removes the conflict with symfony/asset-mapper 8.2+, making it compatible with the latest asset management pipeline.
    • Integrates with Symfony Security for authenticated Turbo Streams.
  • Third-Party:
    • Mercure: Requires symfony/mercure-bundle ^0.6+ and Mercure ^0.9 for real-time features. Supports Mercure protocol 1.0 in turbo_stream_from().
    • Stimulus: Uses StimulusBundle (v2.9+) for asset compilation.
    • Doctrine: Broadcasts entity changes via Doctrine listeners.
  • Browser Support: Turbo supports all modern browsers (Chrome, Firefox, Safari, Edge) and degrades gracefully for older ones.

Sequencing

  1. Prerequisites:
    • Upgrade Symfony to 7.4+ and PHP to 8.4 (if not already).
    • Migrate from symfony/ux-turbo-mercure to mercure-bundle (if applicable).
    • If already using Mercure, review and upgrade to mercure-bundle ^0.6 / Mercure ^0.9 and confirm protocol 1.0 support with your hub.
  2. Core Integration:
    • Install symfony/ux-turbo and configure bundles.
    • Set up asset pipeline (StimulusBundle or Asset Mapper).
  3. Feature Rollout:
    • Start with Turbo Frames for isolated components.
    • Add progressive enhancement to links/forms.
    • Implement Mercure for real-time features (last step).
  4. Optimization:
    • Cache Turbo Stream responses.
    • Monitor performance (server load from partial renders, JS bundle size).
    • Track deprecation warnings from TurboStreamListenRenderer now that they only fire on service use.

Operational Impact

Maintenance

  • Low ongoing cost for the core Turbo integration; most changes are additive and versioned.
  • Deprecation hygiene improved: v3.6.0 limits TurboStreamListenRenderer deprecation notices to actual service usage, reducing log noise and false-positive maintenance tickets.
  • Dependency tracking: Mercure-related dependencies (mercure-bundle ^0.6, Mercure ^0.9, protocol 1.0) should be monitored as they evolve; plan periodic minor upgrades.
  • Tooling churn (e.g., v3.6.0 tooling dependency updates) is low-impact for consuming applications.

Support

  • Vendor support is strong via Symfony UX maintainers and an active community; release cadence is regular.
  • Internal support benefits from the backend-first model—PHP-heavy teams can support most of the stack without deep JS expertise.
  • Escalation path: breaking changes are documented in changelogs and typically paired with migration notes.

Scaling

  • Server-side scaling is dominated by partial render frequency; Turbo Frames reduce full-page payloads but increase per-frame request volume. Cache aggressively where possible.
  • Real-time scaling depends on Mercure hub capacity and topic fan-out. Protocol 1.0 support keeps integration current but does not change hub sizing considerations.
  • Team scaling benefits from declarative conventions (data-turbo-*, Twig components), which are easier to onboard than full SPA state management.

Failure Modes

  • JavaScript disabled / blocked: critical flows must have non-Turbo fallbacks; test with data-turbo="false" and no-JS clients.
  • Mercure outage: real-time features degrade; design stream-driven surfaces to refresh on full-page reload or polling fallback.
  • Version drift: mismatch between ux-turbo and mercure-bundle / mercure hub protocol can break live updates; pin composer constraints and validate in staging.
  • Asset pipeline issues: historically a conflict with asset-mapper 8.2+ existed; now resolved, but asset pipeline changes should still be regression-tested.
  • Deprecation surprise: legacy TurboStreamListenRenderer usage still surfaces warnings when the service is actually invoked—treat these as planned cleanup work, not incidents.

Ramp-up

  • Developers: PHP developers can be productive in days; JS-adjacent concepts (Templates/Frames/Streams) take longer to master.
  • Ops: minimal new infrastructure unless Mercure is adopted; in that case hub deployment, TLS, and topic authorization require onboarding.
  • QA: test matrix must include JS-enabled, JS-disabled, frame navigation, stream responses, and Mercure-connected/unconnected scenarios.
  • Recommended onboarding: start with a single Turbo Frame, expand to progressive enhancement, then introduce Mercure only when a concrete real-time use case is validated.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core