Tristan Edwards

@edwards

Why I’m excited about GlimmerJS

I’ve just come back from EmberConf in Portland, and besides getting to know the community and making some awesome new friends, the GlimmerJS announcement is what really caught my eye.

Some of you might know that I’ve been a big fan of Ember for a long time. Like many others, I was initially put off by the high learning curve, until I eventually learned to embrace the framework’s conventions, and became a better developer in the process.

Even though I’ve flirted with basically all other major web frameworks since then, I still choose Ember most of the time when I have to build an ambitious web application. And why wouldn’t I? The CLI is fantastic, the Glimmer engine is now fast, and getting server-side rendering is literally just an ember install away thanks to FastBoot.

Despite all this, it’s no secret that lighter libraries like Vue and React have stolen the show in recent years. Why? Well, in addition to introducing some awesome new concepts like the virtual DOM and a one-way data flow, React also made it significantly easier to migrate your existing Rails/Laravel/Django front-end piece by piece.

This is crucial. Companies usually aren’t too keen on rewriting software from scratch, and Ember had no way of letting developers dip their feet into the water before diving in. Until now.

Bundle size of different libraries + frameworks (minified + gzipped). Based on my own independent research.

With GlimmerJS, you can finally get the benefits of Ember’s rendering engine and CLI, without having to buy into the whole ecosystem. The project is new, and therefore obviously still a little rough around the edges, but based on what I’ve seen so far, I’m impressed.

Enough talking, show me the code!

Let’s see how we can spice up any traditional web application with some Glimmer components! I’m going to start off with an extremely simple website: no Babel, no ES6, just plain HTML with script tags and links to CSS.

We’ll call our app todo-app since it’s going to contain a todo-list (yeah I know, not a very original concept…) If you ever get stuck while following along, you can check out the project’s GitHub repo.

$ mkdir todo-app && cd todo-app && touch index.html

Here's the inside of index.html:

<html>
 <head>
<title>Todo app</title>
</head>

<body>
<h1>Hello world!</h1>
</body>
</html>

Alright, let’s create an interactive todo-list web component for this page! We’ll first create a components folder inside our project, where all our future Glimmer components will live:

$ mkdir components && cd components

Using the latest Ember CLI (installed globally with Yarn), we now simply run this command:

$ ember new todo-list -b @glimmer/blueprint --web-component

Ember will generate everything we need to get started quickly with our new component. When it’s done installing, we’ll switch our development setup to focus only on the component:

$ cd todo-list && ember server

Visit localhost:4200, and you’ll be greeted with this page:

This is the default markup of our new component, which you can find at todo-list/src/ui/components/todo-list/template.hbs. Let’s turn it into something more “todo-list”-like!

There we go! I personally really like Handlebars syntax since it makes it clear where the regular HTML ends and where Glimmer takes over. (compare that to Angular’s <ul *ngFor="item in items"> or Vue’s <li v-for="item in items">).

Next, we want each item in our list to be rendered into its own todo-item component. Staying inside our todo-list folder, we generate a new Glimmer component in our existing project:

$ ember g glimmer-component todo-item

We can now update our todo-list/template.hbs so that it uses this new component for every list item instead:

{{#each items key="@index" as |item|}}
<todo-item
@item={{item}}
/>
{{/each}}

Notice how Glimmer uses @ to distinguish between arguments (props) and regular HTML attributes when you invoke the component. That’s another feature I really like, not just because of the elegant syntax, but also because it circumvents the problem of having to manually whitelist attributes in the library.

So far, so good. Now let’s add some functionality!

We’ll start with the ability to add items to the list. For this, we first need to import the tracked decorator, so that we can specify which properties are allowed to change (Glimmer distinguishes between mutable and immutable properties to improve performance). We’ll use this decorator on items and on the newly defined newItemText property:

// src/ui/components/todo-list/component.ts
import Component, { tracked } from "@glimmer/component";
export default class TodoList extends Component {
  @tracked newItemText = '';
  @tracked items = [
{
text: "Install Glimmer",
isDone: false,
},
// ...

We proceed by binding some events to our input and button tags. This way we can update newItemText whenever the user types, and add a new item to the list when the button is clicked. For those of you that are familiar with Redux, you’ll recognise the way we use the immutable spread syntax for this:

It works!

We also want to remove an item when the user clicks on “Delete item”, and cross it out when they click on the text. To accomplish this, we need some event handlers on todo-item which will trigger actions up to the todo-list (following Ember’s “Data Down, Actions Up” convention).

Again, the technique we use for updating the data here is pretty similar to Redux’s way of doing things.

You should now be able to add items, delete them and toggle the “crossing out” (although you won’t see any UI change when toggling them yet).

For the grand finale, let’s add some CSS to all this! You’ll notice that Glimmer projects come with an app.scss file, so that you can take advantage of the SASS preprocessor instantly without any extra setup. Simply copy-paste the following into your app.scss:

Now that’s much prettier!

That’s it! Our component is done! The only thing left to do now is to import it into our static website so that we can use it outside of the Ember environment.

This is also super easy since Ember CLI has already compiled the app for us. In the todo-list component’s dist folder, you’ll find both an app.js and an app.css file – they’re all you need to render your component!

Go back to your static website and add references to these files (one script-tag and one link-tag). Then simply invoke the component with <todo-list /> right after your existing “Hello world” title:

Boom!

Now that is sweet! It’s worth noting that our Glimmer component is currently built in “development” mode. By using ember build ---environment=production instead, I got app.js down to 34.18 KB gzipped, which is actually smaller than just React + React DOM by itself. Pretty impressive!

Hopefully this has given you a taste of how easily you can add interactive Glimmer components to your website. I’m certainly looking forward to see how the library develops, and how it will integrate with the rest of the Ember ecosystem in the future.

If you enjoyed this tutorial, you’ll probably also like my online courses on Ember and Elixir over at Ludu. Go check them out!

Topics of interest

More Related Stories