Back to top with progress scrollbar

Discover Symfony UX. UI with Stimulus = fewer JS headaches for you

By Reuben Walker, 23 August, 2022

Purple tinged view of space


Let’s explore the magic that Stimulus JS brings to Symfony UX.

This is a companion article to Discover Symfony UX’s Twig Components. Read that first, as it contains more detailed Symfony UX information referenced here.

As mentioned in our Twig article, we are fans of componentization. It’s a philosophy similar to the S in SOLID programming principles. IYDK that’s the single responsibility principle.

And we are especially fans of the web components used in user interfaces. They are a fine example of componentization.

But we are not fans of JavaScript, especially for UI components. For a review of its clusterfuckiry see our article on Frontend Madness.

Thus, we love anything that simplifies using it or, better yet, eliminates JS. That’s why we use tools like CSSUI on this Drupal site. And never use JS when it’s not necessary. In other words, we use HTML and CSS as you should.

In a Symfony project’s UI, components are handled by a group of tools with the moniker of Symfony UX. This article is going to explore it and its non-Twig-related UI components.

Symfony UX home page screenshot

Symfony UX

If you have read our Twig Components article, you can skip to this.

If not, Symfony describes Symfony UX as “JavaScript tools you can't live without. They’re a set of PHP and JavaScript packages to solve everyday frontend problems featuring Stimulus and Turbo.”

“Symfony UX is an initiative and set of libraries to seamlessly integrate JavaScript tools into your application.

Behind the scenes, the UX packages leverage Stimulus: a small but powerful library for binding JavaScript functionality to elements on your page.”

Thank you, abstraction.

How does Symfony UX work?

The short answer is when you install a package (aka Stimulus component), Symfony updates everything automagically.

The long answer, according to the docs is ⬇️.

“When you install a UX PHP package, Symfony Flex will automatically update your package.json file to point to a "virtual package" that lives inside the PHP package.

The Flex recipe will also update your assets/controllers.json file to add a new Stimulus controller to your app.

Finally, your assets/bootstrap.js file - working with the @symfony/stimulus-bridge - package will automatically register:

  • All files in assets/controllers/ as Stimulus controllers;
  • And all controllers described in assets/controllers.json as Stimulus controllers.

The end result: you install a package, and you instantly have a Stimulus controller available!”

FYI, the virtual package is the Stimulus JS node package.

Symfony UX / Stimulus controllers control your user interface. And thanks to them, you can do so without writing a ton of custom JavaScript. They handle the JS for you. You handle your PHP.

However, you can still write custom JavaScript inside Stimulus Controllers or use third-party components. If that floats your boat.

Stimulus components homepage screenshot

Why? Stimulus was created and is used by developers outside of Symfony (specifically Ruby on Rails). Thus additional tools are available beyond the Symfony UX packages.

In particular, according to their documentation:

  • stimulus-use: Add composable behaviors to your Stimulus controllers, like debouncing, detecting outside clicks, and many other things.
  • stimulus-components: A large number of pre-made Stimulus controllers, like for Copying to clipboard, Sortable, Popover (similar to tooltips) and much more.”

You should always steal your rivals’ good ideas. And share yours. So props to Symfony.

As we just mentioned, you can use code from these third-party tools in your controllers.

Symfony docs say ⬇️:

“By default, all of your controllers (i.e. files in assets/controllers/ + controllers in assets/controllers.json) will be downloaded and loaded on every page.”

Be responsible

A quick note is warranted here. Symfony UX gives you powers. But with great power comes great responsibility. By the way, who said that? Uncle Ben? An Ancient Greek philosopher? 😉

So, just because you can use these doesn’t mean you should. Remember Jurassic Park. Plus, simpler is better and less is more.

Screenshot showing all Symfony UX componente

Symfony UX Components/Packages

As the image above indicates, there are twelve components to make your programming life easier.

You can explore them all here.

Or continue reading for the non-Twig-related ones 🌿.

We will look at and grade:

  • Autocomplete 🙂
  • Chart.JS 📊
  • React 🤮
  • Vue 🙂(Update 9/8/2022)
  • Image Cropper 🖼
  • Lazy Image 🥱📷
  • Stylized Dropzone ⏫
  • Swup Integration 📖
  • Notify 📩
  • Typed ⌨️

