Getting started with LitElement and TypeScript

Aug 26, 2020 · 6 minutes read · [TypeScript] [WebComponents] [LitElement]

The use of powerful frameworks and libraries is very widespread nowadays. We can name Angular, React.js, Vue, Svelte, among with others.

It’s hard to imagine to build a web application without the use of any of those component-based frameworks. For these options, the components are reusable and configurable widgets, they are able to provide a custom behavior and styling, and they’re used as building blocks for the application.

Can we share a component between these frameworks? The short answer is no. Every framework/library has a custom API definition to build components and they are not interoperable with each other.

LitElement

According to the official LitElement website:

LitElement is a simple base class for creating fast, lightweight web components that work in any web page with any framework.

That means we can use the OOP paradigm using JavaScript or even better: TypeScript. Let’s explain it with the following examples.

LitElement and JavaScript

To create your first custom Web Component using JavaScript, you’ll need to define a class that implements the appearance and functionality as follows:

import { LitElement, html } from 'lit-element';

class HelloComponent extends LitElement {
  static get properties() { // JavaScript way to define custom properties
    return { name: { type: String } };
  }

  constructor() {
    super();
    this.name = 'Luis'; // Default value goes here.
  }
  
  render() { // Defines a template to be "rendered" as part of the component.
    return html`Hello ${this.name}. Welcome to LitElement!`;
  }
}

// Register as a custom element named <hello-component>
customElements.define('hello-component', MyElement);

LitElement and TypeScript

You can use the power of TypeScript instead, just need to import some decorators to write your first Web Component as follows:

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

@customElement('hello-component') //Decorator that register as a custom element named <hello-component>
export class HelloComponent extends LitElement {
  @property({type: String}) name = 'Luis'; // You can assign the default value here.

  render() { // Defines a template to be "rendered" as part of the component.
    return html`Hello, ${this.name}. Welcome to LitElement!</p>`;
  }
}

There’s a new component for your project, you can use it in your template files as if it were a new member of the HTML vocabulary:

  <hello-component></hello-component>
  <hello-component name="George"></hello-component>

Wanna play with the latest example? Just open the Stackblitz editor:

LitElement will help you to build your Web Components to be easily shared within your company or organization, even if you are working with different JavaScript frameworks.

Creating Your First Project

So now you’re thinking about to start a project and use LitElement to build your web application based on Web Components. That’s great!

It’s totally true that you can start a project from scratch:

  • You’ll need to install LitElement using npm i lit-element
  • Then, install TypeScript with npm i typescript
  • What about creating the tsconfig.json file?
  • Any build system you want to add and configure?
  • Now you’ll need to add ESlint and Prettier and follow best practices
  • Continue adding the Unit testing support and Karma
  • You get the point…

Project Scaffolding

You got covered by a project generator from the open-wc initiative, and you can create your first project with TypeScript support and common tooling in just few seconds:

Run the open-wc project generator:

npm init @open-wc
# Select "Scaffold a new project" (What would you like to do today?)
# Select "Application" (What would you like to scaffold?)
# Mark/Select "Linting", "Testing", "Demoing" and "Building" (What would you like to add?)
# Yes (Would you like to use TypeScript?)
# Mark/Select "Testing", "Demoing" and "Building" (Would you like to scaffold examples files for?)
# my-project (What is the tag name of your application/web component?)
# Yes (Do you want to write this file structure to disk?)
# Yes, with npm (Do you want to install dependencies?)

You’ll have this output:

luixaviles my-project$npm init @open-wc
npx: installed 30 in 1.643s

        _.,,,,,,,,,._
     .d''           ``b.       Open Web Components Recommendations
   .p'      Open       `q.
 .d'    Web Components  `b.    Start or upgrade your web component project with
 .d'                     `b.   ease. All our recommendations at your fingertips.
 ::   .................   ::
 `p.                     .q'   See more details at https://open-wc.org/init/
  `p.    open-wc.org    .q'
   `b.     @openWc     .d'
     `q..            ..,'      Note: you can exit any time with Ctrl+C or Esc
        '',,,,,,,,,,''


✔ What would you like to do today? › Scaffold a new project
✔ What would you like to scaffold? › Application
✔ What would you like to add? › Linting (eslint & prettier), Testing (karma), Demoing (storybook), Building (rollup)
✔ Would you like to use typescript? › Yes
✔ Would you like to scaffold examples files for? › Testing (karma), Demoing (storybook), Building (rollup)
✔ What is the tag name of your application/web component? … my-project

The next project structure will be generated:

./
├── my-project/
│   ├── .storybook/
│   │   ├── main.js
│   │   └── preview.js
│   ├── src/
│   │   ├── my-project.ts
│   │   ├── MyProject.ts
│   │   └── open-wc-logo.ts
│   ├── stories/
│   │   └── my-project.stories.ts
│   ├── test/
│   │   └── my-project.test.ts
│   ├── .editorconfig
│   ├── .eslintrc.js
│   ├── .gitignore
│   ├── custom-elements.json
│   ├── index.html
│   ├── karma.conf.js
│   ├── LICENSE
│   ├── package.json
│   ├── README.md
│   ├── rollup.config.js
│   └── tsconfig.json

This project has the support of many tools like lit-element, typescript, eslint, prettier, karma(Testing), storybook(Demoing) and rollup(Building)

Finally, run npm run start command to give a development preview of the application.

Extensions for Visual Studio Code

I found the following VS Code extensions very useful to build web components with TypeScript:

  • lit-html. This extension adds syntax highlighting and IntelliSense for html code inside of TypeScript tagged template strings.
  render() { 
    return html`Hello, ${this.name}. Welcome to LitElement!</p>`;
  }
  • LitElement Snippet. This extension provides LitElement code snippets to autogenerate a class with the @customElement() decorator, autogenerate properties, the render function and much more.

  • LitElement and Polymer v2/v3 Snippets. Alternatively to the previous one, you can install this extension that contains several JavaScript and HTML Snippets for LitElement and Polymer.

Conclusion

LitElement is an excellent alternative to build lightweight web applications since it’s based on the Web Components standard, with the addition of being compatible with any JavaScript-based framework or library. Of course, it’s feasible to use these components for building a SPA (Single Page Application) or even add the PWA (Progressive Web Application) capability.

With the help of TypeScript, we can see more possibilities to build Web Components faster with a good developer experience.


You can follow me on Twitter and GitHub to see more about my work.

tweet Share