I write, and sometimes rewrite, various libraries, and I’ve received the “too many libraries” complain more than once … but let me try to explain what’s behind my Open Source Software ideas.

Image for post
Image for post
Photo by Sonja Langford on Unsplash

Update

I’ve created a GitHub discussions repository, which is better than a forum, to hopefully simplify bootstrapping a tiny community around my projects.

As Independent Libraries Author

I try to read carefully trends on mailing lists and Twitter, where apparently everyone complains about JS’ fatigue, libraries size, bloated and slow Web, and all I think about, every single time, is the following:

I’m providing pretty much every popular pattern through modules that, once built for production, go from ~1K to max ~10K combined, and yet that’s not even nearly enough to convince developers, apparently looking for smaller libraries, to adopt or try these out.

Are my libraries too small?

Well, I’m a full time employee and most of my OSS contribution comes from evenings, weekends, or vacations, except when we have some obvious issue with either my custom elements polyfill, or HyperHTMLElement.

Luckily enough, that’s been the case only twice in the last 2+ years of usage, and those two gotchas have been solved within the same day, which is one of the main reasons I don’t usually publish “solve-it-all” software, ’cause time is not on my side:

  • it’s easier to test and fully cover smaller libraries, and make these super reliable for the single purpose they’ve been created for
  • it’s easier to maintain smaller libraries that, if the previous point worked well, don’t actually need much maintenance in the long term
  • it’s easier to orchestrate multiple micro-libraries together, to produce this or that pattern in the best possible way … so

When developers ask me “where is the create-react-app for this?” all I think is that I don’t always use the same structure to develop Web-stack based applications, and offering the best structure per each project, such as static only, lambda based, Service Worker, or Internet of Things, would take time.

The single “always same” thing I usually bootstrap is a rollup + (optionally) babel based structure to publish NodeJS dual modules, and it’s called modulestrap.

npx modulestrap --help

Yet this requires some manual adjustment, in case one needs more rollup plugins, or slightly different setup/outcome, but with this structure I’ve published pretty much everything with backward CommonJS compatibility, ESM, Web and/or NodeJS as target, etc … but that’s it, is a starting point to create anything we’d like to publish, or simply experiment with, maybe also the reason I publish too much, as it makes modules creation a no-brainer.

modulestrap, together with everything else I publish, is a brick to start small and incrementally put together everything else we might need as we go, but this is apparently under-appreciated, or less interesting than scaffolding 500MB of dependencies to have a hot-reloadable “Hello World” … anyway …

Is a community missing?

Various developers mentioned that they love my stuff but there’s no community around. Ironically enough, the hyperHTML #404 issue is about this: “community not found”.

Having a community is something developers seek for a reason, but in my personal experience, it never really worked:

  • they asked me to create a @cgjs org to help developers contributing to this (at this time old and deprecated) project and, since I’ve done that, not a single contribution happened. It took a lot of time to put together all the modules in a monorepo structure, be sure everything would work, anyone could contribute and … crickets.
  • the @ungap org has 1 maintainer: me. Some of its polyfills is being used in @babel/core but this “should be an org” concept failed again.
  • they asked me to put a hyperhtml tag in Stack Overflow and yet they kept filing issues asking for help instead of using Stack Overflow, so that knowledge, issues, or solutions, were confined in the project’s repository, instead of becoming something to talk about in there.
  • they complained about hyperHTML lack of documentation, and it’s been literally one of the first link on top of the README. Mostly nobody read it, even if linked also in other similar libraries of mine, but I’ve got the “where’s the doc” complain. Don’t get me wrong, the documentation is nearly as good as the other libraries documentation you can find out there, but it’s surely better than the one I’ve provided for other projects, but then again, I was 100% focused on my Open Source projects at that time, while today I don’t have much time in general, and yet I document as I can in each README and, guess what, … most devs don’t read that neither.
  • I’ve ultimately tried to create boards around my libraries, but beside being a forum not super exciting 2020 “new community” format, not much is happening … should I twitter more with real examples? Should I post stuff in there and be a community by myself? I don’t know … but whatever different thing I should do would require time.

On the other side, one of the obvious things that’s happening here, is that without proper marketing, it doesn’t matter if your project is an org, it has a community (it won’t ever have it without marketing), or it has some good documentation, if nobody talks about this or that library, it won’t basically happen.

I am not too good at marketing in general, but even if that was the case, marketing would’ve costed a lot of time:

  • create a dedicated account for this or that project
  • create a decent site with docs and examples
  • talk about the library or the pattern you’re trying to promote
  • tweet, share, repeat

Once again, during hyperHTML days I had the time to do all these things, yet I believe if a developer would like to experiment, or build something through one of my projects, there shouldn’t be a need for all this, if the word of mouth is still effective as I think … yet … crickets!

… and who should use my libraries, anyway?

