{"id":15375953,"url":"https://github.com/thepassle/create-lit-app-advanced","last_synced_at":"2025-06-14T06:33:56.558Z","repository":{"id":98994481,"uuid":"149658642","full_name":"thepassle/create-lit-app-advanced","owner":"thepassle","description":"Create LitHTML apps with no build configuration. (LitHTML/Redux/Webpack/Express)","archived":false,"fork":false,"pushed_at":"2018-12-02T11:45:13.000Z","size":574,"stargazers_count":25,"open_issues_count":2,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-16T20:03:06.064Z","etag":null,"topics":["lit-html","litelement","polymer","redux","starter","webpack"],"latest_commit_sha":null,"homepage":"https://create-lit-app.herokuapp.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thepassle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-09-20T19:18:11.000Z","updated_at":"2022-04-06T15:45:50.000Z","dependencies_parsed_at":"2023-03-13T15:53:23.644Z","dependency_job_id":null,"html_url":"https://github.com/thepassle/create-lit-app-advanced","commit_stats":{"total_commits":22,"total_committers":1,"mean_commits":22.0,"dds":0.0,"last_synced_commit":"fce0ae0319f78861316d02c2a17a69bb39b70c49"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thepassle/create-lit-app-advanced","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcreate-lit-app-advanced","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcreate-lit-app-advanced/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcreate-lit-app-advanced/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcreate-lit-app-advanced/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thepassle","download_url":"https://codeload.github.com/thepassle/create-lit-app-advanced/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcreate-lit-app-advanced/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259774597,"owners_count":22909163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lit-html","litelement","polymer","redux","starter","webpack"],"created_at":"2024-10-01T14:05:23.187Z","updated_at":"2025-06-14T06:33:56.536Z","avatar_url":"https://github.com/thepassle.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e ## 🛠 Status: In Development\n\u003e LitElement is currently in development. As long as LitElement is, so is create-lit-app. This repo will be kept up to date with the latest version of LitElement, but there are things that haven't been finalized yet and you can expect some changes.\n\n\u003cbr\u003e\n\n## Create-lit-app\n\n[![Built with create-lit-app](https://img.shields.io/badge/built%20with-create--lit--app-blue.svg)](https://github.com/thepassle/create-lit-app) [![Build Status](https://travis-ci.org/thepassle/create-lit-app-advanced.svg?branch=master)](https://travis-ci.org/thepassle/create-lit-app-advanced) [![Mentioned in Awesome lit-html\u003e](https://awesome.re/mentioned-badge.svg)](https://github.com/web-padawan/awesome-lit-html)\n\n![Lit App Screenshot](https://i.imgur.com/3RtTwbi.jpg)\n\nDemo:\nhttps://create-lit-app.herokuapp.com/\n\n[Create-lit-app on Stackblitz](https://stackblitz.com/edit/create-lit-app)\n\n## Get Started Immediately\n\n![Lit Cli](http://thepassle.nl/SGTEST/cla.gif)\n\nYou don’t need to install or configure tools like Webpack or Babel.\nThey are preconfigured so that you can focus on the code.\n\nClone/fork the [create-lit-app-advanced repo](https://www.github.com/thepassle/create-lit-app-advanced)\n or install the CLI if you want to get started quickly building a fullstack LitHTML app with:\n\n* Routing\n* Express api\n* Redux\n* Build with webpack\n\n\n## Table of Contents\n\n- [Quick start](#quickstart)\n  - [npm start](#npm-start)\n  - [npm test](#npm-test)\n  - [npm build](#npm-build)\n- [Folder Structure](#folder-structure)\n- [Redux](#redux)\n- [Routing](#routing)\n- [Decorators](#decorators)\n- [Adding an api](#adding-an-api)\n- [Usage](https://stackblitz.com/@thepassle)\n  - [Basic template](https://stackblitz.com/edit/create-lit-app-basic-template)\n  - [Passing props](https://stackblitz.com/edit/create-lit-app-passing-props)\n  - [Event handlers](https://stackblitz.com/edit/create-lit-app-event-handlers)\n  - [Conditional rendering](https://stackblitz.com/edit/create-lit-app-conditional-rendering)\n  - [Setting default values](https://stackblitz.com/edit/create-lit-app-default-values)\n  - [Arrays](https://stackblitz.com/edit/create-lit-app-arrays)\n  - [Updating arrays and objects](#updating-arrays-and-objects)\n  - [Attributes](https://stackblitz.com/edit/create-lit-app-updating-objects-arrays)\n  - [Reflecting props to attributes](https://stackblitz.com/edit/create-lit-app-reflect-to-attribute)\n  - [Adding styles](https://stackblitz.com/edit/create-lit-app-styles)\n  - [Querying dom](https://stackblitz.com/edit/create-lit-app-querying-dom)\n  - [Making api calls](https://stackblitz.com/edit/create-lit-app-making-api-calls)\n  - [Using directives](#using-directives)\n    - [until directive](https://stackblitz.com/edit/create-lit-app-directives-until)\n    - [unsafehtml directive](https://stackblitz.com/edit/create-lit-app-directives-unsafehtml)\n    - [classMap directive](https://stackblitz.com/edit/create-lit-app-directives-classmap)\n    - [styleMap directive](https://stackblitz.com/edit/create-lit-app-directives-stylemap)\n  - [Installing components](https://stackblitz.com/edit/create-lit-app-installing-components)\n  - [Upwards data flow](https://stackblitz.com/edit/create-lit-app-upwards-data)\n  - [Slotted components](https://stackblitz.com/edit/create-lit-app-slotted)\n  - [Light dom](https://stackblitz.com/edit/create-lit-app-light-dom)\n  - [Typescript](https://stackblitz.com/edit/create-lit-app-typescript)\n- [Lifecycle](#lifecycle)\n- [Cheatsheet](#cheatsheet)\n- [Polyfills](#polyfills)\n- [Installing a dependency](#installing-a-dependency)\n- [Testing your components](#testing-your-components)\n- [Add LitElement to a website](#add-litelement-to-a-website)\n- [Extensions](#extensions)\n- [Frequently asked questions](#frequently-asked-questions)\n  - [How does lit-html render?](#how-does-lit-html-render)\n  - [How does LitElement know when to rerender?](#how-does-litelement-know-when-to-rerender)\n  - [Why is my component not rerendering?](#why-is-my-component-not-rerendering)\n  - [Why are there empty html comments in my markup?](#why-are-there-empty-html-comments-in-my-markup)\n  - [Difference with VDOM?](#difference-with-vdom)\n  - [Whats the difference between map and repeat?](#whats-the-difference-between-map-and-repeat)\n  - [What is shadow dom?](#what-is-shadow-dom)\n  - [Accessibility and shadow dom?](#accessibility-and-shadow-dom)\n  - [Can I use x library?](#can-i-use-x-library)\n- [Browser support](#browser-support)\n- [Contributing](#contributing)\n- [Credits](#credits)\n- [Further reading](#further-reading)\n- [Acknowledgements](#acknowledgements)\n\n## Quickstart\n\n```sh\nnpm install --global create-lit-app\ncreate-lit-app my-app\n\ncd my-app\nnpm start\n```\n\n### npm start\n\nStart `webpack-dev-server` on localhost `http://127.0.0.1:3000`:\n\n```sh\nnpm run start\n```\n\n### npm test\n\nRun tests:\n\n```sh\nnpm run test\n```\n\n### npm build\n\nRun the production build:\n\n```sh\nnpm run build\nnode server.js\n```\n\nAs easy as that! Your app is ready to be deployed.\n\n## Folder Structure\n\nAfter creation, your project should look like this:\n\n```\ncreate-lit-app/\n  dist/\n  node_modules/\n  src/\n    assets/\n      favicon.ico\n      github.svg\n      logo.svg\n    hello-world.js\n    lit-app-styles.css\n    index.html\n    lit-app.js\n  test/\n    hello-world.html\n    index.html\n  .babelrc\n  .eslintignore\n  package-lock.json\n  package.json\n  README.md\n  server.js\n  webpack.config.js\n```\n\n## Redux\n\nCheck out the [create-lit-app-advanced repo](https://github.com/thepassle/create-lit-app-advanced) for a full example.\n\n## Routing\n\nCreate-lit-app-advanced uses [Vaadin Router](https://github.com/vaadin/vaadin-router) for its routing.\nCheck out the [create-lit-app-advanced repo](https://github.com/thepassle/create-lit-app-advanced) for a full example.\n\n## Decorators\n\nInstead of using the `static get properties()` way of setting properties, you may also use [decorators](https://github.com/tc39/proposal-decorators#decorators). Decorators require the following two babel plugins that live in your `.babelrc` file.\n\n`.babelrc`:\n\n```js\n[\n  \"@babel/plugin-proposal-decorators\",\n  { \"legacy\": true }\n],\n[\n  \"@babel/plugin-proposal-class-properties\",\n  { \"loose\": true }\n]\n```\n\nHere's an example on how to use decorators:\n\n```js\nimport { LitElement, html, property } from '@polymer/lit-element/';\n\nclass DemoElement extends LitElement {\n  \n  @property({type: String})\n  foo = 'bar';\n\n  render() {\n    return html`\n      \u003ch1\u003e${this.foo}\u003c/h1\u003e\n    `;\n  }\n}\n\ncustomElements.define('demo-element', DemoElement);\n```\n\n## Adding an api\n\nYou can edit the `server.js` file and start adding endpoints straight away. Add the following to the devServer section in `webpack.config.js`:\n\n```js\nproxy: {\n  '/api': {\n    target: 'http://localhost:8000/',\n    secure: false\n  },\n```\n\nCheck out the [create-lit-app-advanced repo](https://github.com/thepassle/create-lit-app-advanced) for a full example.\n\n## Usage\n\n- [Basic template](https://stackblitz.com/edit/create-lit-app-basic-template)\n- [Passing props](https://stackblitz.com/edit/create-lit-app-passing-props)\n- [Event handlers](https://stackblitz.com/edit/create-lit-app-event-handlers)\n- [Conditional rendering](https://stackblitz.com/edit/create-lit-app-conditional-rendering)\n- [Setting default values](https://stackblitz.com/edit/create-lit-app-default-values)\n- [Arrays](https://stackblitz.com/edit/create-lit-app-arrays)\n- [Updating arrays and objects](#updating-arrays-and-objects)\n- [Attributes](https://stackblitz.com/edit/create-lit-app-updating-objects-arrays)\n- [Reflecting props to attributes](https://stackblitz.com/edit/create-lit-app-reflect-to-attribute)\n- [Adding styles](https://stackblitz.com/edit/create-lit-app-styles)\n- [Querying dom](https://stackblitz.com/edit/create-lit-app-querying-dom)\n- [Making api calls](https://stackblitz.com/edit/create-lit-app-making-api-calls)\n- [Using directives](#using-directives)\n  - [until directive](https://stackblitz.com/edit/create-lit-app-directives-until)\n  - [unsafehtml directive](https://stackblitz.com/edit/create-lit-app-directives-unsafehtml)\n  - [classMap directive](https://stackblitz.com/edit/create-lit-app-directives-classmap)\n  - [styleMap directive](https://stackblitz.com/edit/create-lit-app-directives-stylemap)\n- [Installing components](https://stackblitz.com/edit/create-lit-app-installing-components)\n- [Upwards data flow](https://stackblitz.com/edit/create-lit-app-upwards-data)\n- [Slotted components](https://stackblitz.com/edit/create-lit-app-slotted)\n- [Light dom](https://stackblitz.com/edit/create-lit-app-light-dom)\n- [Typescript](https://stackblitz.com/edit/create-lit-app-typescript)\n\n## Lifecycle\n\n  * `render()` (protected): Implement to describe the element's DOM using `lit-html`. Ideally,\n  the `render` implementation is a [pure function](https://en.wikipedia.org/wiki/Pure_function) using only the element's current properties\n  to describe the element template. This is the only method that must be implemented by subclasses.\n  Note, since `render()` is called by `update()`, setting properties does not trigger\n  an update, allowing property values to be computed and validated.\n\n  * `shouldUpdate(changedProperties)` (protected): Implement to control if updating and rendering\n  should occur when property values change or `requestUpdate()` is called. The `changedProperties`\n  argument is a Map with keys for the changed properties pointing to their previous values.\n  By default, this method always returns `true`, but this can be customized as\n  an optimization to avoid updating work when changes occur, which should not be rendered.\n\n  * `update(changedProperties)` (protected): This method calls `render()` and then uses `lit-html`\n  in order to render the template DOM. It also updates any reflected attributes based on\n  property values. Setting properties inside this method will *not* trigger another update.\n\n  * `firstUpdated(changedProperties)`: (protected) Called after the element's DOM has been\n  updated the first time, immediately before `updated()` is called.\n  This method can be useful for capturing references to rendered static nodes that\n  must be directly acted upon, for example in `updated()`.\n  Setting properties inside this method will trigger the element to update.\n\n  * `updated(changedProperties)`: (protected) Called whenever the element's DOM has been\n  updated and rendered. Implement to perform post updating tasks via DOM APIs, for example,\n  focusing an element. Setting properties inside this method will trigger the element to update.\n\n  * `updateComplete`: Returns a Promise that resolves when the element has completed\n  updating. The Promise value is a boolean that is `true` if the element completed the\n  update without triggering another update. The Promise result is `false` if a\n  property was set inside `updated()`. This getter can be implemented to await additional state.\n  For example, it is sometimes useful to await a rendered element before fulfilling\n  this Promise. To do this, first await `super.updateComplete` then any subsequent state.\n\n  * `requestUpdate(name?, oldValue?)`: Call to request the element to asynchronously\n  update regardless of whether or not any property changes are pending. This should\n  be called when an element should update based on some state not triggered\n  by setting a property. In this case, pass no arguments. It should also be called\n  when manually implementing a property setter. In this case, pass the property\n  `name` and `oldValue` to ensure that any configured property options are honored.\n  Returns the `updateComplete` Promise which is resolved when the update completes.\n\n  * `createRenderRoot()` (protected): Implement to customize where the\n  element's template is rendered by returning an element into which to\n  render. By default this creates a shadowRoot for the element.\n  To render into the element's childNodes, return `this`. See an example [here](#light-dom)\n\nExample:\n\n![lifecycle](http://thepassle.nl/SGTEST/lifecycle.gif)\n\n`my-app.js`:\n\n```js\nimport { LitElement, html } from '@polymer/lit-element/';\n\nimport './lifecycle-demo.js';\n\nclass myApp extends LitElement {\n  static get properties() {\n    return {\n      showElement: { type: Boolean }\n    };\n  }\n\n  constructor() {\n    super();\n    this.showElement = true;\n  }\n\n  render() {\n    let { showElement } = this;\n\n    return html`\n      \u003c!-- \n      Removing the element from dom will trigger a `disconnectedCallback()` in `lifecycle-demo.js`,\n      adding it to dom will trigger a first `firstUpdated()` and a `updated()` in `lifecycle-demo.js` \n      --\u003e\n      \u003cbutton @click=${() =\u003e this.showElement = !this.showElement}\u003etoggle element\u003c/button\u003e\n\n      ${showElement \n        ? html`\u003clifecycle-demo\u003e\u003c/lifecycle-demo\u003e`\n        : ''\n      }\n    `;\n  }\n}\n\ncustomElements.define('my-app', myApp);\n```\n\n`lifecycle-demo.js`:\n\n```js\nimport { LitElement, html } from '@polymer/lit-element/';\n\nclass LifecycleDemo extends LitElement {\n  static get properties() {\n    return {\n      myArr: { type: Array }\n    };\n  }\n\n  constructor() {\n    super();\n    this.myArr = ['foo', 'bar'];\n  }\n\n  /**\n  * Called after the element's DOM has been updated the first time, immediately before updated() \n  * is called. This method can be useful for querying dom. Setting properties inside \n  * this method will trigger the element to update.\n  */\n  firstUpdated() {\n    console.log('first updated!');\n  }\n\n  /**\n  * Implement to perform post-updating tasks via DOM APIs, for example, focusing an element.\n  * Setting properties inside this method will *not* trigger another update.\n  */\n  updated(changedProps) {\n    super.updated(changedProps);\n    console.log('updated!');\n  }\n\n  /**\n  * Invoked each time the custom element is disconnected from the document's DOM.\n  * Useful for running clean up code.\n  */\n  disconnectedCallback() {\n    console.log('disconnected!');\n  }\n\n  _addItem() {\n    this.myArr = [...this.myArr, 'baz'];\n  }\n\n  render() {\n    let { myArr } = this;\n\n    return html`\n      \u003c!-- Adding an item will cause myArr to change, the property change will get picked up and trigger an update --\u003e\n      \u003cbutton @click=${this._addItem}\u003eadd item\u003c/button\u003e\n\n      ${myArr.map((item) =\u003e {\n        return html`\u003cli\u003e${item}\u003c/li\u003e`;\n      })}\n    `;\n  }\n}\n\ncustomElements.define('lifecycle-demo', LifecycleDemo);\n```\n\n## Cheatsheet\n\nText:\n\n```js\nhtml`\u003ch1\u003eHello ${name}\u003c/h1\u003e`\n```\n\nExpression:\n```js\nhtml`\u003cdiv\u003e${disabled ? 'Off' : 'On'}\u003c/div\u003e`\n```\n\nAttribute:\n```js\nhtml`\u003cdiv id=${id}\u003e\u003c/div\u003e`\n```\n\nBoolean Attribute:\n```js\nhtml`\u003cinput type=\"checkbox\" ?checked=${checked}\u003e`\n```\n\nProperty:\n```js\nhtml`\u003cinput .value=${value}\u003e`\n```\n\nEvent Handler:\n```js\nhtml`\u003cbutton @click=${(e) =\u003e console.log('clicked')}\u003eClick Me\u003c/button\u003e`\n```\n\n## Polyfills\n\nCreate-lit-app includes the following [polyfills](https://en.wikipedia.org/wiki/Polyfill):\n\n* [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise).\n\n* [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch).\n\n* [`Web Components`](https://github.com/webcomponents/webcomponentsjs) via [`webcomponentsjs`](https://github.com/webcomponents/webcomponentsjs). This loader performs client side feature detection and requests only needed polyfills. E.g., for IE11 it will load webcomponents-lite.js which includes full list of polyfills. But for Edge webcomponents-hi-ce-sd.js which contains polyfills for HTML Import, Custom Element and ShadowDOM.\n\n* [`custom-elements-es5-adapter.js`]() According to the spec, only ES6 classes (https://html.spec.whatwg.org/multipage/scripting.html#custom-element-conformance) may be passed to the native customElements.define API. For best performnace, ES6 should be served to browsers that support it, and ES5 code should be serve to those that don't. Since this may not always be possible, it may make sense to compile and serve ES5 to all browsers. However, if you do so, ES5-style custom element classes will now not work on browsers with native Custom Elements because ES5-style classes cannot properly extend ES6 classes, like HTMLElement. As a workaround, if your project has been compiled to ES5, load custom-elements-es5-adapter.js before defining Custom Elements. This adapter will automatically wrap ES5. *The adapter must NOT be compiled.*\n\n## Installing a Dependency\n\nYou may install other dependencies (for example, Axios) with `npm`:\n\n```sh\nnpm install --save axios\n```\n\nAlternatively you may use `yarn`:\n\n```sh\nyarn add axios\n```\n\nThis works for any library, not just `axios`.\n\n## Testing your components\n\nCreate-lit-app uses [karma](https://www.npmjs.com/package/karma) for testing. You can start the test runner with `npm test`, and edit test files in the `test/` folder. Here's an example of a test:\n\n`test/hello-world.spec.js`:\n\n```js\nimport { html, render } from 'lit-html';\nimport { expect } from 'chai';\n\nimport '../src/hello-world';\n\ndescribe('hello-world', () =\u003e {\n  let element;\n\n  const fixture = html`\n    \u003chello-world .greeting=${'Welcome'}\u003e\u003c/hello-world\u003e\n  `;\n\n  beforeEach(async () =\u003e {\n    render(fixture, document.body);\n    element = document.body.firstElementChild;\n    await element.updateComplete;\n  });\n\n  afterEach(() =\u003e {\n    element.remove();\n  });\n\n  it('should render a welcome message', () =\u003e {\n    const title = element.shadowRoot.querySelector('h1');\n    expect(title.innerText).to.equal('Welcome');\n  });\n});\n\n```\n\n## Add LitElement to a website\n\nIn this section, we will show how to add a LitElement component to an existing HTML page. You can follow along with your own website, or create an empty HTML file to practice.\n\nThere will be no complicated tools or install requirements — **to complete this section, you only need an internet connection, and a minute of your time.**\n\n```html\n\u003chtml\u003e\n\u003chead\u003e\n  \u003c!-- Polyfills only needed for Firefox and Edge. --\u003e\n  \u003cscript src=\"https://unpkg.com/@webcomponents/webcomponentsjs@next/webcomponents-loader.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003c!-- Works only on browsers that support Javascript modules like\n       Chrome, Safari, Firefox 60, Edge 17 --\u003e\n  \u003cscript type=\"module\"\u003e\n    import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element@latest/lit-element.js?module';\n    \n    class MyElement extends LitElement {\n\n      static get properties() { \n        return { \n          mood: { type: String }\n        }\n      }\n\n      render() {\n        const { mood } = this;\n        return html`\u003cstyle\u003e .mood { color: green; } \u003c/style\u003e\n          Web Components are \u003cspan class=\"mood\"\u003e${mood}\u003c/span\u003e!`;\n      }\n      \n    }\n\n    customElements.define('my-element', MyElement);\n  \u003c/script\u003e\n  \n  \u003cmy-element mood=\"great\"\u003e\u003c/my-element\u003e\n  \n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Extensions\n\nThese are some extensions made by the community on top of create-lit-app:\n\n* [create-lit-app-typescript](https://github.com/thepassle/create-lit-app/tree/typescript) - Get started with typescript.\n* [create-lit-app-advanced](https://github.com/thepassle/create-lit-app-advanced) - Get started with redux, routing, and an express API.\n* [create-lit-app-auth](https://github.com/sheideman/Create-Lit-App-Auth-Starter) - Get started with authentication using [jwt](https://jwt.io/), passportjs, and mongo. By [Steve Heideman](https://github.com/sheideman).\n\n\n## Frequently asked questions\n\n\n### How does lit-html render?\nLit-html lets you write HTML templates with JavaScript template literals and efficiently render and re-render those templates to DOM. Tagged template literals are a feature of ES6 that can span multiple lines, and contain javascript expressions. A tagged template literal could look something like this:\n\n```js\nconst planet = \"world\";\n\nhtml`hello ${planet}!`;\n```\n\nTagged template literals are just standard ES6 syntax. And these tags are actually just functions! Consider the following example:\n\n```js\nfunction customFunction(strings) {\n    console.log(strings); // [\"Hello universe!\"]\n}\n\ncustomFunction`Hello universe!`;\n```\n\nThey can also handle expressions:\n\n```js\nconst planet = \"world\";\n\nfunction customFunction(strings, ...values) {\n    console.log(strings); // [\"Hello \", \"! five times two equals \"]\n    console.log(values); // [\"world\", 10]\n}\n\ncustomFunction`Hello ${planet}! five times two equals ${ 5 * 2 }`;\n```\n\nAnd if we look in the [source code](https://github.com/Polymer/lit-html/blob/master/src/lit-html.ts) we can see that's exactly what lit-html does:\n\n```js\n/**\n * Interprets a template literal as an HTML template that can efficiently\n * render to and update a container.\n */\nexport const html = (strings: TemplateStringsArray, ...values: any[]) =\u003e\n    new TemplateResult(strings, values, 'html', defaultTemplateProcessor);\n```\n\nLit-html's `html` tag doesn't return dom, it returns an object representing the template, called a TemplateResult.\n\nA `\u003ctemplate\u003e` element is an inert fragment of DOM. Inside a `\u003ctemplate\u003e`, script don't run, images don't load, custom elements aren't upgraded, etc. `\u003ctemplate\u003e`s can be efficiently cloned. They're usually used to tell the HTML parser that a section of the document must not be instantiated when parsed, and will be managed by code at a later time, but it can also be created imperatively with createElement and innerHTML.\n\nLit-html creates HTML `\u003ctemplate\u003e` elements from the tagged template literals, and then clone's them to create new DOM.\n\nOn the initial render it clones the template, then walks it using the remembered placeholder positions, to create Part objects.\n\nA Part is a \"hole\" in the DOM where values can be injected. lit-html includes two type of parts by default: NodePart and AttributePart, which let you set text content and attribute values respectively. The Parts, container, and template they were created from are grouped together in an object called a TemplateInstance.\n\n### How does LitElement know when to rerender?\n\nLitElement reacts to changes in properties and rerenders your component if a value has changed. You can declare these properties in the properties getter:\n\n```js\nstatic get properties() {\n  return {\n    myBoolean: { type: Boolean }\n  }\n}\n\nconstructor() {\n  super();\n  this.myBoolean = false;\n}\n```\n\nSetting `this.myBoolean = true;` will trigger a rerender.\n\n### Why is my component not rerendering?\n\nDeep changes in objects or arrays are not observed and need to be immutably set or require you to manually call `this.requestUpdate()`. Consider the following example:\n\n```js\nimport { LitElement, html } from '@polymer/lit-element/';\n\nclass UpdatingDemo extends LitElement {\n  static get properties() {\n    return {\n      myObj: { type: Object }\n    };\n  }\n\n  constructor() {\n    super();\n    this.myObj = { id: 1, text: \"foo\" };\n  }\n\n  _updateObj() {\n    // this.myObj.text = \"bar\"; This change will not get picked up and wont trigger a rerender. You can however call this.requestUpdate(); to manually cause the rerender.\n\n    this.myObj = {...this.myObj, text: \"bar\"}; // This change will get picked up and cause your component to rerender.\n  }\n\n  render() {\n    const { myObj } = this;\n    \n    return html`\n      \u003cdiv\u003e\n        ${myObj.text}\n        \u003cbutton @click=${this._updateObj}\u003eUpdate\u003c/button\u003e\n      \u003c/div\u003e\n    `;\n  }\n}\n\ncustomElements.define('updating-demo', UpdatingDemo);\n```\n\n### Why are there empty html comments in my markup?\n\nLit-html uses them to keep track of its expression/parts locations, so it can update efficiently, consider the following example:\n\ncode:\n\n```js\nclass DemoEl extends LitElement {\n  static get properties() {\n    return {\n      myString: { type: String }\n    };\n  }\n  constructor(){\n    super();\n    this.myString = 'bar';\n  }\n\n  render() {\n    const { myString } = this;\n    return html`\n      \u003ch1\u003efoo\u003c/h1\u003e\n      \u003ch1\u003e${myString}\u003c/h1\u003e`; // will wrap `${myString}` with \u003c!---\u003e \n  }\n}\n```\n\noutput:\n\n```html\n\u003cdemo-el\u003e\n  #shadow-root (open)\n    \u003c!----\u003e\n    \u003ch1\u003efoo\u003c/h1\u003e\n    \u003ch1\u003e\n      \u003c!----\u003e\n      \"bar\"\n      \u003c!----\u003e\n    \u003c/h1\u003e\n    \u003c!----\u003e\n\u003c/demo-el\u003e\n```\n\n### Difference with VDOM?\nVDOM implementations keep a separate JavaScript structure representing the DOM structure in the browser. For all the changes to the structure the VDOM implementation will perform a diffing operation and will perform updates to the DOM itself.\n\nWhile this method is effective, it does mean a lot of excessive processing is done. Lit-html leverages the ECMAScript ES6 tagged template literals feature to use native browser rendering engine implementations to perform the same task. \n\n### Whats the difference between map and repeat?\n\nIf you expect to the order of elements to change (swapping position of elements, deleting elements within the array) use `repeat`. If your array length never changes, or if you only append to to it use `map`.\nIf you have an array `[a,b,c]`, `map` will render 3 nodes. When when you change the array to `[b,a,c]` the dom nodes stay in the same position but the data passed to the nodes changes\n\nWhile `repeat` will swap the nodes along with the data. this can be very useful if you modify dom nodes which isn't expressed in any of your data.\n\nTL;DR use map for very small lists and very small templates. Iterating over a small hardcoded list of options to build a form for example.\n\n### What is shadow dom?\n\nRead [this post](https://blog.revillweb.com/open-vs-closed-shadow-dom-9f3d7427d1af) by [Leon Revill](https://twitter.com/revillweb) on shadow dom and the difference between the `open` and `closed` modes.\n\n### Accessibility and shadow dom?\nScreenreaders have no difficulty with piercing shadow dom. From the Polymer FAQ:\n\n\u003e “A common misconception is that the Shadow DOM doesn’t play nicely with assistive technologies. The reality is that the Shadow DOM can in fact be traversed and any node with Shadow DOM has a shadowRoot property which points to its shadow document. Most assistive technologies hook directly into the browser’s rendering tree, so they just see the fully composed tree.”\n\n### Can I use x library?\nLots of libraries using global API like document.querySelector and relying on global CSS would be broken by Shadow DOM. Libraries themselves should be updated to work with the new concepts, where possible. Webcomponents are still in early stages of adaptation, lots of libraries would actually make great webcomponents, so if you're interested in using one of your favourite libraries, please consider contributing.\n\nSome libraries could potentially still work by querying the shadowroot of an element.\n\nRead more about it in [this](https://medium.com/dev-channel/dont-use-jquery-plugins-with-shadow-dom-e161f1891511) medium post by [Rob Dodson](https://twitter.com/rob_dodson)\n\n## Browser support\n\n| [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png\" alt=\"IE / Edge\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eIE / Edge | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\" alt=\"Firefox\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eFirefox | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\" alt=\"Chrome\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eChrome | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png\" alt=\"Safari\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eSafari | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari-ios/safari-ios_48x48.png\" alt=\"iOS Safari\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eiOS Safari | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png\" alt=\"Opera\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eOpera |\n| --------- | --------- | --------- | --------- | --------- | --------- |\n| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions\n\n## Contributing\n\nWe'd love to have your helping hand on create-lit-app! Feel free to create a pull request if you want to help out.\n\n## Credits\n\n### Helpful links:\n\n* [Awesome lit-html](https://github.com/web-padawan/awesome-lit-html)\n* [litHTML](https://github.com/Polymer/lit-html)\n* [Polymer slack](https://polymer.slack.com/)\n* [Vaadin Router](https://github.com/vaadin/vaadin-router)\n* [Polymer3-webpack-starter](https://github.com/web-padawan/polymer3-webpack-starter)\n* [Polymer PWA starter kit](https://github.com/Polymer/pwa-starter-kit)\n* [Redux](https://redux.js.org/introduction)\n\n## Acknowledgements\n\n* Owen Buckley of [Project Evergreen](https://projectevergreen.github.io/)\n* [Web-padawan](https://github.com/web-padawan)\n* [Lars den Bakker](https://github.com/LarsDenBakker)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepassle%2Fcreate-lit-app-advanced","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthepassle%2Fcreate-lit-app-advanced","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepassle%2Fcreate-lit-app-advanced/lists"}