Image for post

I’ve done it. I have done the thing that everyone tells you not to do as a developer directly following “don’t build your own cms (which I have also done)”. I built my own framework, Joist.

Over the past 2 or so years I have been been thinking about how I personally like to write applications and build components and couldn’t find anything that did EXACTLY what I wanted EXACTLY the way I wanted. So i built Joist, a framework that I want to use that I don’t mind if you want to use too :).

Some of the things I wanted:

  • dependency injection
  • opinionated state management
  • framework agnostic components (WebComponents)
  • view layer agnostic (You should be able to swap between no view library, lit-html and lighterhtml whenever you like.)

Getting Started

The easiest way to get started with Joist is by going to and just the Joist starter. is a an EXCELLENT site that lets you build and publish components with a variety of libraries. (Seriously even if you don’t care about Joist you should check it out.)

If you want to build an application you can use Create Snowpack App (CSP).

npx create-snowpack-app my-app --template @joist/starter-snowpack

This will set you up with a dev server, production builds via rollup and unit testing via web-test-runner.


Joist is view library agnostic but comes with built in support for lit-html and is what we will use for all of our examples. Now let’s look at what a Joist element looks like.

import { component, JoistElement } from '@joist/component';
import { template, html } from '@joist/component/lit-html';

  tagName: 'my-element',
  state: {
    title: 'Hello World'
  render: template(({ state }) => {
    return html`<h1>${state.title}</h1>`
class MyElement extends JoistElement {}

A Joist component is defined by extending the JoistElement base custom element and adding some component metadata. Metadata includes the tag name of the new element, the default state of the element and the render function. A joist render function is passed an object called RenderCtx.

Dependency Injection (DI)

At the heart of Joist is the dependency injector. The dependency injector itself is completely separate from the components and is in its own package. Each Joist component has its own injector that inherits from a single global injector. This allows Joist components to construct their own locally scoped services as well as share global singletons. Services decorated with the service decorator will be treated as singletons. Services can be injected into the constructor of other services via the inject decorator. Custom elements can inject services with the get decorator. The get decorator maps a service to a property onto any class that implements the InjectorBase interface. Here is an example of Microsoft’s FASTElement using the Joist injector.

#javascript #web-development #typescript #programming #joist

The easiest way to get started with Joist
1.40 GEEK