I’ve been advocating Web Standards and minimal requirements forever and I try to provide lightweight and usually extremely fast alternatives that work well on KaiOS phones, as well as latest iPhone and, strawberry on top, my libraries cover most famous patterns through modules that, not only are small in size, require zero tooling around, and are as standard based as possible.

That means that, theoretically, any junior to senior developer could grab one library and build something, but here again I hear too often “which library should I use? … I’m confused”, beside me providing:

… and yet, developers are confused … but I think the issue is that, once again, nobody reads anything, unless is on everyone else mouth.

Most developers just don’t bother digging more, but surely enough, I should spend more time making my libraries scope and usage obvious … and once again, time “enters the scene”.

Worth also mentioning that, ideally, every developer would know the basics behind the library/framework they are choosing, but I start thinking nobody cares nearly enough, and this is hard to accept for me, as I rarely pick any software to develop anything, if I don’t know what’s going on behind … so that maybe, explaining what’s going on behind might help reducing this confusion … but I’m not too optimistic here neither …

Different Patterns

In a logical world, developers would take time to think about what they are trying to solve and what works best to solve that specific requirement.

Today, it looks like developers don’t bother thinking about requirements, they just grab something that does everything, and they usually choose patterns instead of the right tool for the job … so this section is about patterns covered by my most recent micro libraries, and I’ll try to clarify what could be confusing.

To start with, there are actually only 2 core libraries of mine that are somehow overlapping in terms of provided pattern:

The reason for such overlapping is that having less options around, allowed me to write less convoluted code, resulting in smaller bundles, faster execution, and best-in-class performance. Dropping lighterhtml extensibility and some beloved feature to become like uhtml makes no sense, and the same goes for augmentor which has way too many configuration things mostly nobody cares about, so that bumping major to remove features/options doesn’t look right … but that’s it: my micro-libraries are simply the most essential code I can think about, needed to provide the pattern they cover and not much else … but what are these patterns?

If you like React

µland is quite possibly the best tooling-free alternative out there. Being JSX free, you can’t express components through markup, but you can do it via callbacks and hooks:

import {Component, render, html, useState} from 'uland';

const Counter = Component((initialState) => {
const [count, setCount] = useState(initialState);
return html`
<button onclick=${() => setCount(count + 1)}>
Count: ${count}
</button>`;
});

// basic example, show two independent counters
render(document.body, () => html`
<div>
A bounce of counters.<hr>
${Counter(0)} ${Counter(1)}
</div>
`);

However, if you really want to write JSX like template literals, still without needing tools to have working code, kaboobie should satisfy that pattern.

Alternatively, you can try heresy out, which uses the transform ability provided by lighterhtml, and requires each component registration, although with name-clashing guards, for an even “closer to JSX” experience, but it’s worth saying heresy is a good choice mostly if paired with its SSR counterpart.

If you like React SSR

I know things are changing again in React world these days, but if you’d like to re-use same client-side components on the server, you can give µland-ssr a chance.

On the other side, heresy-ssr is based on basicHTML DOM emulation, which is completely different from template literals only solutions such as uland, so here again there are two patterns:

  • a static template literal based approach to create layouts only
  • a whole DOM world in the SSR, to do with components anything DOM could do, before creating layouts

If you like Vue.js or Svelte

One of the recent projects of mine I’ve spent time to create a decent documentation within its readme, is µce-template:

<template is="uce-template">
<style scoped>
span { color: green }
</style>

<the-green>
The <span>{{thing}}</span> is green
</the-green>

<script type="module">
export default {
setup() {
return {thing: 'world'}
}
}
</script>
</template>

In few words, uce-template is a 100% Custom Elements based library, which goal is to help defining portable components once, but usable everywhere, directly in the HTML.

Combined with µce-loader, it is possible to stream definitions, as these are found in the page, making uce-template an ideal static/server page companion for graceful, client-side, enhancement.

Of course tooling based alternatives such as Svelte might produce a slightly smaller outcome, but uce-template components are literally portable via copy and paste and usable as stand alone without tooling whatsoever.

If you like Hooks/Vue.js reactive

Previously mentioned, µhooks is my latest take at this pattern, and it works for both client, server, or Internet of Things projects.

It comes with various helpers too:

  • µhooks-fx to propagate once changes as done in µland
  • µhooks-nofx to actually do nothing except returning initial values, as done in µland-ssr
  • µhooks-dom to automatically attach effects to returned nodes, also used in µland

When it comes to reactive changes, compatible with hooks libraries, reactive-props is the one exported in µce-template too, and it can be integrated in any project … ’cause bear in mind, pretty much every library of mine work in what you have built already, there’s no lock in, neither explicit underlying requirement.

// create reactive elements
const body = reactiveElement(
document.body,
{test: ''},
() => console.log('body.test', body.test)
);

body.test; // ""
body.test = 'value'; // body.test "value"

