Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?


Failed to load latest commit information.
Latest commit message
Commit time
March 16, 2023 16:25
March 16, 2023 15:33
March 13, 2023 17:28
March 13, 2023 17:28


Template is a simple JS framework for creating interactive applications.

It focuses on using web-native patterns.

Calling it a framework is a bit of an exaggeration, it's a single class that manages HTML <template>s.

The entire "framework" is here: ./template.js


Your Hello World example:

    <script src="./template.js"></script>
    <div id="app"></div>
    <template id="HelloWorld">
      <div class="hello-world">
        <h1 class="message"></h1>
      class HelloWorld extends Template {
        constructor() {
          // First argument is the id of the template
          // fragment contains the hydrated template
          // We can use it to query for child nodes, in this case: class="message"
          // Anything you want to update during runtime should be stored on "this"
          this.message = this.fragment.querySelector(".message");
        setMessage(msg) {
          // Update the content of <h1 class="message">
          this.message.innerText = msg;
      // Get the div we want to mount into
      const app = document.getElementById("app");
      // Create an instance of our HelloWorld component
      const helloworld = new HelloWorld();
      // Mount our component into the dom
      // Set our message
      helloworld.setMessage("Hello Template!");

Build process

You'll find that your index.html file grows pretty quick when using Template.

The fix is easy. First, create a directory called app.

Then create the files that make up our index.html "template":

For example:


<!DOCTYPE html>
    <script src="./template.js"></script>


    <div id="app"></div>





If you look at the files above, we've just split a standard index.html file up into chunks.

Now we use this little shell script to "build" our app by injecting our files:

cat ./app/pre-css.html > index.html
# Inject all of our CSS into the page
cat ./app/**/*.css > index.html
cat ./app/pre-template.html >> index.html
# Inject all of our HTML into the pa ge
cat ./app/**/*.html > index.html
cat ./app/pre-js.html >> index.html
# Inject all of our JS into the page
cat ./app/**/*.js >> index.html
cat ./app/post-js.html >> index.html

Now index.html contains your single page app!

You can now create folders for each component (and nested components) under the app directory.

For example, here is a file system with an Auth component that has two subcomponents Login and Signup:

├── Auth
│   ├── index.html
│   ├── index.js
│   ├── Login
│   │   ├── index.html
│   │   └── index.js
│   └── Signup
│       ├── index.html
│       └── index.js
├── post-js.html
├── pre-css.html
├── pre-js.html
└── pre-template.html

For some example components, checkout the ./examples directory.

Note: For CSS to work with the ShadowDOM Template uses, you'll need to include <style> tags inside the <template> tag of your component's index.html file. The page's CSS will not apply to nodes in the ShadowDOM tree. You can still style some global properties in a global CSS file if you choose, but this "quirk" of web components is why there are no index.css files in the file tree above.