DEV Community

Cover image for You Should Be Shipping a Manifest with Your Web Components
Burton Smith
Burton Smith

Posted on

You Should Be Shipping a Manifest with Your Web Components

Besides your components, the Custom Elements Manifest is the most important thing you can ship in your library.

What is a Custom Elements Manifest (CEM)?

The Custom Elements Manifest is a schema designed to document the metadata about your custom elements/web components, including attributes, properties, methods, events, slots, CSS parts, and CSS variables. It takes all of the information about your components and serializes it into a single json file in your project.

Why do users need it?

This standardized documentation method unlocks huge possibilities with how teams use and interact with your component library. Developers can use it for documentation purposes like Adobe Spectrum's API documentation.

Image description

Teams can also use them for framework, IDE integrations, and other tooling like Storybook.

This is nice if you want to create specific types or framework integrations you would like to ship with your components, but it's tough to anticipate all of your user's needs. You may be building your components to be used in a Vue.js environment, but another team may come along that needs to use your components in a react environment. Rather than waiting for you to build and ship react wrappers, teams can use the CEM to generate their own wrappers locally.

A recent example of this was when I was helping a team get up and running with Shoelace in a Next.js application. Shoelace provides react wrappers, but they were throwing an error when Next.js tried to server-side render them. Fortunately, Shoelace ships their CEM, so I was able to use it to generate new wrappers that were SSR-safe.

Here is a link to an example:

Open in StackBlitz

How do you create a CEM?

There are a couple of tools out there for creating a CEM (web-component-analyzer and Lit labs has an experimental tool), but my go-to tool is the Custom Elements Manifest Analyzer.

This is a great option for a few reasons reasons:

Here are some available plugins I've created that can help improve your custom element adoption:

NOTE: These provide CEM Analyzer plugins and functions for pre-generated CEMs. If you're not using the CEM Analyzer, don't worry, you can still take advantage of these.

Conclusion

The Custom Element Manifest is a great tool for accelerating user adoption of your custom element component library. By providing it as part of your product, you can provide consumers with the means to ensure their needs are being met when using your custom elements.

When choosing a library or framework for authoring your custom elements, it's a good idea to try to find one that you can generate a CEM, especially if your components will be used by other teams.

Top comments (10)

Collapse
 
westbrook profile image
Westbrook Johnson

Loving this! And, really enjoying wc-storybook-helpers. 👏👏👏

I share the CSF output from Storybook into my unit testing toolings, which means the helpers will be even more powerful for me and my test! Note, however, that Storybook's preview.js will not be run in that context, so to leverage the helpers you'll need to include something like:

import cem from './custom-elements.json' with { type: 'json' };

globalThis.__STORYBOOK_CUSTOM_ELEMENTS_MANIFEST__ = cem;
Enter fullscreen mode Exit fullscreen mode

It's a little leaky, yes. Maybe a method similar to import { setCustomElementsManifest } from "@storybook/web-components"; could be exported from wc-storybook-helpers to allow for a nicer usage?

Collapse
 
stuffbreaker profile image
Burton Smith

Are you including that in the main.ts?

Collapse
 
westbrook profile image
Westbrook Johnson

At Storybook time, it's just managed by setCustomElementsManifest(customElements);, no problem.

However, I use all of the CSF structure from my Storybook as a part of my unit test set up. Right now Vitest but also Web Test Runner in a number of cases. In those contexts, the Storybook preview.js file will not be included, so something like the above in the preparation script for my test run is required to prevent it from yelling at me with:

Error: Custom Elements Manifest not found. Be sure to follow the pre-install steps in this guide:
https://www.npmjs.com/package/wc-storybook-helpers#before-you-install
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
stuffbreaker profile image
Burton Smith

Where are you adding this code so it works during testing?

import cem from './custom-elements.json' with { type: 'json' };

globalThis.__STORYBOOK_CUSTOM_ELEMENTS_MANIFEST__ = cem;
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
westbrook profile image
Westbrook Johnson

For Vite, I add it to my setup file.

I'm fairly certain that other testing tools all have similar concepts.

Thread Thread
 
stuffbreaker profile image
Burton Smith

Let me check with the Storybook team where the best place for this would be for testing.

Thread Thread
 
westbrook profile image
Westbrook Johnson

To be clear, I don't use "Storybook" for testing. I use the CSF exports from my stories in the test context. Sort of like the package were called wc-csf-helpers, but because wc-storybook-helpers, I have to work around the Storybook part (the assumption of the presence of their global value) when I test in other contexts. Not a huge issue. In that it's just one line, it might not be worth doing anything about.

Thread Thread
 
stuffbreaker profile image
Burton Smith

Oh, interesting. Maybe I can at least add something about it in the docs.

Collapse
 
programmerraja profile image
Boopathi

This is a really insightful post! The concept of a Custom Elements Manifest is game-changing for web component libraries, making integration and adoption much smoother.

Collapse
 
stuffbreaker profile image
Burton Smith

Thank you! It really has had a huge impact on our ability to provide a product teams appreciate.