Last, but not least, hookedElements, based on µhooks, is another graceful enhancement alternative that doesn’t need polyfills and all for ~2K, simulating Custom Elements features, but compatible with literally any DOM element live on the client.

If you like Custom Elements

…. but you don’t like classes verbosity, µce would be my go-to!

import {define} from 'uce';define('my-counter', {
init() {
this.count = 0;
this.dec = () => { this.count--; this.render(); };
this.inc = () => { this.count++; this.render(); };
this.render();
},
render() {
this.html`
<button onclick="${this.dec}">-</button>
<span>${this.count}</span>
<button onclick="${this.inc}">+</button>
`;
}
});

If you like “vanilla”

If you need a helper able to setup listeners, avoid XSS, simplify Custom Elements definition and content, µhtml is definitively something to try.

import {render, html, svg} from 'uhtml';
// const {render, html, svg} = require('uhtml');

render(document.body, html`<h1>Hello 👋 µhtml</h1>`);

It literally works with everything else I’ve mentioned so far, and like everything else it can be used already in any project of yours, either as graceful enhancement based “re-hydration”, or as SSR and/or Web Workers, thanks to its speedy and even lighter µhtml-ssr counter-part, which can also be swapped with the richer µcontent, able to minify CSS, HTML, and JS on the fly, requiring although various 3rd party libraries with it.

I’d personally start small with µhtml-ssr though, and switch to µcontent only if produced page size is not great, but with compressed outputs, that’s rarely something needed.

It is also worth underlying that µland-ssr works with Web Workers too, while µcontent targets only the NodeJS environment. See that? Different patterns/scenarios one more time, no overlap.

If you like tool-less development

I know talking about a CLI tool, in a tool-less section, makes little sense, yet these days we need to spin a server anyway, or nothing really works, right?

The only tool I use to test modules, libraries, and whatsoever, is called µcdn, which together with µcompress, is able to produce pure, native ESM based experience for debugging or production.

npx ucdn --help# debug pages and modules
# each refresh ensures no cache
npx ucdn --debug

The best feature of this CLI tool, is that code such as:

import {render, html} from 'uhtml';

will be automatically resolved so that every import will be a real ESM import.

Of course, once import-maps will be available, that’d be the best way to go, but until we are there, I find this CLI extremely simple and efficient for quick prototyping and more.

Consider µcdn like the local version of //unpkg.com/library?module, and only once you need to deploy live, consider usual bundlers or, why not, an export via µcontent.

If you like tool-based solutions

I’m afraid I haven’t much to offer, but many others do, and you can still integrate one or more “bricks” of mine, within these 3rd party tools.

Personal Conclusion

Probably the TR;DR I should’ve put on top, but I wanted to go through all my thoughts and feelings around this topic, and here’s my summary:

  • way too many new Web developers don’t learn HTML, CSS, and JS basics; they just start with something else they feel instantly productive with, or a must know tech to enter the market. I can’t blame them, but I also don’t understand how these developers believe they can succeed in the long term, but I wish they will, as being a developer is a constant learning experience, and it’s never too late to pick up the basics 👍
  • developers don’t care nearly enough about not using tools … and I guess I am old school here, but it’s really hard for me to imagine needing 500MB development dependencies to start a small to medium/big project
  • the market apparently doesn’t care much about people knowing the stack they work on, as long as they use “buzz-thingy” to show an “Hello World”. I come from different times, where you couldn’t find a job if you didn’t know the basics, but I’m nobody to change this trend and I’ll just acknowledge it.
  • if it’s not used, or promoted, by “Big Co” it’s not worth it. Here there’s literally nothing I can do about, except mentioning that some “Big Co” use one of my modules behind the scene, either as dependency or utility.
  • the “need for community” is half a myth: without marketing behind, nobody really cares about a community. They prefer copy/paste Stack Overflow solutions to crawl and they’ll rarely contribute to make the community around the topic, library, or project, better.
  • without time to dedicate to a variety of full-stack oriented projects, it’s hard to gain momentum and maybe start seeing a community around such projects … and time, for personal OSS projects, is never enough.
  • I won’t stop pushing forward the Web I dream about; I’ll keep experimenting my tool-less ideas, but I’ll also try to share more real-world / live examples, hoping this will help developers to better understand use cases they can solve through one of my dozen projects.

After all, there’s surely a lesson I’ve learned this year, so that 2021 will be the year I’ll push less on GitHub, but more on Twitter/Medium, and use the little extra time I have to improve the current documentation around my latest libraries, hoping to see, at the end of the next year, some adoption improvement.

If that won’t happen though, I might as well realize it’s not worth it to even try to provide alternatives, as nobody apparently cares much and, after all, those projects I’m “competing” with, are already very good at “solving-it-all”.

Happy New Year everyone 🥳

Web, Mobile, IoT, and all JS things since 00's. Formerly JS engineer at @nokia, @facebook, @twitter.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store