werkint/frontend-mapper-bundle
A small Symfony bundle for mapping frontend assets and resources to backend configuration, simplifying how templates and views resolve their frontend dependencies. Lightweight and easy to wire in, though documentation is sparse and adoption is limited, so expect to read the source to get started.
Reality check first: despite the "Laravel developer" framing, werkint/frontend-mapper-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/frontend-mapper.php. It was last touched in January 2016 (Symfony 2.x/3.x era), has 2 stars and zero dependents. Treat it as a piece of legacy source you may read or vendor, not something you composer require into a modern Laravel app.
Minimal steps to evaluate it:
Clone and read, don't install.
git clone https://github.com/Werkint/FrontendMapperBundle /tmp/fmb
cd /tmp/fmb && cat composer.json && find . -name "*.php" | head -50
The composer.json will tell you the real constraints (symfony/symfony, php >=5.x). Those constraints are the first thing that will block a Laravel 9/10/11 install.
Locate the entry points. For a bundle of this age, look for:
*Bundle.php (the Bundle subclass — this is the Symfony registration hook, not a Laravel provider)DependencyInjection/*Extension.php and Configuration.php (where config schema lives)Resources/config/services.yml (the actual service graph)Mapper, Resolver, or Factory classes — these are the parts you'd actually reuse.Identify the domain concept. The name suggests it maps "frontend" definitions (forms, fields, widgets, routes) to backend services. Before writing any integration code, confirm what a "frontend" or "mapping" means in this codebase by tracing one public method end-to-end.
First use case (Symfony, if you must). Register the bundle in app/AppKernel.php (or config/bundles.php on Symfony 4+), import its services.yml, and wire one mapper service into a controller. That is the only path the original author designed for.
First use case (Laravel, realistically). Copy the standalone mapper classes into app/Support/FrontendMapper/, strip any Symfony\Component\* imports, and bind them in a small service provider of your own. Don't try to load the bundle.
Pattern 1 — Extract the mapper, discard the bundle. The valuable part of any bundle like this is usually 1–3 plain classes with no framework coupling. Pull them out, replace Symfony DI constructor injection with Laravel's container, and put a thin adapter around them:
// app/Support/FrontendMapper/MapperAdapter.php
class MapperAdapter
{
public function __construct(private LegacyMapper $mapper) {}
public function map(array $input): array
{
return $this->mapper->map($input);
}
}
Bind in a provider and inject MapperAdapter everywhere. This isolates the abandoned code behind one seam you can later replace.
Pattern 2 — Config translation.
If the bundle's Configuration.php defines a tree (e.g. field mappings, type aliases), translate that into a published Laravel config file. Keep the shape identical so the legacy Configuration semantics survive:
// config/frontend-mapper.php
return [
'mappings' => [
'user' => ['email' => 'string', 'age' => 'integer'],
],
];
Load it in the provider with $this->mergeConfigFrom(...) and pass config('frontend-mapper.mappings') into the extracted mapper.
Pattern 3 — Symfony-style service decoration, Laravel-style. If the original relies on tagged services / compiler passes to collect mappers, replicate with Laravel's tagged bindings:
$this->app->tag([EmailMapper::class, AddressMapper::class], 'frontend.mappers');
$this->app->bind(MapperRegistry::class, fn ($app) =>
new MapperRegistry($app->tagged('frontend.mappers'))
);
This preserves the "register N mappers, resolve by key" workflow the bundle was built around without a compiler pass.
Pattern 4 — Event-based extension.
Bundles of this vintage often fire Symfony events (FrontendMapEvent etc.). Map those to Laravel events/listeners one-for-one so downstream code doesn't need to know the origin. This is the cheapest way to keep behaviour identical while modernising the plumbing.
Pattern 5 — If you genuinely keep it in a Symfony app.
Standard bundle wiring: register in bundles.php, import Resources/config/services.yml via the extension, then autowire the mapper into a controller/console command. Use it for one narrow job (e.g. building a form schema from a frontend definition), not as the backbone of a domain.
FrontendMapperServiceProvider, no FrontendMapper facade, no php artisan vendor:publish. Any tutorial implying otherwise is wrong. Expect to write all the glue yourself.symfony/symfony: ~2.7|~3.0 and php: >=5.5. Installing alongside Laravel 9+ (PHP 8.1+, Symfony 6/7 components) will produce unresolvable conflicts. Use --ignore-platform-reqs only in a scratch project, never in production.composer.json autoload before assuming Werkint\FrontendMapperBundle\... paths.ContainerBuilder or a Reference, you've gone too deep — stop and cut the dependency at the mapper class boundary instead.Configuration.php trees often use required nodes and normalisers that silently transform input (e.g. singularising keys, coercing scalars). Preserve those normalisers when you port the config, or behaviour will drift subtly.load(), event dispatchers, and any *Interface the bundle defines for mappers/resolvers. Interfaces are your safest integration surface — code against them and swap the implementation.app/Support/ (or a private vendor) so you control patching.symfony/form alternatives), DTO mappers (spatie/laravel-data, cuyz/valinor), or plain transformation classes usually cover the same ground with active maintenance. Only keep this bundle if its specific mapping semantics are non-trivial to reproduce.How can I help you explore Laravel packages today?