Skip to content

Getting Started with LitElement and Tailwind

Getting Started with LitElement and Tailwind

By taking advantage of LitElement's thin layer over Web Components combined with Tailwind's near infinite offering of CSS utility classes, you can create a beautiful, completely custom, and incredibly performant data-driven user-interface with ease.

Tooling

We will be using a combination of tools to give us as great of a developer experience as possible, as quickly as possible.

  • RollupJS - Rollup's approach to module bundling relies on the native JavaScript module standard, ES Modules, as opposed to Node's CommonJS module system.
  • Babel - Babel will allow us to use the latest JavaScript features by compiling down our code to ES5, something older browsers will understand.
  • TypeScript - Better to have silly errors during development than insanity-inducing errors in production. TypeScript's got our backs by reducing the bugs (accidental features?) we introduce in our code.
  • ESLint
  • Prettier

Installing RollupJS and initial configuration

Rollup has an excellent starter-app template that we can use to get going quickly. Clone their repo and we'll use that as our starting point.

Create/Edit/Remove these files:

  • LICENSE - This is just a prototype, so we don't need this file.
  • README.md - Again, this is just a prototype, so we don't need this either.
  • src/update.js - We can remove this.
  • public/index.html - We can remove the <h1> and the <p> tags. We'll start fresh.
  • package.json - Remove the date-fns dependency.
  • src/main.js - Update it so it has a single command to test our config, console.log('Hello, World!')

After that's done, let's test our initial Rollup setup:

  1. yarn install or npm install to install our dependencies
  2. yarn dev or npm dev to run our development environment
  3. Navigate to localhost:5000
  4. Open dev-tools to see our test message
Logging Hello, World!

Configuring Babel & TypeScript

To configure Babel and TypeScript, we'll take advantage of Rollup's Babel plugin, and we'll configure babel to compile our TypeScript code.

Install the following dependencies:

  • @babel/core
  • @rollup/plugin-babel
  • @babel/preset-env
  • typescript
  • @rollup/plugin-typescript
  • @babel/preset-typescript

Edit the following files:

  • src/main.js rename to src/main.ts
  • rollup.config.js

Import and use the Babel plugin, and set the input file as a .ts file (for TypeScript).

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
import typescript from '@rollup/plugin-typescript';
import { babel } from '@rollup/plugin-babel'

// `npm run build` -> `production` is true
// `npm run dev` -> `production` is false
const production = !process.env.ROLLUP_WATCH;

export default {
  input: 'src/main.ts',
  output: {
    file: 'public/bundle.js',
    format: 'es',
    sourcemap: true
  },
  plugins: [
    resolve(),
    commonjs(),
    typescript({
      include: ['src/**/*.ts']
    }),
    babel({
      babelHelpers: 'bundled',
      exclude: "node_modules/**"
    }),
    production && terser({ format: { comments: false } }), // minify, but only  in production
 ]
};
  • .babelrc - Create and setup Babel configuration file to compile down to a minimum of ES5 code.
{
  "presets": ["@babel/preset-env"]
}
  • tsconfig/json - Create the TypeScript configuration file with the command yarn tsc --init

Configuring ESLint and Prettier

Install the following dependencies:

  • eslint
  • prettier
  • eslint-config-prettier
  • eslint-plugin-prettier

Run yarn eslint --init and choose the following options to create .eslintrc.js, ESLint's config file.

  • enforce code style
  • JavaScript modules
  • No Framework
  • TypeScript
  • Project runs in the browser
  • Use Airbnb style guide
  • config format JavaScript

After this, we can see that our IDE (in my scenario, VS Code) recognizes the ESLint configuration and is throwing some issues my way.

ESLint Errors

In .eslintrc.js

  • Add 'plugin:prettier/recommended' to the extends array
  • Add 'prettier' to the plugins array
  • Add "prettier/prettier": "error" to the rules object

