survos/fw-bundle
A small Symfony bundle from Survos that packages shared base functionality for Symfony applications and bundles, covering configuration defaults, service wiring, and common utilities. Little-used (no stars, low score), so treat it as early-stage or internal tooling rather than a widely adopted, well...
First, disambiguate the name. survos/fw-bundle is "a Symfony bundle for Framework7" — the mobile HTML/CSS/JS framework by iDangero — not Symfony 7 and not Laravel 7. There is no Laravel integration of any kind: no extra.laravel.providers, no Illuminate\* constraints, no service provider, no facades. composer require survos/fw-bundle into a Laravel app will install PHP code that Laravel never loads.
So a Laravel developer has exactly two realistic entry points:
docs/events.md.Where to look first, in order
docs/events.md — the single highest-value artifact in the repo. It documents how Framework7 v9's page/tab lifecycle events actually work (real DOM events vs. F7's internal pub/sub), verified against the compiled F7 source rather than the marketing docs. This file is portable to Laravel verbatim.assets/src/controllers/mobile_controller.js — the Stimulus controller, ~one screen of code. This is what you port.assets/package.json — not an npm manifest you can npm install. It is Symfony AssetMapper importmap metadata, listing logical import names (e.g. @survos-mobile/mobile) and paths. Read it as a dependency map, not a package spec.templates/fw-base.html.twig and templates/components/ — the F7 view/sheet/popup markup you re-express in Blade.src/SurvosFwBundle.php — bundle config tree, compiler pass, AssetMapper registration. Symfony-only; skim to understand what the templates expect to be in scope, then ignore.First use case (Laravel-native port)
Do not install the bundle. Reproduce the smallest slice: one F7 app, one Stimulus controller, one real F7 event firing.
npm i framework7@^9 @hotwired/stimulus vite
// resources/js/controllers/mobile_controller.js
import { Controller } from '@hotwired/stimulus';
import Framework7 from 'framework7/bundle';
import 'framework7/css/bundle';
export default class extends Controller {
connect() {
this.app = new Framework7({ el: this.element });
}
disconnect() { this.app?.destroy(); }
}
{{-- resources/views/layouts/fw.blade.php --}}
<!DOCTYPE html>
<html>
<head>@vite(['resources/css/app.css', 'resources/js/app.js'])</head>
<body>
<div data-controller="mobile"><div id="app">@yield('content')</div></div>
</body>
</html>
Then confirm a page-transition event fires and logs — cross-check the event name against docs/events.md before trusting any blog post or older F7 tutorial.
Treat the bundle as a snapshot, not a dependency. With one release, no changelog, zero stars and zero dependents, the correct mental model is "curated source I read once." Copy what you need into resources/js and resources/views, note the source commit in a comment, and own the code from then on. This sidesteps every Symfony/Laravel mismatch below.
Port the Stimulus controller in full, then re-point it at Vite. The controller is framework-agnostic once you strip the import alias. Its only Symfony coupling is the importmap name @survos-mobile/mobile; in Vite you replace it with a relative path. Keep the class shape (connect / disconnect / destroy()) so upstream diffs stay diffable against your copy.
Port fw-base.html.twig to Blade structurally, not syntactically. Twig components (<twig:Foo>) have no Blade equivalent; map each one to either a Blade component (<x-foo>) or a partial (@include). What matters for F7 is the DOM contract — .view, .page, .navbar, data-name on routes, data-* attributes F7 reads on init — not the templating language.
Use Laravel's container for the seams the compiler pass fills. The bundle decorates/resolves services in a Symfony compiler pass inside src/SurvosFwBundle.php. In Laravel the equivalents are:
// app/Providers/FwServiceProvider.php
$this->app->singleton(F7Config::class, fn () => new F7Config(
config('fw.theme'),
config('fw.routes'),
));
// decorate rather than replace
$this->app->extend(F7Config::class, fn (F7Config $c, $app) => $c->with(...));
Keep F7 state out of Livewire/Inertia component lifecycles. F7 mutates the DOM on page transitions; Livewire morphdom and Inertia's page swaps both fight it. The stable pattern is one F7 app instance owned by a persistent root element, with content injected by the server outside F7's routing (or by F7's own router.navigate), never by a framework that re-renders the container.
Port docs/events.md into a test, not just a comment. The document exists because F7's documented events and its compiled-source events diverged. Encode the verified names in a small JS test so a future F7 major bump fails loudly:
it('listens on real F7 v9 page events', () => {
expect(REAL_PAGE_EVENTS).toEqual(expect.arrayContaining(['page:beforeremove', /* … */]));
});
If you truly need the Twig helpers, invert the integration: stand up the Symfony app behind a subdomain or path prefix and link out to it, sharing only session/auth via a signed token. Embedding Symfony's AssetMapper output inside a Laravel page is not a supported shape and will break on every Laravel asset recompile.
"framework 7" is a false friend. Both the package description and the repo name read like a Symfony/Laravel major-version bundle. They are not. Any generated assessment that talks about extra.laravel.providers, vendor:publish, or php artisan tinker for this package is extrapolating from the phrase "Symfony bundle" and is describing a different package. Ignore it and read src/ and docs/events.md.
AssetMapper ≠ Vite. assets/package.json follows the Symfony importmap schema (imports, logical @scope/name keys, path values). Laravel ships Vite/npm. You cannot npm install that file. Translate each logical import into a real npm dependency and a package.json of your own.
The bundle targets Symfony 8.1 while it is pre-stable and permits beta packages, and it depends on survos/kit-bundle plus the AbstractUxBundle pattern. That means the source is aiming at a moving target and will churn; do not treat any file path inside it as stable across even patch releases.
F7 v9 real event names only (verified 2026-07-29). Older F7 tutorials and Stack Overflow answers use event names that F7 v9 no longer emits. The bundle's docs/events.md was written specifically because the maintainer got burned by this. If you add a listener, check that file first — otherwise you get a listener that attaches cleanly and silently never fires.
Twig components and Blade components share no syntax. <twig:Foo bar="baz"> → <x-foo :bar="$baz"/>. Do not try to run Twig in Laravel (twigbridge et al. are a maintenance trap for this amount of markup); just rewrite the components.
The compiler pass has no Laravel analogue. If the pass is doing something you actually need — service decoration, tag collection, conditional registration — reimplement it with $this->app->extend(), $this->app->tag(), or a register()-time if in your own provider. There is no debug:container --tag= equivalent workflow; use php artisan about and app()->getLoadedProviders().
Debugging is Symfony-shaped and won't help you. bin/console debug:asset-map, bin/console lint:twig, bin/console debug:container all assume the bundle is installed in Symfony. In your Laravel port the equivalents are npm run build + browser console, php artisan view:cache, and php artisan about. Don't chase Symfony-specific error messages you'll never see.
Zero adoption means no field evidence. One 1.0 tag (2025-03-08, "initial version"), no changelog, no dependents, no issue history. There is no signal on how the maintainer responds to bugs. Pin any direct use (if you ever attempt it) to an exact commit, and note in your own repo which commit you copied from — you are your own upstream.
Extension points, in the order they'd matter if you were staying on Symfony (they mostly collapse to "copy the file" for Laravel): the config tree in src/SurvosFwBundle.php, the compiler pass, the overridable Twig templates under templates/bundles/SurvosFwBundle/, and the Stimulus base class (mobile_controller.js is explicitly the base for an app-level app_controller.js). Subclassing the JS controller is the only one that survives the port cleanly — do that, and vendor the rest.
How can I help you explore Laravel packages today?