Skip to content
DevinimJS
Phase 1 · Lesson 1

Hello World — Your First Reactive Component

Get a DevinimJS counter running on a plain HTML file. No Node.js, no bundler, no framework runtime to install.

What you'll learn
  • Load DevinimJS from a CDN with one <script type="module"> line
  • Drop a ready-made component into plain HTML
  • Configure components with data-* attributes
  • Listen for component events in your page script

The single-file approach

Create an empty index.html file. DevinimJS needs only two things: a custom element on the page and a module script that loads it.

CKCSS provides the visual layer. DevinimJS handles behavior. Your HTML owns structure. Together they need zero build tools.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My First DevinimJS Page</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/kayacuneyd/ckcss@v0.1.0-beta.1/dist/ckcss.min.css">
</head>
<body>

  <dv-counter data-start="0" data-step="1"></dv-counter>

  <script type="module" src="https://cdn.jsdelivr.net/gh/kayacuneyd/devinimjs@v0.5.1/dist/modules/dv-counter.js"></script>
</body>
</html>

Open this file in a browser. You'll see two buttons (+ and −) and a number. Every click mutates the component's internal reactive state and the DOM updates automatically.

Try it live

Live demo

Click the buttons. The display updates because the component owns reactive state.

What just happened?

  1. The browser encounters <dv-counter> and sees it's not a standard HTML element.
  2. The module script registers <dv-counter> as a custom element using define().
  3. On connection the component reads data-start="5" and data-step="2" via this.num('start', 0) and this.num('step', 1).
  4. The template() method renders a button and an <output> bound to the reactive this.state.count.
  5. Each click calls increment() which mutates the state; the component re-renders on the next microtask.

Responding to changes

Components emit dv:* custom events. Your page can listen to them with standard addEventListener:

<script type="module">
  const counter = document.querySelector('dv-counter');
  counter.addEventListener('dv:change', (event) => {
    console.log('New value:', event.detail.count);
    // Save to LocalStorage, send to a PHP endpoint, update a cart total...
  });
</script>

Persistence stays in the page. Components only own interaction state.

Pinning versions (important)

Always pin a tagged release

Never load main or an unversioned CDN URL. Use @v0.5.1 (or the latest tag) so your site doesn't break when the library updates.

For production, download the minified bundles to your own server:

# Core runtime (~2.8 KB gzipped)
curl -O https://cdn.jsdelivr.net/gh/kayacuneyd/devinimjs@v0.5.1/dist/core.min.js

# Individual components
curl -O https://cdn.jsdelivr.net/gh/kayacuneyd/devinimjs@v0.5.1/dist/modules/dv-counter.js

Recap

One import line

No package.json, no npm install, no bundler required.

HTML-first configuration

Components read data-* attributes. PHP or static HTML can provide initial values.

Events for persistence

Pages listen to dv:* events. Components don't know how data is saved.

Pinned releases

Use a tagged CDN URL. Never point at main.