Making a fullstack CRUD app with LitHTML, Redux, Express, and Webpack.

Pascal Schilp
9 min readJul 16, 2018

--

Before I start, I should mention that: This is not a tutorial. But if you’re here because you want to quickly start building lit apps with Redux/Express/Webpack/Routing, check out this repo over here: create-lit-app

And let me know if you’ve used it to build something cool!

I’ve fairly recently started working at a job where we use Polymer on the frontend. Coming from React and ES6 modules, switching to Polymer and HTML imports felt a little awkward for sure. Recently, however, the Polymer team has decided to switch over to NPM with their release of Polymer 3. Read all about it here.

With the release of Polymer 3 also comes the new suggested base class LitElement, spawned from Justin Fagnani’s Lit-html. Which seems to be the way forward:

“For new development, you should also consider LitElement, a light, performant, next-generation base class for custom elements.”

https://www.polymer-project.org/3.0/docs/about_30

So what is LitHTML?

LitHTML lets you write HTML templates with JavaScript template literals (get it?), and efficiently render and re-render those templates to DOM. Which looks a little something like this:

Now, if you’ve used React before, you might recognize this as JSX or a Functional Stateless Component (short: FSC), but its not. It’s actually just standard javascript syntax!

LitHTML uses tagged template literals, which is simply a feature of ES6 (#usetheplatform), that can span multiple lines, and contain javascript expressions. This tagged template literal (specifically: html`` ) returns a template result, which is an object that contains a reference to the template we want to render, and the data that we want to render it with.

The nice thing about tagged template literals is, that when we want to render our helloTemplate multiple times:

Only one template result object is made for our entire app, the only thing thats different is the data passed to it.

Additionally, LitHTML doesn’t have Vdom, or do any diffing.

What is LitElement?

LitElement is the new base class that uses LitHTML to react to changes in properties and render stuff declaratively. A LitElement looks like this:

If you’re interested in more Lit examples and learn more about lifecycle, please check out these incredible demos by Lars den Bakker

The interesting bit is this right here: Then lit-html ensures that updates are fast by creating the static DOM once and smartly updating only the parts of the DOM that change.

The difference with Vdom (virtual dom) is that Vdom rerenders the entire virtual tree with every change. It scales with the number of nodes in your template, but drives the cost per node down as low as possible.

LitHTML doesn’t do any diffing, or compare any static parts of a template after the initial render. Instead, it looks only at the expressions. Which are just javascript values. If a value, or result of an expression didnt change, it doesnt update the DOM. LitHTML doesn’t even do any extra work for this, its just javascript evaluating the expressions. After all, Polymer is not a framework, its syntactic sugar over the standard Web Components APIs.

Additionally, Lit is fast because it uses the fast built in string parsing of the browser, which is roughly 3x faster than generic javascript expressions. (#usetheplatform)

A little more on tagged template literals…

This weird looking html tag might throw you off a little if you’ve never seen it before, so lets dive into it a little deeper. Tagged template literals are just standard ES6 syntax. And these tags are actually just functions! Consider the following example:

We just made our own tagged template literal, and all we did is declare a function. You can try this out yourself right now by writing it in the console of your browser. The only difference is in how we call it.

Now lets see how tagged template literals handle expressions:

When we use expressions or other variables in our template literal, javascript will evaluate the expression, and we can access the result in our function. (I used the spread, or rather; the gather operator to combine all following parameters in an array, but we also could’ve written:function customTaggedLiteral(strings, value1, value2)). And thats how tagged template literals work.

And if we look at the source code of LitHTML, we can see that thats exactly whats happening:

So again, LitHTML doesn’t use any spooky framework-magic under the hood. Just standard ES6 syntax. (#usetheplatform)

For a more in depth explanation of the inner workings of LitHTML, please consider watching the following two videos by Justin Fagnani: https://www.youtube.com/watch?v=Io6JjgckHbg https://www.youtube.com/watch?v=ruql541T7gc

Making a CRUD app with LitHTML

Now that we have some context, and have had some impressions of what LitHTML and LitElement are and look like, its time to showcase the app that I made with them.

In my spare time I like to watch Twitch streams, moderate them (shoutout to BradWOTO), and write chatbots and other streamer tools for them. I won’t go into the chatbot too much, but the premise is simple: The bot watches a streamers chat for any commands, and if someone posted a command, the bot sends a reply, which is stored in a database. A command also has a clearance, meaning that some commands are moderator-only, or subscriber-only, and thus can only be used by moderators or subscribers.

And since my discovery of LitHTML I’ve been dying to get my hands on a hobby project to try it out. I’d recently finished this chatbot, and thought it would be a great exercise to write a fairly straight forward CRUD (Create/Read/Update/Delete) app to manage the commands for the bot. This means a couple things:

  • I’d need authentication/authorization, because we don’t want everyone to be able to delete all the commands.
  • I’d need an API/database connection to handle all the CRUD stuff. I used an SQL database since thats where the bots commands already were, but you could easily switch that out for Mongo.
  • I’d need some sort of state management. (Arguably I could’ve done this without Redux, but I figured it’d be good exercise to try it in combination with LitHTML)

I won’t explain the entire code in this story, but I will highlight a couple of interesting examples and tidbits. Lets start at the beginning.

Styling

One great feature that I stumbled upon is how we can use styles. Consider this example:

My colors are declared in a Colors.js file, and imported in Appstyles.js. I can now simply use ${ AppStyles } in any component I want them, and because only one AppStyles template object is ever made, and the expressions in the template are unlikely to change, this drives down the cost of rendering immensely, and allows for modularity.

Using external components

Using external webcomponents is super easy. Simply install with:

npm install --save @vaadin/vaadin-button

And import and use like so:

Easy peasy japanesey.

I fell absolutely in love with the Vaadin components, so huge shoutout to the Vaadin team. Their components are beautiful, accessible, and well documented.

(They also have an excellent router that create-lit-app uses for its routing)

Vaadin’s text-field and text-area components come with built in validation, which made them perfect to use in my app since, for example: every command needs to start with an exclamation mark.

Validating inputs is done with Regular Expressions, and looks like this:

Adding Redux

Redux is a great way to manage state, and is widely used by many different applications. Redux keeps the entire state of your application in one single, immutable object that is called the store. When values in your store change, your view/UI changes. This concept is often described as: UI = f(state)Explaining Redux in depth is out of scope for this story, but you can read all about Redux here, possibly the best kept docs I’ve ever read.

I use Redux for storing all my commands, keeping track of any errors from the API, and loading state. Also for opening modals, and search queries.

Since I use a couple of different operations on my command (Add/Delete/Update), I need a couple of different modals and validations. So when for example I click on my <edit-button>:

I dispatch an action to the store with a modalMode, ‘edit’ in this case, and as payload the command that I want to edit.

My modal structure looks like this:

Another great feature of Redux is time travel debugging. You can probably guess how the view of my application changed because of these actions:

If you’re interested in adding Redux to your lit project, you can read the polymer-pwa-starter section on Redux, or if you want a quick, easy example head over to create-lit-app.

Directives

Another cool thing that comes with LitHTML are directives. Directives are functions that can extend lit-html by directly interacting with the Part API.

One great example of a directive is the until directive, which looks like this:

So until the promise is resolved, it’s going to show “Loading…”.

The directive I used is the UnsafeHTML directive. In Twitch chatrooms you can use emotes, and are simply text, for example: Kappa, will render this emote in the chat:

Streamers can also have custom emotes, that you can use if you’re subscribed to them. For example: bradLOVE will render a heart emote, and can only be used by subscribers of BradWOTO.

I thought it’d be cool to not just display the text bradLOVE in the commands list, but instead display the actual image of the emote. This is where I ran into a problem, since simply replacing the text bradLOVE with an image tag will not work, and show up like this:

The way I managed to solve this is by using the UnsafeHTML directive, like this:

And it will output this:

Building/deploying with webpack

I used webpack for building my project, with major help from the incredibly helpful web-padawan and his polymer3-webpack-starter.

I struggled a lot setting up webpack, but the folks over at the polymer slack webpack channel are super helpful. Once I had webpack set up, and development was done, all I had to do was run webpack --env production, and my app was up and ready to go.

For deploying I used Heroku, a cloud application platform. Here’s a really helpful link for hosting a node app on heroku. Since webpack bundled all my code, all I had to do was serve my distribution folder with my express server like so:

And my app was up and running!

Wrapping up

Thats all for this blogpost, like I mentioned earlier, this is not really a tutorial, but rather a write up of my experience developing a lit app. If you want to get started developing a lit app yourself, please check out create-lit-app, as it has everything this app has set up for you and ready to go. (Redux/Webpack/Express API). I’d love to hear any feedback or suggestions.

Thanks for reading!

Originally published at gist.github.com.

--

--