For non-American readers A = great, B = good, C = so-so, D = Crap, there is no E, F = Failure

We will publish an article in the future on Turbo🏃🏽. I’m thinking of “Discover Symfony UX: Turbo lets you say FU to SPAs” for the title.

Some of the components are useful. And IMHO some should be avoided whenever possible, like JS itself. When you should use HTML and CSS people, do so. And I don’t mean Failwind or Bootcrap. Use the languages directly and correctly.

Anyway, most of these components do implement JavaScript, while a few have a dash of Symfony and Ajax sprinkled in.

Symfony UX Autocomplete component screenshot


Autocomplete is an appropriate use of JS.

It provides smart form controls via Ajax-powered autocomplete and <select>.

The docs say:

“Breathe life into EntityType and ChoiceType fields with Tom Select and a sprinkle of Ajax.”

And Tom Select says:

“Tom Select is a dynamic, framework agnostic, and lightweight (~16kb gzipped) <select> UI control. With autocomplete and native-feeling keyboard navigation, it's useful for tagging, contact lists, country selectors, and so on. Tom Select was forked from selectize.js with four main objectives: modernizing the code base, decoupling from jQuery, expanding functionality, and addressing issue backlogs.”

Autocomplete gets an A+ grade.

Symfony UX chart js component screenshot


Chart.JS is another appropriate use of JavaScript. Charts are useful for user experience and effective content.

The component lets you render graphs via chart.js.

Symfony says:

“Leverage the power of chart.js entirely from PHP.”

I say amen, brother.

And Chart.JS itself says it is “simple yet flexible JavaScript charting for designers and developers.”

And they are correct.

Chart.JS get an A+ too.

Symfony UX React component screenshot


I would have chosen Vue, Alpine, or even Svelte for this component. But like WordPress, Symfony screwed up and chose React. Bigger is not better, and popular never is.

I stay away from it just like I stay away from religious fanatics, fascists, communists, conspiracy theorists, and stupid people in general.

There is too much JS in the world, to begin with, especially a clusterfuck like React. If I have to touch it, I hold my nose and use a 410-foot pole.

Plus, it’s from fucking Facebook.

But here’s the component link with more info if you’re interested.

Remember, if you are forced to use some SPA-like garbage UI by an evil boss or ignorant client, you can roll your own web components. Or use 3rd party components like Vue.

Fortunately, SymfonyCasts says you can use Vue in Stimulus controllers. Just not in the React component.

Better yet, use CSS components in your app or Stimulus components with Symfony UX.

Rant over and React gets a totally objective F. 😉

Screenshot Symfony UX Vue Component

Update 9/8/2022.

Fortunately for you, Symfony UX just released a Vue component.

Vue explains the advantages of using it over something like React.

"The web is extremely diverse - the things we build on the web may vary drastically in form and scale. With that in mind, Vue is designed to be flexible and incrementally adoptable. Depending on your use case, Vue can be used in different ways:

  • Enhancing static HTML without a build step
  • Embedding as Web Components on any page
  • Single-Page Application (SPA)
  • Fullstack / Server-Side Rendering (SSR)
  • Jamstack / Static Site Generation (SSG)
  • Targeting desktop, mobile, WebGL, and even the terminal"

Like Symfony with Vue you only use what you need. You progressively implement it.

The Symfony UX documentation says:

"Vue.js is a JavaScript framework for building user interfaces. Symfony UX Vue.js provides tools to render Vue components from Twig, handling rendering and data transfers.

Symfony UX Vue.js supports Vue.js v3 only.

UX Vue.js works by using a system of Vue.js controller components: Vue.js components that are registered using registerVueControllerComponents and that are meant to be rendered from Twig."

Explore all the docs here.

And learn more about Vue 3 here.

Vue gets a totally objective A+. 😉

Symfony UX Image Cropper component screenshot

Image Cropper

As the name implies, you can crop images with Image Cropper.

Symfony says:

“Let your users crop images with Cropper.js, then grab the final image from PHP. Simple.”

I say, why? 98.874% of the time, this is unnecessary for the frontend. Maybe if you are building a backend for someone? Or a photography tutorial app?

Image Cropper gets a B-.

Symfony UX Lazy Images component screenshot

Lazy Image

Lazy loading images is an appropriate use of JS. So, hurray for Lazy Image.

Symfony says:

