What is WebComponent?

@beforesemicolon/web-component is a lightweight, compiler-free reactive layer built on top of the native Web Components API. It is powered by the @beforesemicolon/markup template engine to bring reactivity, state management, and scoped styling to standard Custom Elements.

By design, the native Web Components APIs are low-level and verbose. Writing raw custom elements often results in redundant boilerplate for DOM manipulation, attribute tracking, event handling, and manual UI updates. The WebComponent base class simplifies this process, letting you build self-contained, reactive components using standard browser APIs.

Key Enhancements

WebComponent wraps native custom elements with several major enhancements:

Start Here

Full Example

Here is a complete reactive counter component implemented in TypeScript, showcasing props, state, event dispatching, stylesheets, and template rendering:

typescript
1// import everything from Markup as if you are using it directly2import { WebComponent, html } from '@beforesemicolon/web-component'3import stylesheet from './counter-app.css' with { type: 'css' }4 5interface Props {6    label: string7}8 9interface State {10    count: number11}12 13class CounterApp extends WebComponent<Props, State> {14    static observedAttributes = ['label']15    label = '+' // defined props default value16    initialState = {17        // declare initial state18        count: 0,19    }20    stylesheet = stylesheet21 22    countUp = (e: Event) => {23        e.stopPropagation()24        e.preventDefault()25 26        this.setState(({ count }) => ({ count: count + 1 }))27        this.dispatch('click')28    }29 30    render() {31        return html`32            <p>${this.state.count}</p>33            <button type="button" onclick="${this.countUp}">34                ${this.props.label}35            </button>36        `37    }38}39 40customElements.define('counter-app', CounterApp)

In your HTML you can simply use the tag normally.

html
1<counter-app label="count up"></counter-app>
edit this doc