Build and deploy Open Source LWC components

In 2021 probably every Salesforce developer knows, how to deploy LWC components to the Salesforce platform. It is also a well known, that you can use the LWC framework outside Salesforce as well.

The documentation is pretty good, but without prior frontend development experience it can be a little bit challenging. So let’s see, how a standalone web app is created in LWC.


There is a handy tool to create a boilerplate LWC app:

npx create-lwc-app my-app-name

This creates and installs a project and creates 2 demo components. In order to see it in action, run npm run watch .

The source structure

In this scenario, I assume that we are creating a standalone, one-page LWC app. All your code lives under src/, by convention. Everything else in the project directory is just tooling.

├── index.html
├── index.js
├── modules
│ ├── jsconfig.json
│ └── my
│ └── toDo
│ ├── toDo.css
│ ├── toDo.html
│ └── toDo.js
└── resources
└── favicon.ico

As you see, the structure is very similar to the Salesforce file structure. All components live in their own directories undermodules, named by the component name; and all the .css, .html and .js files have the same names. There is one additional level: there is a so-called namespace: so my toDo component’s real name is my-to-do

The entry point for you app is index.html by convention — and you can serve from src/ other files as well. Static resources should be put under resources/ .

Appending root component to an HTML

So the entry point for your app is index.html , which is a totally normal .html file. In order to render a component inside it, you need to append the root LWC component somewhere into this file. That’s how you do this.

In your index.html, you create a div called main:

<div id="main"></div>

And also create index.js

import { createElement } from 'lwc';import ToDo from 'my/toDo';const td = createElement('to-do', { is: ToDo });document.querySelector('#main').appendChild(td);

The script creates an instance of your element (here: toDo under the my namespace) and inserts it into the #main div.

Note that you should not load the .js file in index.html — it will be added automatically when the project is built.

The build

At this point, if you load index.html from the /src directory, you won’t see anything. The javascript is not functional in this form, because the browser has no idea, how to resolve all the underlying dependencies. So you need to create the build. There is script for this: npm run build

If you look into package.json, you see that the following command is run, when you start build:

lwc-services build -m production

Lwc-services is a tooling library for lwc. With the build command, it does the following:

  • runs a bundler (webpack) in order to resolve dependencies and merge them into one file
  • appends all the needed .js to your index.html
  • copies everything into the /dist directory.

If you load now /dist/index.html , your app will work as intended. Note that you have only one .js file — all your component code, .css, templates and more is inside of it. You can also note that this .js is very ugly — because its minified.

Serve and Watch

Making a build every time you changed something in your components is boring. So there is watch mode: npm run watch . This will start a local webserver, and rebuild you app every time you saved a change in files.

The npm run serve script does a very similar thing: runs a webserver which serves the /dist . However, this does not re-build every time you save a file.

I also recommend to look into package.js and see, what other npm scripts are included.

Sum it up — the OSS LWC development process

The easiest way to create a LWC project is the following:

  • use the create-lwc-app tool, in order to create a boilerplate.
  • write your components and your root .html in the /src directory
  • create builds or run the watch script

And you are good. It is important that you never commit your dist/ into your repo, because its only an ephemeral representation of your app — from the source you can create a build anytime you want.

See a whole LWC project repo here: