AssetMapper & frontend assets
New Symfony web apps often ship AssetMapper - versioned assets without a mandatory Webpack/Vite pipeline. Your FE brain still applies; the defaults just differ from Laravel's Vite stub.
Mental model
- Put CSS/JS under
assets/ - Import map (
importmap.php/assets/app.js) tells the browser how modules resolve - Twig helpers dump the right
<link>/<script type="importmap">tags - In prod, assets get digested/versioned
It's closer to "native ES modules + a smart map" than to a full bundler - until you need one.
Typical Twig hooks
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('styles/app.css') }}">
{% endblock %}
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}Exact helpers depend on your Flex recipe version - peek at the generated base.html.twig. When something 404s, check assets/ and php bin/console debug:asset-map (if available in your version).
When you want Vite / Encore
Some teams still use Webpack Encore or a custom Vite setup - especially for React/Vue SPAs living inside Symfony.
Rules of thumb:
- AssetMapper - classic MPA, light JS, Stimulus-ish islands
- Encore / Vite - heavy SPA, JSX/TSX pipelines you already know
Don't fight the project's choice on day one. Match whatever package.json / importmap.php already implies.
Compared to Laravel
| Laravel | Symfony (default webapp) |
|---|---|
resources/js + Vite | assets/ + AssetMapper |
@vite([...]) | importmap() / asset() |
npm run dev always | optional until you outgrow the map |
As you can see, the FE skill transfers - the default toolchain is the surprise.
Next: forms, validation, and CSRF without reinventing $_POST.
Best,
-- ł.