One pinned import
Load CKCSS for presentation and DevinimJS for interaction. Runtime consumers need no npm package.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/kayacuneyd/ckcss@v0.1.0-beta.1/dist/ckcss.min.css">
<script type="module" src="https://cdn.jsdelivr.net/gh/kayacuneyd/devinimjs@v0.5.1/dist/modules/dv-tabs.js"></script>
<dv-tabs data-label="Account settings">
<section data-tab="Profile">Profile content</section>
<section data-tab="Billing">Billing content</section>
</dv-tabs>Build-free compatibility
Runtime
Zero npm/runtime dependencies. Native ES modules run directly in modern browsers.
Distribution
dist/ is optional optimization. Source modules remain a supported browser entry point.
New features must first work in the source runtime, then be added to the distribution. No compile-time template analysis, code generation or framework runtime is allowed.
Core API
| API | Purpose | Agent rule |
|---|---|---|
component | Default concise component factory. | Use it first for new components. |
BaseComponent | Proxy-reactive custom-element base class. | Use it as an advanced escape hatch. |
html | Escaping template tag. | Return it from view() or template(). |
createStore | Shared state and subscriptions. | Keep ownership at page/application level. |
morph | Focused DOM reconciliation. | Use stable data-key for moving lists. |
unsafe | Explicit raw HTML boundary. | Only use independently sanitized HTML. |
import { BaseComponent, html, define } from 'https://cdn.jsdelivr.net/gh/kayacuneyd/devinimjs@v0.5.1/dist/core.min.js';
class AcmeGreeting extends BaseComponent {
initialState() { return { name: this.str('name', 'World') }; }
template() { return html`<p>Hello ${this.state.name}</p>`; }
}
define('acme-greeting', AcmeGreeting);Opt-in tools for richer pages
Import app.min.js only when a page needs async data, JSON requests, forms or hash routing.
import { createAsyncState, fetchJson, createForm, createHashRouter } from 'https://cdn.jsdelivr.net/gh/kayacuneyd/devinimjs@v0.5.1/dist/app.min.js';
const products = createAsyncState();
products.run(() => fetchJson('/api/products.json'));
const checkout = createForm({ email: '' });
const router = createHashRouter().add('/', 'home').add('/products/:id', 'product');
router.start();Data flow guidance
Keep requests and persistence in page/application code. Components receive attributes or page-owned data and publish semantic dv:* events.
Component contract
Components follow dv-kebab.js → DvPascal → define('dv-kebab', ...). Configuration uses data-*; outbound communication uses bubbling dv:* CustomEvents.
| Family | Components | Events |
|---|---|---|
| Foundation | dv-counter, dv-tabs, dv-disclosure, dv-modal | change, tab, toggle, open/close |
| Forms/discovery | dv-field, dv-confirm, dv-search, dv-autocomplete | input, change, query, select, confirm |
| Data/commerce | dv-data-table, dv-pagination, dv-product-card, dv-cart | sort, page, add-to-cart, remove |
| Feedback/state | dv-toast, dv-toast-stack, dv-state | show, hide, retry |
Native behavior is the baseline
Prefer native controls. Interactive components define keyboard behavior, focus behavior, labels, roles and live-region semantics. Tabs follow the WAI-ARIA tabs pattern; dialogs restore focus and close on Escape; status messages use polite announcements.
Release check
Run npm run verify before release. It includes lint, unit tests, browser tests and the core size gate.
Escaped by default
Interpolated template values are escaped. The unsafe() boundary is explicit and must only receive independently sanitized HTML. Keep backend data in attributes or JSON and treat it as untrusted input.
Give agents a reliable map
Start with llms.txt for orientation, then use llms-full.txt and the component manifest for exact contracts.
Golden path
Generate with npm run create:component -- acme-card --format=dv. Keep external values in props, use on:event for actions, add the unit test and manifest entry, then run npm run validate:component -- acme-card.