I'm pleased to announce that I've officially released the w1c ecosystem of libraries to npm1!

It's still in pre-release but so far I've pulled out all the stops to bring this to life.

What?

It’s a web component2 library called W1C. More specifically, a nostalgic collection of distinctive, framework-agnostic UI components built with Lit, with docs, Storybook examples, and a CLI for scaffolding.

W1C Docs
Documentation for W1C, a retro web component library for modern pages.
https://w1c.desertthunder.dev

In the tiny w1c ecosystem, I've also provided some themes and access to the fonts. You can try out the typography in the docs site with the "Theme" dropdown. I think the System 7/Mac theme has the best typography.

Why?

At this point I don't remember what inspired me to start making goofy UIs in my web apps.

This was an opportunity for me to let other's experience what I've been feeling when making these goofy UIs. A little bit of joy and a reminder of what it felt like to use a computer for the first time.

  • Ibex is an interactive ATmosphere browser that looks like Ubuntu 8.

  • Tempest is a PDS that looks like windows 95

  • Notebird is a tiddlywiki style app that looks like old school twitter.

It also gave me a reason to dig deeper into unfamiliar tools like Storybook & Lit.

The whole concept of the indie web has been really fun to observe and I hope this helps folks dive in!

Plus aren't you tired of seeing large instrument serif headings and Geist in every UI?

How?

I got lit. Lit owns the entire implementation layer of the component library. The core pattern is that you subclass the LitElement class, add some properties and override the render method. You get these cool tagged literals/helpers for html & css.

import { LitElement, css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('w1c-button')
export class W1cButton extends LitElement {
   @property({ type: Boolean, reflect: true })
   disabled = false;

   render() {
     return html`
        <button ?disabled=${this.disabled}>
          <slot></slot>
        </button>
       `;
    }

   static styles = css`...`;
}

Then you take the component and augment the HTMLElementTagNameMap

declare global {
  interface HTMLElementTagNameMap {
    'w1c-button': W1cButton;
  }
}

so in this little example, W1cButton goes in your markup like so:

<w1c-button>OK</w1c-button>

I think that in the spirit of HTMX and Data Star, web components help you make your markup more powerful while also being flexible enough to work with your preferred toolchain (mine is Svelte and I put these in Svelte components for the docs).

There are also drag and drop utilities made in pure typescript that help make windows moveable.

And?

Documentation

The documentation is a static site built with SvelteKit & mdsvex so pages are defined as +page.md in their respective route directories. I had a lot of fun with this because it let me sandbox and test the "framework agnostic" claim I was making in my plans for the project right out of the gate. Svelte's state management is pretty nice and it gave me the chance to bake in my own QoL features like copying markdown of the page.

CLI

You can access all of the documentation through the cli! I don't really know why I added this but it seems like since there's all of those markdown documents there, why not let users access it from the command line?

Here's the truncated output of w1c docs components/window into stdout for example (if you install @w1c/cli globally):

Really, the main purpose of the CLI is to scaffold your project. It's built with clack by bomb.sh and, like the rest of the libraries & packages, typescript.

Stories

It's surprisingly not very intuitive to customize the feel of a Storybook but it is super easy to make Storybook useful. It can run your playwright tests (and mark components as passing or failing), and can really open the door for customization and experimentation. I'm really impressed with it and so late to the party.

You can view the stories here. There's a fun little showcase of Geocities style components that I don't want to spoil with a screenshot.

Changesets

I'd never really used changesets for version management and change tracking and I'm not sure why. I wrote a framework/language agnostic tool with Golang a while ago without really giving this a change. It's quite nice but I wouldn't call it essential. I like the human written changelog and this is like adding a "human readable"/"normie" commit message. Maybe I'm using it wrong but I've really only used it seriously in two projects.


Thanks for reading! Checkout the packages here and make something silly with it and host it on wisp.place!