“Load fast with Lazy Images. Serve small or blurred images first, then load the real thing after the page loads.”

It’s an interesting implementation using BlurHash.

Blurhash says:

“BlurHash takes an image and gives you a short string (only 20-30 characters!) that represents the placeholder for this image. You do this on the backend of your service and store the string along with the image. When you send data to your client, you send both the URL to the image and the BlurHash string. Your client then takes the string and decodes it into an image that it shows while the real image is loading over the network. The string is short enough to comfortably fit into whatever data format you use. For instance, it can easily be added as a field in a JSON object.”

Lazy Image (if you need it) gets an A-.

Symfony UX Stylized Dropzone component screenshot

Stylized Dropzone

This component lets you implement a styled upload zone in your app.

Symfony says:

“Native Upload Dropzone with style. Upgrade your upload field to a stylized "Dropzone" with file previews.”

The documentation says:

“The most common usage of Symfony UX Dropzone is to use it as a drop-in replacement of the native FileType class. It provides a default stylesheet to ease usage. You can disable it to add your design. Symfony UX Dropzone allows you to extend its default behavior using a custom Stimulus controller.”

This could be useful at times so Stylized Dropzone gets a B+.

Symfony UX Swup component screenshot

Swup Integration

Swup Integration can be used as an alternative to the Turbo component. That’s interesting.

You can create slick Ajax Page Transitions with Swup.

Symfony says:

“Replace full page refreshes with Ajax-powered, stylized page transitions.”

Swup.js says it’s a:

“Complete, flexible, extensible, and easy to use page transition library for your web.”

It’s worth exploring.

Swup Integration gets an A.

Symfony UX Notify component screenshot


Notify provides native browser notifications.

Simple enough.

Symfony says:

“Notify users from inside PHP. Send real-time, native browser notifications to everyone via Symfony's Notifier Component.”

Their docs say:

“To use Symfony UX Notify you must have a running Mercure server and a properly configured notifier transport. Then, you can inject the NotifierInterface service and send messages on the chat/myMercureChatter channel. Finally, to "listen" and trigger the notifications in the user's browser, call the stream_notifications() Twig function anywhere on the page.”

This is useful so Notify gets an A+.

Symfony UX Typed component screenshot


Again, why? Maybe in a tutorial?

This is the type of half-assed and unnecessary JS functionality that plagues web design. You can see how annoying it is on the Symfony UX homepage.

But it’s a half-free world, so knock yourself out if interested.

Typed gets an objective C. 😉

Wrapping it up

Ok. School’s out.

Let’s hope there are more components on the way from Symfony UX. Alternatives to React insertion should top the list. Update 9/8/20022. They added a Vue component. Yay!

Carousel? No. Lightbox? Maybe. Dropdown? Yes. Textarea autogrow? 🤯

And if you have a request, let please Symfony know. You might want to make a donation as well. Let me rephrase that. Give them some money. Free riders suck.

You can use their commercial products like Symfony Insight, attend official Symfony conferences, buy the Symfony book, or if you are rich or own a company, sponsor them.

Money rant over, you now know more about Symfony UX and specifically its JS-related components. Which are most of them. The initiative and set of libraries seamlessly integrate JavaScript tools into your application. Some are more useful than others. And if you believe in proper UI, some should be avoided 99% of the time.

They can:

  • autocomplete fields 😎
  • insert charts into your application 😊
  • infect your app with React 😡
  • use Vue rather than React 😊
  • crop images 😐
  • lazy load images 😎
  • preview files to be uploaded 😊
  • add page transition animation 😊
  • add notifications 😎
  • and provide showy typing. 😞

Now, implement this goodness (minus the React) into your Symfony projects with less JS and no BS required. Use the ones that improve your UX and skip any unnecessary UI.

Want to eliminate even more JavaScript? Read our article, Frontend Madness: SPAs, MPAs, PWAs, Decoupled, Hybrid, Monolithic, Libraries, Frameworks! WTF for your PHP backend?

Explore some more

We rate these SymfonyCast courses 10 out of 10.

It’s worth the investment. Plus, they are entertaining.

To learn about more advanced options, visit the repository @symfony/stimulus-bridge, the Node package that is responsible for a lot of the magic Stimulus JS brings to Symfony UX.

Happy coding Symfonistas!

section separator

Join our list  

* indicates required

Please share