@jasonshimmy/custom-elements-runtime
v2.5.2
Published
A powerful, modern, and lightweight runtime for creating reactive web components with TypeScript
Maintainers
Readme
🧩 Custom Elements Runtime
The Complete Web Components Framework
Build modern components with strict TypeScript, zero dependencies, and a clean functional API. Designed for speed, standards compliance, and productivity.
🕹️ Try it on Codepen.io.
✨ Why You'll Love It
- ⚡ Blazing Fast: Minimal runtime, instant updates, zero dependencies.
- 🎨 JIT CSS: On-demand, utility-first styling directly in your HTML at runtime.
- 💪 No Build Necessary: Instant development feedback, no bundling required.
- 🧑💻 TypeScript First: Strict types, intellisense, and safety everywhere.
- 🧩 Functional API: No classes, no boilerplate—just pure functions.
- 🛠️ SSR & HMR Ready: Universal rendering and instant hot reloads.
- 🔌 Extensible: Directives, event bus, store, and more for advanced use cases.
- 🏆 Developer Friendly: Clean docs, examples, and a welcoming community.
⏱️ Getting Started
- Install:
npm install @jasonshimmy/custom-elements-runtime - Create a Component:
import {
component,
ref,
html,
useEmit,
useProps,
} from '@jasonshimmy/custom-elements-runtime';
component('my-counter', () => {
const props = useProps({ initialCount: 0 });
const count = ref(props.initialCount);
const emit = useEmit();
const handleClick = () => {
count.value++;
emit('update:initial-count', { count: count.value });
};
return html`
<button
type="button"
class="px-4 py-2 bg-primary-500 text-white rounded"
@click.prevent="${handleClick}"
>
Count: ${count.value}
</button>
`;
});- Use in HTML:
<my-counter
initial-count="5"
@update:initial-count="handleCountUpdate"
></my-counter>
<script>
function handleCountUpdate(event) {
console.log('Count updated to:', event.detail.count);
}
</script>- Enjoy instant reactivity and type safety!
📦 Complete API Reference
Below is the complete list of public symbols exported by the runtime and its named subpaths (root entry + subpath entries).
Root Entry
Package: @jasonshimmy/custom-elements-runtime
| Export | Description |
| ----------------------- | ---------------------------------------------------------------------- |
| component | Define a custom element with the functional component API. |
| html | Template tag function producing runtime VNodes from template literals. |
| css | Define component-scoped/JIT styles or register stylesheets. |
| ref | Create a reactive reference object with a .value property. |
| computed | Create a derived, read-only reactive value from other reactives. |
| watch | Register watchers reacting to changes in reactive values. |
| useProps | Hook to declare/consume typed component props with defaults. |
| useEmit | Hook returning an emit function for dispatching custom events. |
| useOnConnected | Hook that runs a callback when the component connects. |
| useOnDisconnected | Hook that runs a callback when the component disconnects. |
| useOnAttributeChanged | Hook observing host attribute changes. |
| useOnError | Hook to register a component-level error handler. |
| useStyle | Hook to register or compute component styles at runtime. |
| unsafeHTML | Insert raw HTML into a template (unsafe; use carefully). |
| decodeEntities | Utility to decode HTML entities in strings. |
Directives
Package: @jasonshimmy/custom-elements-runtime/directives
| Export | Description |
| ------------- | ------------------------------------------------------------------ |
| when | Conditional rendering: render children when the condition is true. |
| each | Iterate arrays and render a VNode per item with stable keys. |
| match | Fluent branching API (when/otherwise/done) returning VNodes. |
| anchorBlock | Create a stable anchor VNode used as block boundaries. |
Directive Enhancements
Package: @jasonshimmy/custom-elements-runtime/directive-enhancements
| Export | Description |
| ------------------ | ------------------------------------------------------------------------ |
| unless | Inverse of when (render when condition is false). |
| whenEmpty | Render content when a collection is empty or null. |
| whenNotEmpty | Render content when a collection has items. |
| eachWhere | Filter + iterate; render only items matching a predicate. |
| switchOnLength | Render different content based on array length cases. |
| eachGroup | Group array items by a key and render per-group content. |
| eachPage | Render a paginated subset (page) of items. |
| switchOnPromise | Render loading/success/error/idle states for async data. |
| whenMedia | Render content when a CSS media query matches. |
| mediaVariants | Map of responsive media queries (sm, md, lg, xl, 2xl, dark). |
| responsiveOrder | Ordered breakpoint keys used by responsive helpers. |
| responsive | Per-breakpoint helpers (sm/md/lg/xl/2xl/dark). |
| whenVariants | Compose multiple variants (e.g., dark + lg) into one media query. |
| responsiveSwitch | Render different content for different breakpoints. |
| switchOn | Fluent switch/case API matching a value to content. |
Transitions
Package: @jasonshimmy/custom-elements-runtime/transitions
| Export | Description |
| ------------------------- | ------------------------------------------------------------------------------------- |
| Transition | Wrap content with enter/leave transition metadata consumed by the runtime. |
| TransitionGroup | Animate lists with enter/leave/move transitions for children. |
| transitionPresets | Built-in transition presets (fade, slide, scale, etc.). |
| createTransitionPreset | Create a reusable transition preset programmatically. |
| getTransitionStyleSheet | Obtain the CSSStyleSheet used by the transition runtime. |
| Types | TransitionClasses, TransitionHooks, TransitionOptions, TransitionGroupOptions |
Event Bus
Package: @jasonshimmy/custom-elements-runtime/event-bus
| Export | Description |
| ---------------- | ------------------------------------------------------------------------------ |
| EventHandler | Type: callback signature used by the event bus. |
| GlobalEventBus | Class: singleton implementing a global pub/sub event bus. |
| eventBus | Proxy: lazy proxy to the singleton GlobalEventBus instance. |
| emit | Emit a global event with an optional payload. |
| on | Register a handler for a global event (returns unsubscribe function). |
| off | Remove a handler for a global event. |
| once | Register a one-time handler; returns a Promise resolving with the payload. |
| listen | Listen for native CustomEvent on the global event bus (returns unsubscribe). |
Store
Package: @jasonshimmy/custom-elements-runtime/store
| Export | Description |
| ------------- | ----------------------------------------------------------- |
| Store | Interface describing subscribe / getState / setState. |
| createStore | Create a simple observable store that notifies subscribers. |
Router
Package: @jasonshimmy/custom-elements-runtime/router
| Export | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------------------- |
| useRouter | Create and use a router instance configured with routes (client & SSR). |
| initRouter | Initialize the router and register router-view / router-link. |
| matchRoute | Match a path against configured routes and extract params. |
| matchRouteSSR | SSR-friendly wrapper for route matching. |
| parseQuery | Parse a query string into a key/value map. |
| resolveRouteComponent | Resolve/load a route's component (supports async loaders + caching). |
| Types | Route, RouteState, RouteComponent, GuardResult, RouterLinkProps, RouterLinkComputed, RouterConfig |
SSR
Package: @jasonshimmy/custom-elements-runtime/ssr
| Export | Description |
| ---------------- | ------------------------------------------------------ |
| renderToString | Render a VNode tree to HTML for server-side rendering. |
| VNode (type) | The runtime VNode shape used by renderers and SSR. |
Global Styles (CSS)
Package: @jasonshimmy/custom-elements-runtime/css or @jasonshimmy/custom-elements-runtime/css/style.css
| Export | Description |
| ----------- | -------------------------------------------------------- |
| style.css | CSS export that contains CSS variables and a base reset. |
Variables (CSS)
Package: @jasonshimmy/custom-elements-runtime/css/variables.css
| Export | Description |
| --------------- | ------------------------------------------------------------- |
| variables.css | CSS export that contains design tokens (colors, fonts, etc.). |
Reset (CSS)
Package: @jasonshimmy/custom-elements-runtime/css/reset.css
| Export | Description |
| ----------- | ------------------------------------------------- |
| reset.css | CSS export that contains a base reset for styles. |
📖 Documentation Index
Explore the complete documentation for every runtime feature:
🚀 Getting Started
- 🎯 Functional API - Start here! Complete guide to the modern functional component API
🏗️ Core Features
- 🧩 Template - Template syntax and html function
- 🧭 Directives - Conditional rendering with
when,each, andmatch - 🛠️ Directive Enhancements - Advanced directive utilities:
unless- Inverse ofwhenwhenEmpty/whenNotEmpty- Collection checkseachWhere- Filtered iterationswitchOnLength- Render based on array lengtheachGroup- Group and render itemseachPage- Pagination supportswitchOnPromise- Async state renderingwhenMedia- Media query responsive renderingresponsive- Responsive utilities
- 🔗 Bindings - Data binding with
:prop,@event,:model,:class,:style - 🔔 Events Deep Dive - Custom event emission and handling patterns
- 🎬 Transitions Guide - Animation and transition effects
🎨 Styling
- 🎨 JIT CSS - On-demand utility-first styling system
- 📝 Prose Typography - Beautiful typography for long-form content
🔗 Communication & State
- 📢 Event Bus - Global event system for cross-component communication
- 🗄️ Store - Global state management
- 🚦 Router - Client-side routing
- 🤝 Cross-Component Communication - Patterns for component interaction
⚡ Advanced Features
- 🔮 Virtual DOM - VDOM implementation and performance details
- 🌐 SSR - Server-side rendering support
- ♻️ HMR - Hot module replacement
- 🛡️ Infinite Loop Protection - Runtime safeguards against infinite loops
- 🔒 Secure Expression Evaluator - Safe evaluation of dynamic expressions in templates
🔧 Integration Guides
- ⚛️ React Integration - Using components in React apps
- 🦊 Vue Integration - Using components in Vue apps
- 🅰️ Angular Integration - Using components in Angular apps
- 🔥 Svelte Integration - Using components in Svelte apps
🛠️ Troubleshooting
- 🔧 Troubleshooting - Common issues and solutions
For examples and implementation details, explore the source code in src/lib/.
🧑🔬 Real-World Examples
🌟 Showcase & Community
- Showcase your components! Open a PR to add your project to our gallery.
- Questions or ideas? Start a discussion or open an issue.
- Contribute: We welcome PRs for docs, features, and examples.
- ❤️ Like what you see? Support ongoing development on Patreon
💖 Support This Project
Custom Elements Runtime is a labor of love built to make modern web development faster and more expressive. If it's helping you build better components, consider supporting me on Patreon to help keep the momentum going.
Your support helps fund continued development, documentation, and community engagement. Every bit helps—thank you!
