Zero Build Reactivity • JavaScript

Build reactive UIs with zero ceremony

Write this.count++ and watch your UI update. No build tools required.

<script src="https://cdn.jsdelivr.net/gh/quellabs/wakapac@main/wakapac.min.js"></script>
Live Demo - Try it!

{{greeting}}

Count: {{count}}

<div id="app">
  <h4>{{greeting}}</h4>
  <p>Count: {{count}}</p>
  <input data-pac-bind="value: name">
  <button data-pac-bind="click: increment">+1</button>
</div>

<script>
wakaPAC('#app', {
  name: 'World', count: 0,
  computed: {
    greeting() { return `Hello ${this.name}!`; }
  },
  increment() { this.count++; },
  reset() { this.count = 0; this.name = 'World'; }
});
</script>

Simple.

Include one file.
Write HTML.
Refresh browser.

No Build.

One file.
One script tag.
Working code in 60 seconds.

Powerful.

Full reactivity.
Computed properties.
Component hierarchy.

Get Started in 60 Seconds

Copy, paste, done. No installation. No configuration.

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/gh/quellabs/wakapac@main/wakapac.min.js"></script>
</head>
<body>

<div id="app">
    <h1>Hello {{name}}!</h1>
    <input data-pac-bind="value: name">
</div>

<script>
    wakaPAC('#app', {
        name: 'World'
    });
</script>

</body>
</html>

That's a complete reactive application 50KB minified MIT licensed

Everything You Need. Nothing You Don't.

Complete reactive framework in one file

No Build Step

One script tag. Refresh your browser. It just works.

Direct Assignment

Write this.count++ not setCount(count + 1). Natural JavaScript, automatic updates.

Mustache Interpolation

{{expressions}} with full JavaScript operators, ternaries, array literals.

Computed & Browser Properties

Derived values recalculate automatically. Reactive network status, viewport size, scroll position - zero setup.

Component Hierarchy

Parent-child messaging built-in. Clear relationships, explicit communication.

Low Level Events

Low-level msgProc for drag-and-drop, custom gestures, IDE-like UIs.

Why WakaPAC Exists

After 25 years building web applications, I wanted a tool that gets out of the way. One script tag, natural JavaScript, reactive updates. No build step, no configuration, no ceremony.

WakaPAC is what I wished existed: the directness of early Knockout.js with modern JavaScript power.

— Floris, Quellabs

See It In Action

Real code, real patterns, ready to copy

Todo List
<div id="todos">
  <input data-pac-bind="value: newTodo">
  <button data-pac-bind="click: add">Add</button>

  <ul data-pac-bind="foreach: items">
    <li>
      {{item.text}}
      <button data-pac-bind="click: remove">
        Delete
      </button>
    </li>
  </ul>
</div>

<script>
wakaPAC('#todos', {
  newTodo: '',
  items: [],

  add() {
    if (this.newTodo.trim()) {
      this.items.push({ text: this.newTodo });
      this.newTodo = '';
    }
  },

  remove(item) {
    const index = this.items.indexOf(item);
    this.items.splice(index, 1);
  }
});
</script>
Computed Properties
wakaPAC('#app', {
  firstName: 'John',
  lastName: 'Doe',
  items: [
    { name: 'Apple', price: 10 },
    { name: 'Banana', price: 20 }
  ],

  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    },

    totalPrice() {
      return this.items.reduce(
        (sum, item) => sum + item.price,
        0
      );
    },

    itemCount() {
      return this.items.length;
    }
  }
});

Automatically recalculates when dependencies change

Parent-Child Communication
// Child component
const child = wakaPAC('#child', {
  sendMessage() {
    this.notifyParent('alert', {
      text: 'Task completed',
      time: Date.now()
    });
  }
});

// Parent component
const parent = wakaPAC('#parent', {
  receiveFromChild(type, data, childPAC) {
    if (type === 'alert') {
      console.log('Child says:', data.text);
    }
  },

  broadcastToAll() {
    this.notifyChildren('refresh', {
      theme: 'dark'
    });
  }
});
Reactive Browser Properties
<div id="app">
  <!-- Network status -->
  <p data-pac-bind="visible: !browserOnline">
    ⚠️ You are offline
  </p>

  <!-- Viewport info -->
  <p>Screen: {{browserViewportWidth}} ×
         {{browserViewportHeight}}</p>

  <!-- Page visibility -->
  <p data-pac-bind="visible: !browserVisible">
    Tab hidden - updates paused
  </p>

  <!-- Scroll position -->
  <p>Scrolled: {{browserScrollY}}px</p>

  <!-- Network quality -->
  <p>Connection: {{browserNetworkQuality}}</p>
</div>

All reactive, zero configuration required

Built on PAC Architecture

Presentation-Abstraction-Control: A smarter alternative to MVC

Presentation

Your HTML and DOM — what users see and interact with

Abstraction

Your data model and business logic — what your app knows

Control

The reactive mediator — keeps everything synchronized

Why this matters: PAC enforces a single data flow path through the Control layer. When your UI breaks, there's only one place to look. No mystery mutations, just clear, predictable data flow.

Stop Configuring. Start Building.

Download one file and write working code in the next 60 seconds

Open source • MIT licensed • 50KB minified • Zero dependencies