Create and configure .prettierrc, Prettier's configuration file. This single line is for any Window's developers, preventing any weird end-of-line prettier issues.

{
  "endOfLine": "auto"
}
ESLint

Using LitElement to make a data-driven User Interface

Now that we have a solid tooling setup, lets code up some UI with LitElement.

LitElement is a thin wrapper around Web Components. It provides us a way to declaratively write our UI as a function of state. A difference though between LitElement and another framework like React or Vue is that LitElement is built on top of the native component model of the web.

Let's code the obligatory 'Hello, World!'

First, install lit-element as a dependency to the project:

yarn add lit-element

To use a web component, we'll define it in src/main.ts, and then we'll use the new component in public/index.html.

src/main.ts

import { LitElement, customElement, html } from "lit-element";

@customElement("app-component")
export default class AppComponent extends LitElement {
  render() {
    return html` <h1>Hello, World!</h1> `;
  }
}

public/index.html

<!doctype html>
<html>

<head lang='en'>
  <meta charset='utf-8'>
  <meta name='viewport' content='width=device-width'>
  <title>LitElement w/ Tailwind</title>

  <style>
    body {
      font-family: 'Helvetica Neue', Arial, sans-serif;
      color: #333;
      font-weight: 300;
    }
  </style>
</head>

<body>
  <app-component></app-component>
  <script type="module" src='bundle.js'></script>
</body>

</html>

You'll most likely run into several ESLint and TypeScript issues. A few to be wary of are:

  • TypeScript Decorators: The line with @customElement() is a TypeScript feature called a decorator. In order to use them, you have to explicitly turn the feature in in your tsconfig.json.
  • Expected 'this' to be used by class method 'render': This is an ESLint rule noticing that we aren't using this in the instance method render(). We can tell ESLint to ignore specific functions by adding a rule to our eslintrc.js

After resolving any linting issues you may have, you should have your Hello, World!

Hello, World w/ LitElement

Styling components with Tailwind

Now we are going to add Tailwind to our project.

Install the following dependencies:

  • rollup-plugin-postcss
  • tailwindcss
  • postcss
  • autoprefixer

Run the following command to generate a Tailwind configuration file:

npx tailwindcss init

tailwindcss.config.js

