DEV Community

Cover image for Discover Symfony UX. UI with Stimulus = fewer JS headaches for you
Reuben Walker, Jr.
Reuben Walker, Jr.

Posted on

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

This article originally appeared on Symfony Station.


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 us 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 homepage screenshot

Symfony UX

If you have read our Twig Components article, you may scroll down to the Be Responsible heading.

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 ⬇️.

Add flex link Flex

“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 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 JS 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 of Symfony UX components

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 🤮
  • Image Cropper 🖼
  • Lazy Image 🥱📷
  • Stylized Dropzone ⏫
  • Swup Integration 📖
  • Notify 📩
  • Typed ⌨️

For non-American readers A = great, B = good, C = so-so, D = Crap, 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.

Autocomplete component screenshot


Autocomplete is an appropriate use of JS.

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

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) 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.

ChartJS 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.

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. 😉

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-.

Lazy Image 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-.

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+.

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.

Swup 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+.

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.

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 😡
  • 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!


Reuben Walker toasts Symfony
Reuben Walker

Symfony Station

Top comments (0)