Package Exports
- @jasonshimmy/custom-elements-runtime
- @jasonshimmy/custom-elements-runtime/css
- @jasonshimmy/custom-elements-runtime/css/colors
- @jasonshimmy/custom-elements-runtime/css/reset.css
- @jasonshimmy/custom-elements-runtime/css/style.css
- @jasonshimmy/custom-elements-runtime/css/variables.css
- @jasonshimmy/custom-elements-runtime/directive-enhancements
- @jasonshimmy/custom-elements-runtime/directives
- @jasonshimmy/custom-elements-runtime/entities.json
- @jasonshimmy/custom-elements-runtime/event-bus
- @jasonshimmy/custom-elements-runtime/router
- @jasonshimmy/custom-elements-runtime/ssr
- @jasonshimmy/custom-elements-runtime/store
- @jasonshimmy/custom-elements-runtime/transitions
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 memoized, derived read-only value from other reactive sources. |
watch |
Register watchers reacting to changes in reactive values. |
watchEffect |
Auto-track reactive reads and re-run a side-effect whenever dependencies change. |
nextTick |
Returns a Promise resolving after all pending DOM updates are flushed. |
flushDOMUpdates |
Synchronously flush all pending DOM update tasks (useful in tests). |
scheduleWithPriority |
Schedule a callback at a given UpdatePriority level. |
provide |
Store a value on the current component for descendant injection. |
inject |
Retrieve a value provided by an ancestor component. |
createComposable |
Package reusable stateful logic (hooks, reactive state) into a composable. |
getCurrentComponentContext |
Access the active component context from within a composable or render function. |
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. |
useExpose |
Publish methods and properties onto the host element as an imperative public API. |
useSlots |
Inspect which named slots have been filled by the component consumer. |
useTeleport |
Render virtual DOM content into any DOM node outside the shadow root. |
registerKeepAlive |
Register <cer-keep-alive> to preserve component state across DOM removals. |
registerSuspense |
Register the <cer-suspense> built-in component. |
registerErrorBoundary |
Register the <cer-error-boundary> built-in component. |
registerBuiltinComponents |
Register both <cer-suspense> and <cer-error-boundary> in one call. |
unsafeHTML |
Insert raw HTML into a template (unsafe; use carefully). |
decodeEntities |
Utility to decode HTML entities in strings. |
setDevMode |
Toggle dev-mode logging on or off at runtime. |
devLog |
Log a message to the console in dev mode only (no-op in production). |
isReactiveState |
Type-guard returning true when a value is a ReactiveState instance. |
createHealthMonitor |
Create a new health monitor instance (factory; each call returns an independent instance). |
getHealthMonitor |
Return the global singleton health monitor instance (lazily created). |
updateHealthMetric |
Update a named metric on the global singleton health monitor. |
getHealthStatus |
Return the current HealthReport from the global singleton health monitor. |
| Types | HealthMonitorInstance, HealthReport, UpdatePriority, TeleportHandle, ReactiveState, VNode |
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 |
One-time listener. Callback form once(name, handler) โ void. Promise form once(name) โ Promise<T>. Do not mix. |
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. |
findMatchedRoute |
Find the first matching route entry from an array of routes (lower-level helper). |
parseQuery |
Parse a query string into a key/value map. |
serializeQuery |
Serialize a key/value map into a query string (e.g. ?a=b). |
normalizePathForRoute |
Normalize a path string for consistent route matching (strips trailing slashes, etc.). |
DEFAULT_SCROLL_CONFIG |
Default scroll-to-fragment configuration object used by the router. |
isDangerousScheme |
Returns true for dangerous URL schemes (e.g. javascript:). |
isAbsoluteUrl |
Returns true when a URL string is absolute (has a protocol). |
safeDecode |
Decode a URI component, returning the original string on error. |
canonicalizeBase |
Normalize a router base path string (strips trailing slashes, ensures leading slash). |
resolveRouteComponent |
Resolve/load a route's component (supports async loaders + caching). |
clearComponentCache |
Clear the resolved route component cache (useful for testing and HMR). |
activeRouterProxy |
Stable proxy to the currently active router; forwards subscriptions and method calls (advanced/testing use). |
| Types | Route, RouteState, RouteComponent, GuardResult, RouterLinkProps, RouterLinkComputed, RouterConfig, Router |
SSR
Package: @jasonshimmy/custom-elements-runtime/ssr
| Export | Description |
|---|---|
renderToString |
Render a VNode tree to HTML for server-side rendering. |
registerEntityMap |
Register a custom named-entity map for SSR decodeEntities. |
loadEntityMap |
Async loader that dynamically imports the full HTML5 named-entity map; returns the map to pass to registerEntityMap. |
clearRegisteredEntityMap |
Reset the registered entity map back to the built-in minimal set. |
VNode (type) |
The runtime VNode shape used by renderers and SSR. |
RenderOptions (type) |
Options for renderToString (injectSvgNamespace, injectKnownNamespaces). |
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. |
Extended Color Palette (TypeScript)
Package: @jasonshimmy/custom-elements-runtime/css/colors
Opt-in extended color palette with full Tailwind-compatible color names (slate, gray, zinc, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose) with shades 50โ950.
import { extendedColors } from '@jasonshimmy/custom-elements-runtime/css/colors';
// Use individual color scales
const blueShades = extendedColors.blue; // { '50': '#eff6ff', '100': '...', ... }
// Use in a component
component('branded-card', () => {
useStyle(
() => css`
:host {
--card-accent: ${extendedColors.violet['500']};
}
`,
);
return html`<slot></slot>`;
});| Export | Description |
|---|---|
extendedColors |
Full extended palette โ Record<string, Record<string, string>> (name โ shade โ hex). |
ColorScale |
Type: single color scale with shade keys 50โ950. |
๐ 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
- ๐ Space Utilities - Tailwind-style
space-x-*andspace-y-*spacing utilities - ๐ Prose Typography - Beautiful typography for long-form content
- ๐จ Colors - Extended Tailwind-compatible color palette (
/css/colorssubpath)
๐ 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
- โก Reactive API -
watch()targeted watchers,computed()memoization,watchEffect()auto-tracking, andnextTick() - ๐๏ธ Provide / Inject - Ancestor-to-descendant dependency injection without prop-drilling
- ๐งฉ Composables - Reusable stateful logic with
createComposable() - ๐ Teleport - Render content outside the shadow root with
useTeleport() - โป๏ธ Keep-Alive - Preserve component state across DOM removals with
<cer-keep-alive> - ๐ฉบ Health Monitor - Track runtime metrics and receive periodic health reports with
createHealthMonitor() - ๐ฎ 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!