Skip to content
Andre Kless edited this page Mar 27, 2026 · 164 revisions

This wiki provides detailed documentation for the ccmjs framework.

👉 New to ccmjs? Start with the README.

🧠 Basic Principle

Once the ccmjs framework is included in a web page, the global ccm namespace becomes available. This creates a global object (window.ccm) that provides access to the core API. The central operation is:

ccm.start(component, config, area);

The specified component (component) is instantiated with the given configuration (config) and rendered into the provided web page area (area). A component combined with a configuration results in a running app.

Example:

<!DOCTYPE html>
<meta charset="UTF-8">
<body>

<script src="https://ccmjs.github.io/framework/ccm.js"></script>

<script>
const component = "https://ccmjs.github.io/quiz/ccm.quiz.mjs";

const config = {
  feedback: true,
  questions: [
    {
      text: "Does this example work?",
      input: "radio",
      answers: [
        { text: "Yes", correct: true },
        { text: "No" }
      ]
    }
  ]
};

ccm.start(component, config, document.body);
</script>

🏗️ Structure of a Component

A component is a file whose name starts with ccm., followed by the component's unique name and ends with .mjs. Example: ccm.quiz.mjs.

The content of a component has the following structure:

export const component = {
  name: "quiz",                                    // Unique name
  ccm: "https://ccmjs.github.io/framework/ccm.js", // URL to ccmjs
  config: {/*...*/},                               // Contains the default configuration
  Instance: function () {                // Defines the blueprint for creating component instances
    this.start = async () => {/*...*/};  // The web page area of ​​the component is designed here.
  }
};

Within the start() method, the web page area to be designed can be accessed via this.element. Every entry in the config can be accessed via this.

Example of a hello component:

export const component = {
  name: "hello",
  ccm: "https://ccmjs.github.io/framework/ccm.js",
  config: {
    name: "World"
  },
  Instance: function () {
    this.start = async () => {
      this.element.innerHTML = "Hello " + this.name;
    };
  }
};

Usage of the hello component:

<!DOCTYPE html>
<meta charset="UTF-8">
<body>
<script src="https://ccmjs.github.io/framework/ccm.js"></script>
<script>
  ccm.start("./ccm.hello.mjs", {
    name: "Mika"                 // Overrides "World" in the default configuration
  }, document.body);
</script>

The <body> of the web page then contains Hello Mika.

⚙️ Services

ccmjs offers the following services:

In addition, ccmjs also offers useful 🧰 Helper Functions for component developers under ccm.helper.

🔗 Declarative Dependencies

Additional dependent resources can be dynamically integrated at runtime via the config of a component. Dependencies to other resources are specified as an array in the form of [functionName, ...params].

Example:

const config = {
  html: ["ccm.load", "./templates.mjs"],                        // HTML templates
  css: ["ccm.load", "./styles.css"],                            // CSS
  store: ["ccm.store", {name: "mycollection"}],                 // Datastore
  dataset: ["ccm.get", {name: "mycollection"}, "mykey"],        // Single dataset
  comp: ["ccm.component", "./ccm.component.mjs", {/*config*/}], // Component object
  inst: ["ccm.instance", "./ccm.component.mjs", {/*config*/}],  // Instance of a component
  app: ["ccm.start", "./ccm.component.mjs", {/*config*/}]       // Directly started instance
};

Dependencies in ccmjs are expressed declaratively and resolved automatically at runtime.

🧭 Design Philosophy

ccmjs intentionally keeps its core minimal and focused on runtime composition. Common concerns such as Routing, User Authentication, or Internationalization are not built into the framework itself. Instead, they are provided as optional ccmjs components that can be added via configuration when needed.

To ensure interoperability between independently developed components, ccmjs relies on a set of established conventions. These conventions define common patterns for configuration structures, naming, and interaction between components. Following these 📏 ccmjs Conventions enables seamless composition and reuse across different projects and developers.

Similarly, ccmjs does not prescribe any specific HTML templating system. Component developers are free to choose how rendering is implemented.

Versioning and Isolation are core design principles of ccmjs. Both the framework and ccmjs components are explicitly versioned, allowing multiple framework versions and multiple versions of the same component to safely coexist on the same web page. Each component is bound to a specific ccmjs version and executes within its own namespace, preventing global conflicts and enabling independent evolution.

ccmjs follows a Security by Design approach. Components and instances are encapsulated and accessible only via explicit references. Immutable component registration prevents later modification. Subresource Integrity (SRI) ensures trusted resource loading. Shadow DOM isolation (open by default, configurable to closed or none) provides structural encapsulation.

ccmjs emphasizes Code Transparency as a first-class design principle. Each component is a standalone, human-readable file that can be inspected at runtime. There is no build step, bundling, or hidden abstraction layer. Developers can always access the original source code, understand how a component works, and debug it directly in the browser using source maps. This makes ccmjs particularly suitable for learning, teaching, and long-term maintainability.

Clone this wiki locally