lively4-core

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

AI Collaboration Experiment

A significant part of this AI collaboration is an experiment to teach Claude Code how to develop in Lively4. By working together on real development tasks, we are:

This documentation serves dual purposes: guiding AI development work and creating human-readable documentation of Lively4’s development practices. The demos/claude/ directory contains examples and experiments from this collaborative learning process.

Essential Commands

Testing:

Example:

npm run test-single test/client/strings-test.js
# ✅ 6 tests passed, 0 failed in 0.01s

Development:

In-Browser Development:

Core Architecture

Lively4 System: Self-supporting browser-based development environment using:

Module System:

Central API (src/client/lively.js):

File Organization & Patterns

Directory Structure:

Component Development Pattern:

  1. Create paired files: templates/my-component.html + templates/my-component.js
  2. Components extend Morph and follow this structure:
export default class MyComponent extends Morph {
  async initialize() {
    this.windowTitle = "Component Title";
    this.registerButtons(); // auto-registers onButtonName handlers
    lively.html.registerKeys(this); // auto-registers onKeyDown handlers
  }
  
  livelyExample() {
    // Customize instance with example content
  }
  
  livelyMigrate(other) {
    // Handle live updates during development
    this.someProperty = other.someProperty;
  }
}

Template Pattern (HTML):

<template id="my-component">
  <style data-src="/templates/livelystyle.css"></style>
  <style>/* component-specific styles */</style>
  <div id="content">
    <button id="myButton">Click Me</button>
  </div>
</template>

Key Integration Points

Container System: lively-container (src/components/tools/lively-container.js)

Event System: Use lively.addEventListener() for proper cleanup:

lively.addEventListener("myId", this, "click", evt => this.onClick(evt))
// Automatically cleaned up with lively.removeEventListener("myId", this)

Component Access:

this.get("#selector") // querySelector in component and shadowRoot
await lively.openComponentInWindow("component-name")

Development Guidelines

Interactive Markdown Development

Script Integration in Markdown Files:

Development Journal

Special Notes