module.exports = {
  purge: [
    './src/**/*.html',
    './src/**/*.js',
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

Create/Edit the following files:

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';
import typescript from '@rollup/plugin-typescript';
import { babel } from '@rollup/plugin-babel'
import postcss from 'rollup-plugin-postcss' // import postcss plugin

const production = !process.env.ROLLUP_WATCH;

export default {
  input: 'src/main.ts',
  output: {
    file: 'public/bundle.js',
    format: 'es',
    sourcemap: true
  },
  plugins: [
    resolve(),
    commonjs(),
    postcss(), // use postcss plugin
    typescript({
      include: ['src/**/*.ts']
    }),
    babel({
      babelHelpers: 'bundled',
      exclude: "node_modules/**"
    }),
    production && terser({ format: { comments: false } }),
  ]
};

postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}

src/styles.css

@tailwind base;
@tailwind components;
@tailwind utilities;

src/main.ts

import './styles.css' // import the tailwind styles
import { LitElement, customElement, html } from "lit-element";

@customElement("app-component")
export default class AppComponent extends LitElement {
  createRenderRoot() {
    return this; // turn off shadow dom to access external styles
  }
  render() {
    return html` <h1 class="mx-auto my-4 py-4 text-center shadow-lg text-xl w-1/2">Hello, World!</h1> `; // use tailwind css utility classes
  }
}

After our configuration, we now have a working LitElement & Tailwind setup!

Styled with Tailwind

Conclusion

After our configuration, we now have a strong base to start creating a beautiful data-driven user interface with powered by both LitElement and Tailwind CSS.

This Dot Labs is a development consultancy that is trusted by top industry companies, including Stripe, Xero, Wikimedia, Docusign, and Twilio. This Dot takes a hands-on approach by providing tailored development strategies to help you approach your most pressing challenges with clarity and confidence. Whether it's bridging the gap between business and technology or modernizing legacy systems, you’ll find a breadth of experience and knowledge you need. Check out how This Dot Labs can empower your tech journey.

You might also like

Bun v1.0 cover image

Bun v1.0

On September 8, 2023, Bun version 1 was released as the first production-ready version of Bun, a fast, all-in-one toolkit for running, building, testing, and debugging JavaScript and TypeScript. Why a new JS runtime You may ask, we already have Node and Deno, so why would we need another javascript runtime, Well yes we had Node for a very long time, but developers face a lot of problems with it, and maybe the first problem is because it’s there for a very long time, it has been changing a lot between different versions and one of the biggest nightmares for JavaScript developers these days is upgrading the node version. Also, Node lacks support for Typescriptt. Zig programming language One of the main reasons that Bun is faster than Node, is the programming language it has been built with which is Zig. Zig is a very fast programming language, even faster than C) (here is some benchmarks), it focuses on performance and memory control. The reasons it’s faster than C is because of the LLVM optimizations it has, and also the way it handles the undefined behavior under the hood Developer Experience Bun delivers a better developer experience than Node on many levels. First, it’s almost fully compatible with Node so you can use Node packages without any issues. Also, you don’t need to worry about JS Common and ES Modules anymore, you can use both in the same file, yup you read that right, for example: `js import { useState } from 'react'; const React = require('react'); ` Also, it has a built-in test framework similar to Jest or Vitest in the project so no need to install a different test framework with different bundler in the same project like Webpack or Vite `js import { describe, expect, test, beforeAll } from "bun:test"; ` Also, it supports JSX out-of-the-box `bash bun index.tsx ` Also, Bun has the fastest javascript package manager and the most efficient you can find as of the time of this post `bash bun install ` Bun Native APIs Bun supports the Node APIs but also they have fun and easy APIs to work with like `Bun.serve()` : to create HTTP server `Bun.file()` : to read and write the file system `Bun. password.hash()`: to hash passwords `Bun.build()`: to bundle files for the browser `Bun.FileSystemRouter()`: a file system router And many more features Plugin system Bun also has an amazing plugin system that allows developers to create their own plugins and add them to the Bun ecosystem. `js import { plugin, type BunPlugin } from "bun"; const myPlugin: BunPlugin = { name: "Custom loader", setup(build) { // implementation }, }; ` Conclusion Bun is a very promising project, and it’s still in the early stages, but it has a lot of potential to be the next big thing in the JavaScript world. It’s fast, easy to use, and has a lot of amazing features. I’m very excited to see what the future holds for Bun and I’m sure it will be a very successful project....

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools cover image

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools

