Heavily inspired by the recent Vue 3 announcement, promises a very similar DX, also defeating most pain-points of the modern Web.

Some background

There are very few developers that fully understand the purpose and context of Web Components, and few others not super happy about the current state.

If we also consider the controversial history of the umbrella, where got removed, shipped in two different versions, and one browser vendor doesn’t want to fully comply with latest specs, plus the fact that partial updates are still nowhere, we can easily sympathize with the confusion and skepticism that surrounds this part of the standard Web, but let’s start clarifying a few things before continuing:

  • developers usually go “” with any technology, library, or framework, they choose, like “”. But here’s the catch: are not meant to replace everything we are doing, are instead something very easy to integrate within everything we’re doing already (). We still inevitably end up writing and to structure pages and views, after all, and there are just a portable <tag-name> that can be used like any other <tag> … it’s not that suddenly everything has to be a <custom-tag>, can we agree on this?
  • accessibility is likely the most underrated topic on the , but shipping inaccessible is exactly the same as shipping inaccessible layout that use <div class="button"> instead of <button>, forgets aria-x attributes, forgets focus area, keyboard navigation, and so on and so fort. And while provide a better mechanism to create accessible components out of the box, ’cause a <button> would work exactly like a <button is="custom-button">, yet if a button is used when a link would’ve been more appropriate, or vice-versa, we’re still shipping inaccessible, not user friendly, pages, nothing can help us. Accordingly, it’s our duty to grant great accessibility with every element we place on a page, and cannot take really any blame if we mess that part up.
  • requiring JS is inevitable, and there is no real-world use-case for “”, simply because that’s the only programming language we have there, and we should stop considering a second citizen of the . It’s actually a very first class citizen just like and : these technologies the , and there wouldn’t be any without , as there couldn’t be any web without or ( “” … bear with me …)

I am not saying a page cannot contain just , I am saying that every page will use too because that’s backed in the browser, since all native elements have their own styles anyway, and all native elements also have their listeners, DOM events, and reaction that are likely driven or, since is the only way we, developers, have to gracefully enhance anything, we gotta know at basics too. To summarize my thoughts around this topic: “” it’s the same as “”.

Simple and clear: you can have a great looking document with just and , but you can do that also with or any software that targets , but as soon as you need any dynamic behavior, you’re out of luck without .

That’s out of control anyway …

I hear you, and I agree, it’s been years articles regarding “” appear every second week, and if you check the amount of competing libraries and frameworks, and the list is not even entirely there, wait ‘till you learn most of those libraries and frameworks require tooling just to show a “”, which includes a whole new level of extra learning and friction.

But since I am also a bit nostalgic, and I miss that “” simplicity that made me love the in the first place, pretty much everything I publish in GitHub requires no tools and no transpilers to start getting some shit done!

Following the standards pattern, my libraries can also be incrementally integrated without requiring a complete rewrite of whatever is there already: static? dynamic? framework? library? No problems at all!

… well, I bring this philosophy with me daily:

And that’s how a new star in the universe was born!

The uce-template strength

With no strings attached, uce-template grants the following:

  • no tools/tooling needed, but tooling friendly, and with a single tool included in the package (it’s a lib a CLI optionally handy)
  • no polyfills needed: it’s a single script away that can be imported or included in the , and that’s literally it, the rest is
  • compatible with , , , , and
  • it’s just all inclusive, actually for modern browsers
  • cross-platform standalone components with or without or

Yes, that’s correct, neither or are strictly needed but there to help out without even needing to learn anything about at all.

<!-- multi times usage -->
<button is="rain-bow">
🦄 I am rainbow
</button>
<!-- definition -->
<template is="uce-template">
<button is="rain-bow"></button>
<style>
button[is="rain-bow"] {
font-weight: bold;
background-color: #91d370;
background-image: linear-gradient(
319deg, #91d370 0%, #bca0ff 37%, #f2cd54 100%
);
}
</style>
</template>
Image for post
Image for post
preview of the rainbow button

Incredibly simple, isn’t it? We can define within the current page, through standard tags, how our component would look like, and this is scratching only the surface of what’s possible with uce-template!

Components as .uce files

Being able to define components within a specific page is already cool, but to make our components really portable, how about having these in portable files that any could use, without repeating the definition all over?

After all, what we care about is just their definition, so that having it a part helps separating concerns, where the page is just the view, and components can land at any time if found in such page or not.

So here what our rain-bow.uce file would look like:

<button is="rain-bow"></button>
<style>
button[is="rain-bow"] {
font-weight: bold;
background-color: #91d370;
background-image: linear-gradient(
319deg, #91d370 0%, #bca0ff 37%, #f2cd54 100%
);
}
</style>

And in the examples section of the project, all instructions about how automatically load these components once any of them has been found in the current page, so here we have already:

  • zero JS needed, except a single script in the page
  • zero Custom Elements knowledge required
  • maximum freedom in defining components that even if the whole JS would break, won’t mess up with how the page should natively look and behave

And there’s more to it …

Scoped and Shadowed style

If instead of being a builtin extend, our component is just a regular element, it is possible to automatically prefix its style definition via the scoped attribute:

<my-unicorn></my-unicorn>
<style scoped>
button {
font-weight: bold;
background-color: #91d370;
background-image: linear-gradient(
319deg, #91d370 0%, #bca0ff 37%, #f2cd54 100%
);
}
</style>

The result is pretty much the same, except if there’s no button within the component, nothing will be styled. Please note no other button is affected.

As extra feature, style-wise, if the element has a shadow attribute in its definition, and the style also has a shadow property, the style will be injected on top of the component ShadowDOM root element, so that nothing around should affect its look, even worst obtrusive .

Enough with the part though, it’s time to reveal the “” this tiny library offers … ready?

The JS side

Listeners, reactive changes, validation, or data handling, once we add to the equation the potentials of each component become unimaginable, and here all it takes to add some listener to our component:

<my-unicorn>
You clicked me
<button onclick={{inc}}>
🦄 {{state.times}}
</button>
times
</my-unicorn>
<script type="module">
import {reactive} from '@uce';
export default {
setup() {
const state = reactive({ times: 0 });
const inc = () => state.times++;
return {inc, state};
}
};
</script>

And that’s pretty much it! As we can see in this live demo, to enrich some component with dynamic parts, all we have to do is to its own definition, where the setup method, if defined, can arbitrary return an that will be passed along to the component as is, and if such object has some reactive state, in this case with a times property that can be incremented via a click, the component layout will be automatically updated per each state change.

All dynamic parts can be confined within {{...}} brackets, and anything written in there will be just real , so that falling back to any value would be that simple:

<user-details>
User: {{user.name || 'anonymous'}}
Role: {{user.role || 'guest'}}
</user-details>

Math operations, callbacks, everything needed, really, can be written within those double brackets, but the simpler we keep it in there, the better, for layout clarity sake 😉

About the module system

Same way I’ve imported reactive from '@uce', we can define anything we need/like to import ahead of time and even asynchronously, so that no extra would ever be needed until one component is shown in the current, or future, visited page.

Please check again the to know more about dependencies.

The CLI / Command Line Interface

This time described in the , the uce-template --help would already show which option can be passed along:

uce-template v0.1.31
https://github.com/webreflection/uce-template
uce-template [options] file.html
cat file.html | uce-template [options]
-h --help this message
--babel targets ES5
--debug to not minify JS
-o output file

This does one thing only: it creates optimized , , and files for either a whole file, or any .uce component definition, so that what gets shipped in production would be as tiny as possible, for blazing fast performance and less bandwidth usage for Mobile 🎉

If the --babel flag is passed, the generated would be automatically transpiled to be compatible with , because of course we need to keep in mind that if we write modern , will not be happy about it.

However, if we write compatible within our definitions, this tool isn’t even needed, and we can indeed test the classic example in .

And much more

I know this project is very recent, but I am trying to write as much documentation as I can, with live demos included, in its file, but feel free to reach me out anyhow if there’s anything in particular you’d like me to document or explain, and thanks a lot for giving this shiny new way to write a chance ♥, and I’d like to leave here yet another example I’ve created, to have <slot> within the definition 👋

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