HTML-first policy
Purpose
Section titled “Purpose”Relements must remain usable with plain HTML and CSS as a first-class integration path.
This is the core compatibility guarantee of the project. A consumer should be able to use the basic design system in any web project by writing semantic HTML and loading CSS. JavaScript, custom elements, and framework wrappers are progressive layers, not requirements for the foundation.
Compatibility Guarantee
Section titled “Compatibility Guarantee”The baseline Relements experience must work with:
- Plain HTML files.
- Server-rendered templates.
- Static site generators.
- CMS-rendered markup.
- React.
- Vue.
- Svelte.
- Angular.
- Any framework that can render HTML classes and attributes.
The canonical API is the browser API:
- HTML elements.
- Native HTML attributes.
- CSS classes.
- CSS custom properties.
data-*attributes.- ESM JavaScript modules where behavior is needed.
- DOM events where interaction needs to be observed.
Framework-specific APIs must never become the source of truth.
Layer Order
Section titled “Layer Order”Every feature should follow this order:
-
HTML Start with the closest native semantic element.
-
CSS Add styling, tokens, variants, layout, and visual states.
-
JavaScript Add behavior only when native HTML and CSS are not enough.
-
Custom Element Add a custom element only when a reusable framework-neutral component boundary is valuable.
-
Framework Wrapper Add thin wrappers only after the platform API is stable.
CSS-Only Consumption
Section titled “CSS-Only Consumption”Consumers must be able to use the foundation like this:
<link rel="stylesheet" href="/relements/index.css" />
<button class="re-button" data-variant="primary">Save</button>This usage must not require:
- JavaScript.
- A bundler.
- A frontend framework.
- A compiler.
- Hydration.
- Runtime registration.
JavaScript Enhancement Rules
Section titled “JavaScript Enhancement Rules”JavaScript should enhance existing markup:
<div class="re-tabs" data-re-tabs>...</div>import { enhanceTabs } from "@relements/core/behaviors/tabs";
const controller = enhanceTabs(document);Enhancers must:
- Accept a root node.
- Return a cleanup API.
- Avoid framework assumptions.
- Preserve understandable markup before enhancement.
- Use native events or documented
CustomEventAPIs.
Framework Wrapper Rules
Section titled “Framework Wrapper Rules”Framework wrappers are optional adapters.
They may provide:
- TypeScript ergonomics.
- Event binding convenience.
- Framework lifecycle integration.
- Familiar import paths for framework users.
They must not:
- Replace the HTML/CSS API.
- Introduce behavior that does not exist in the core package.
- Require consumers to use a wrapper for basic components.
- Hide native HTML attributes without a strong reason.
- Become the only documented usage path.
Canonical usage should always remain valid:
<button className="re-button" data-variant="primary"> Save</button>Wrappers should stay thin:
<Button variant="primary">Save</Button>The wrapper should render the same platform-level contract:
<button class="re-button" data-variant="primary">Save</button>Component Acceptance Rule
Section titled “Component Acceptance Rule”A component cannot be considered complete unless it documents and tests the lowest viable layer:
- HTML-only if possible.
- HTML plus CSS for visual styling.
- HTML plus CSS plus JavaScript for enhanced behavior.
- Custom element only when justified.
- Framework wrapper only after the core API is stable.
Non-Negotiables
Section titled “Non-Negotiables”- Basic styles must work with plain HTML.
- Native controls must stay native unless replacement is justified.
- CSS classes and custom properties are public API.
- JavaScript must be optional for static and form-oriented primitives.
- Framework support must build on the platform API, not fork it.