In the ever-evolving world of web development, Nuxt.js has taken a monumental leap with the launch of Nuxt DevTools v1.0. More than just a set of tools, it's a game-changer—a faithful companion for developers. This groundbreaking release, available for all Nuxt projects and being defaulted from Nuxt v3.8 onwards, marks the beginning of a new era in developer tools. It's designed to simplify our development journey, offering unparalleled transparency, performance, and ease of use. Join me as we explore how Nuxt DevTools v1.0 is set to revolutionize our workflow, making development faster and more efficient than ever. What makes Nuxt DevTools so unique? Alright, let's start delving into the features that make this tool so amazing and unique. There are a lot, so buckle up! In-App DevTools The first thing that caught my attention is that breaking away from traditional browser extensions, Nuxt DevTools v1.0 is seamlessly integrated within your Nuxt app. This ensures universal compatibility across browsers and devices, offering a more stable and consistent development experience. This setup also means the tools are readily available in the app, making your work more efficient. It's a smart move from the usual browser extensions, making it a notable highlight. To use it you just need to press Shift + Option + D` (macOS) or `Shift + Alt + D` (Windows): With simple keystrokes, the Nuxt DevTools v1.0 springs to life directly within your app, ready for action. This integration eliminates the need to toggle between windows or panels, keeping your workflow streamlined and focused. The tools are not only easily accessible but also intelligently designed to enhance your productivity. Pages, Components, and Componsables View The Pages, Components, and Composables View in Nuxt DevTools v1.0 are a clear roadmap for your app. They help you understand how your app is built by simply showing its structure. It's like having a map that makes sense of your app's layout, making the complex parts of your code easier to understand. This is really helpful for new developers learning about the app and experienced developers working on big projects. Pages View lists all your app's pages, making it easier to move around and see how your site is structured. What's impressive is the live update capability. As you explore the DevTools, you can see the changes happening in real-time, giving you instant feedback on your app's behavior. Components View is like a detailed map of all the parts (components) your app uses, showing you how they connect and depend on each other. This helps you keep everything organized, especially in big projects. You can inspect components, change layouts, see their references, and filter them. By showcasing all the auto-imported composables, Nuxt DevTools provides a clear overview of the composables in use, including their source files. This feature brings much-needed clarity to managing composables within large projects. You can also see short descriptions and documentation links in some of them. Together, these features give you a clear picture of your app's layout and workings, simplifying navigation and management. Modules and Static Assets Management This aspect of the DevTools revolutionizes module management. It displays all registered modules, documentation, and repository links, making it easy to discover and install new modules from the community! This makes managing and expanding your app's capabilities more straightforward than ever. On the other hand, handling static assets like images and videos becomes a breeze. The tool allows you to preview and integrate these assets effortlessly within the DevTools environment. These features significantly enhance the ease and efficiency of managing your app's dynamic and static elements. The Runtime Config and Payload Editor The Runtime Config and Payload Editor in Nuxt DevTools make working with your app's settings and data straightforward. The Runtime Config lets you play with different configuration settings in real time, like adjusting settings on the fly and seeing the effects immediately. This is great for fine-tuning your app without guesswork. The Payload Editor is all about managing the data your app handles, especially data passed from server to client. It's like having a direct view and control over the data your app uses and displays. This tool is handy for seeing how changes in data impact your app, making it easier to understand and debug data-related issues. Open Graph Preview The Open Graph Preview in Nuxt DevTools is a feature I find incredibly handy and a real time-saver. It lets you see how your app will appear when shared on social media platforms. This tool is crucial for SEO and social media presence, as it previews the Open Graph tags (like images and descriptions) used when your app is shared. No more deploying first to check if everything looks right – you can now tweak and get instant feedback within the DevTools. This feature not only streamlines the process of optimizing for social media but also ensures your app makes the best possible first impression online. Timeline The Timeline feature in Nuxt DevTools is another standout tool. It lets you track when and how each part of your app (like composables) is called. This is different from typical performance tools because it focuses on the high-level aspects of your app, like navigation events and composable calls, giving you a more practical view of your app's operation. It's particularly useful for understanding the sequence and impact of events and actions in your app, making it easier to spot issues and optimize performance. This timeline view brings a new level of clarity to monitoring your app's behavior in real-time. Production Build Analyzer The Production Build Analyzer feature in Nuxt DevTools v1.0 is like a health check for your app. It looks at your app's final build and shows you how to make it better and faster. Think of it as a doctor for your app, pointing out areas that need improvement and helping you optimize performance. API Playground The API Playground in Nuxt DevTools v1.0 is like a sandbox where you can play and experiment with your app's APIs. It's a space where you can easily test and try out different things without affecting your main app. This makes it a great tool for trying out new ideas or checking how changes might work. Some other cool features Another amazing aspect of Nuxt DevTools is the embedded full-featured VS Code. It's like having your favorite code editor inside the DevTools, with all its powerful features and extensions. It's incredibly convenient for making quick edits or tweaks to your code. Then there's the Component Inspector. Think of it as your code's detective tool. It lets you easily pinpoint and understand which parts of your code are behind specific elements on your page. This makes identifying and editing components a breeze. And remember customization! Nuxt DevTools lets you tweak its UI to suit your style. This means you can set up the tools just how you like them, making your development environment more comfortable and tailored to your preferences. Conclusion In summary, Nuxt DevTools v1.0 marks a revolutionary step in web development, offering a comprehensive suite of features that elevate the entire development process. Features like live updates, easy navigation, and a user-friendly interface enrich the development experience. Each tool within Nuxt DevTools v1.0 is thoughtfully designed to simplify and enhance how developers build and manage their applications. In essence, Nuxt DevTools v1.0 is more than just a toolkit; it's a transformative companion for developers seeking to build high-quality web applications more efficiently and effectively. It represents the future of web development tools, setting new standards in developer experience and productivity....

GraphQL Updates- October 2021 cover image

GraphQL Updates- October 2021

State of GraphQL State of GraphQL brings together core contributors, members of the GraphQL Foundation, and community leaders to talk about the future of GraphQL, and answer audience questions. Sponsors Shout-out to the sponsors of the event, StepZen and Moon Highway! - StepZen > One GraphQL API. All Your Data. Zero Infrastructure. StepZen is a GraphQL-as-a-Service provider, even including a FREE forever pricing tier with 300k calls/month included. - Moon Highway > The cutting edge JavaScript training for engineers of all skill levels Moon Highway is a training company that teaches a lot of courses centered around the JavaScript ecosystem. - JavaScript & Node - React - GraphQL Hosts - Tracy Lee, CEO, This Dot Labs - Eve Porcello, Co-founder & Instructor, Moon Highway Panelists - Uri Goldshtein, Founder, The Guild - Carlos Rufo, Engineering Lead, GraphCMS - Joey Nenni, Web Engineering Lead (GraphQL), PayPal - Janessa Garrow, Developer Experience Engineer, Apollo GraphQL - Tanmai Gopal, Founder, Hasura GraphQL Updates The first portion of the State of GraphQL covered updates from each panelist. The GraphQL Foundation One of the first topics covered by State of GraphQL was The GraphQL Foundation. > The GraphQL Foundation is a neutral foundation founded by global technology and application development companies. The GraphQL Foundation encourages contributions, stewardship, and a shared investment from a broad group in vendor-neutral events, documentation, tools, and support for GraphQL. > > GraphQL.org Uri opened up the conversation by emphasizing how open the foundation is. The GraphQL Foundation has always been open, but it's now easier than ever to become part of the community. The true "meat" of where the GraphQL action is though is in the GraphQL Working Group. There, topics such as changes to the GraphQL spec, ideas for new features, and more are discussed. Also, all the meetings are recorded and even summarized by text! Apollo Odyssey > Odyssey is Apollo's free interactive learning platform. Janessa from the Apollo team introduced us to Apollo Odyssey. Odyssey is Apollo's official learning platform. It was created to improve the developer experience of learning GraphQL. While some people may be able to learn effectively from docs, others may find different learning styles, like those offered by Odyssey, a more effective way of learning. Courses offered range from the basics, like what are queries and resolvers, to the more advanced subjects, such as Apollo Federation. Hasura Tanmai from Hasura spoke next about updates done within Hasura. One of the biggest new features is support for cross-database joins over GraphQL. This update allows the developer to retrieve data from any number of data stores with efficient queries. The next thing being worked on now is end-to-end streaming. PayPal Joey Nenni of PayPal spoke about PayPal's experience with adopting GraphQL. He mentioned that once PayPal supported developers with tooling and sample apps, GraphQL spread like wildfire. Seeing the potential to do more with GraphQL, especially with sharing components, PayPal looked into Apollo Federation about 9 months ago, and as of about 2 weeks ago, they are now live with millions of requests already going through their gateway. Joey also spoke about how GraphQL adoption is really about persistence. It's an iterative process. By making small steps, collecting small wins, and repeating that process, it becomes a lot easier to sell GraphQL. Joey coined the term "Guerilla Warfare" when it comes to finding successful implementations for GraphQL solutions. GraphCMS > GraphCMS gives you instant GraphQL Content APIs to create, enrich, unify, and deliver your content across platforms. GraphCMS recently hosted GraphQL Conf AND** has recently raised $10 million in a Series A funding round. With all of this GraphQL focused momentum, GraphCMS is poising itself as a powerful solution for Headless CMS. > The ultimate content platform that enables you to deliver applications at scale. > > Carlos Rufo Defer and Stream One important piece of information that Uri brought to the groups' attention was that defer, stream, live queries, and other features in spec proposals, but not in the actual spec, CAN BE USED SAFELY. Uri noticed a patter in production settings: once people have been given the option to use these new features, like defer, they see how valuable those features can be. If you want to see more information involving these GraphQL directives, you can check out a blog post covering them here. Apollo Federation > Implement a single graph across multiple services > > Apollo Documentation One very popular subject that is commonly brought up in Apollo conversations is Apollo Federation, and the idea of having a unified Graph connecting many services. For PayPal, they spoke about the experiences encountered while transitioning some of their shared logic to a federated graph, while maintaining developer experience. Apollo itself had a very positive experience using Apollo Federation. They ran into the need to unite two services, one written in Kotlin, and one in TypeScript, and have them run under a single gateway. This was a very big win and prevented the need for developers to learn additional languages to support a larger graph. Tanmai had a balanced perspective on Apollo Federation: > Are we federating how the API comes together and presents itself? Or are we federating the execution itself? He shared his experiences with analyzing where exactly a federated graph could be a good fit. For Uri, he spoke about how the most important question is, "Are we actually making the product development faster?" Adopting Apollo Federation may give a different answer depending on the team and work being done. Conclusion GraphQL is still growing rapidly, and as shown in this State of GraphQL, there is a growing thriving community surrounding it. Continue the conversation, no matter your experience level, and check out the GraphQL Working Group. While this was a quick summary of the things spoken about during the State of GraphQL, you can catch the whole video on YouTube. Thank you for enjoying the State of GraphQL!...

Being a CTO at Any Level: A Discussion with Kathy Keating, Co-Founder of CTO Levels cover image

Being a CTO at Any Level: A Discussion with Kathy Keating, Co-Founder of CTO Levels

In this episode of the engineering leadership series, Kathy Keating, co-founder of CTO Levels and CTO Advisor, shares her insights on the role of a CTO and the challenges they face. She begins by discussing her own journey as a technologist and her experience in technology leadership roles, including founding companies and having a recent exit. According to Kathy, the primary responsibility of a CTO is to deliver the technology that aligns with the company's business needs. However, she highlights a concerning statistic that 50% of CTOs have a tenure of less than two years, often due to a lack of understanding and mismatched expectations. She emphasizes the importance of building trust quickly in order to succeed in this role. One of the main challenges CTOs face is transitioning from being a technologist to a leader. Kathy stresses the significance of developing effective communication habits to bridge this gap. She suggests that CTOs create a playbook of best practices to enhance their communication skills and join communities of other CTOs to learn from their experiences. Matching the right CTO to the stage of a company is another crucial aspect discussed in the episode. Kathy explains that different stages of a company require different types of CTOs, and it is essential to find the right fit. To navigate these challenges, Kathy advises CTOs to build a support system of advisors and coaches who can provide guidance and help them overcome obstacles. Additionally, she encourages CTOs to be aware of their own preferences and strengths, as self-awareness can greatly contribute to their success. In conclusion, this podcast episode sheds light on the technical aspects of being a CTO and the challenges they face. Kathy Keating's insights provide valuable guidance for CTOs to build trust, develop effective communication habits, match their skills to the company's stage, and create a support system for their professional growth. By understanding these key technical aspects, CTOs can enhance their leadership skills and contribute to the success of their organizations....