Getting Started
Monster is a web components library. The fastest way to get productive is to think in three layers: markup for the component itself, options via data-monster-option-*, and optional JavaScript for richer behavior.
This page shows the two practical entry points: direct browser usage for quick prototypes, and package-based usage for real projects. It also explains how the documentation examples in this repository are structured.
Quick Start in the Browser
For a first experiment you only need an HTML file and a module import. This keeps the feedback loop short and is ideal for checking component behavior before integrating Monster into a larger application.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Build fantastic websites!</title>
<style>
*:not(:defined) {
visibility: hidden;
}
</style>
</head>
<body>
<main>
<monster-select>
<div data-monster-value="value1">label-1</div>
<div data-monster-value="value2">label-2</div>
<div data-monster-value="value3">label-3</div>
</monster-select>
<script type="module">
import 'https://esm.sh/@schukai/monster/source/components/form/select.mjs';
import { PropertyStyleSheet } from 'https://esm.sh/@schukai/monster/source/components/stylesheet/property.mjs';
document.adoptedStyleSheets = [PropertyStyleSheet];
</script>
</main>
</body>
</html>Two details matter here:
*:not(:defined)hides unresolved custom elements until the browser has upgraded them.- You only import the modules you actually use. Monster does not require an all-or-nothing runtime bundle.
For quick demos, CDN-based imports are fine. For production projects, package-based imports are usually the better choice because you control versioning, bundling and caching explicitly.
Install via NPM, Yarn or PNPM
In an application repo, install Monster as a package and import only the components and stylesheets you need.
- Add the package:
npm install @schukai/monsteroryarn add @schukai/monsterorpnpm add @schukai/monster
To pin a specific version, append @version to the package name.
A minimal package-based setup usually looks like this:
import "@schukai/monster/source/components/form/select.mjs";
import { PropertyStyleSheet } from "@schukai/monster/source/components/stylesheet/property.mjs";
document.adoptedStyleSheets = [
...document.adoptedStyleSheets,
PropertyStyleSheet,
];That gives you the component module and the foundational property stylesheet. Depending on the control, you may add further stylesheets or neighboring components, but the import principle stays the same.
Core Markup Rules
Most Monster components follow a small set of conventions:
- The tag name is the component API, for example
<monster-select>. - Declarative options use
data-monster-option-*. - Structural data is often passed via children, labels, slots or datasource references.
- Advanced behavior is added with JavaScript events and method calls, not by re-implementing the component UI yourself.
<monster-select
data-monster-option-features-filterable="true"
data-monster-option-labels-placeholder="Choose an option"
>
<div data-monster-value="one">One</div>
<div data-monster-value="two">Two</div>
</monster-select>The documentation pages list all supported options, methods, properties and events for each component. The important point is that the declarative HTML API is the default, and JavaScript should extend it instead of replacing it.
Attributes, Options and Properties
Monster uses three different API layers and they should not be mixed up:
attributesdata-monster-value="one"data-monster-option-*data-monster-option-features-filterable="true"properties / methodselement.value = "two", element.fetch()The default path is: start with HTML, add data-monster-option-* for declarative behavior, then move to properties or methods only when state becomes dynamic.
<monster-select
data-monster-option-features-filterable="true"
data-monster-option-labels-placeholder="Choose an option"
value="two"
>
<div data-monster-value="one">One</div>
<div data-monster-value="two">Two</div>
</monster-select>const select = document.querySelector("monster-select");
select.value = "one";
select.setOption("labels.placeholder", "Select a value");
select.addEventListener("change", (event) => {
console.log("new value", event.target.value);
});Events and Methods
Monster components usually expose two extension points for JavaScript:
- Listen to DOM or custom events when you want to react to user interaction.
- Call methods when you want to update state, load data or trigger component behavior from outside.
For example, a simple select can often be configured entirely in markup, while a more workflow-oriented component such as monster-api-button becomes interesting when you react to events like monster-api-button-successful or call runtime functions that fetch and import actions.
const apiButton = document.querySelector("monster-api-button");
apiButton.addEventListener("monster-api-button-successful", (event) => {
console.log("request completed", event.detail);
});
apiButton.addEventListener("monster-api-button-failed", (event) => {
console.error("request failed", event.detail);
});The rule of thumb is simple: markup explains what a component is, JavaScript explains what should happen over time.
How Documentation Examples Are Structured
The examples in monsterjs-org deliberately split source view and runtime view. That keeps the docs readable and avoids leaking demo-only IDs or bootstrapping code into the copy-paste source examples.
main.htmlrun.html if needed.run.htmlmain.html.script.mjsrun.mjsscript.mjs in code view.readme.htmlstyle.cssIn practice this means: main.html and script.mjs should be the clearest source you want a user to learn from. run.html and run.mjs may diverge where the live demo needs extra plumbing.
Generated example sections in the documentation now also include an Open in playground action. That sends the runtime HTML, CSS and JavaScript directly to playground.html?load=true, so readers can tweak a working example immediately instead of rebuilding it by hand.
When to Use Which Layer
- Use pure HTML first when the component API is already expressive enough.
- Add JavaScript when you need events, runtime state, async data or dynamic options.
- Add custom CSS only when Monster tokens and built-in styles are not sufficient.
- Prefer Monster tokens for color, spacing and radius so the result remains compatible with dark mode and theming.
Where to Go Next
After this page, the best next steps are:
- Read the foundations pages for color, layout and typography.
- Open a component page like Select and inspect its API section together with the live examples.
- Reuse the example structure from this repo when you write your own documentation or internal showcases, or start from the playground.