-
Notifications
You must be signed in to change notification settings - Fork 0
Home
The Client-side Component Model (CCM) defines a conceptual framework for developing modular and reusable web components. The ccmjs framework provides the official JavaScript reference implementation of this model.
While W3C Web Components focus on extending HTML, ccmjs focuses on JavaScript-based composition and JSON-driven configuration.
Unlike frameworks such as Angular, React, or Vue, ccmjs composes components at runtime. Components are loaded, configured, and instantiated dynamically in the browser — without a build step or bundler, and without prior compilation.
ccmjs components are configured via declarative data and resolve their dependencies on demand. This enables highly dynamic applications where structure and behavior can change at runtime.
With the JavaScript command ccm.start(component, config, area), a component (component) with a specific configuration (config) can be embedded in a web page area (area). The combination of the component and its configuration results in a concrete application instance, which is then rendered into the specified area of the web page.
As soon as ccmjs is integrated into a web page, ccm.start() is available.
Here is an example of embedding a quiz app:
<!DOCTYPE html>
<meta charset="UTF-8">
<body>
<script src="https://ccmjs.github.io/framework/ccm.js"></script>
<script>
ccm.start("https://ccmjs.github.io/quiz/ccm.quiz.mjs", {
feedback: true,
questions: [
{
text: "Does this example work?",
input: "radio",
answers: [
{text: "Yes", correct: true},
{text: "No"}
]
}
]
}, document.body);
</script>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 () {
this.start = async () => {/*...*/}; // the web page area of the component is designed here
}
};Within the start() the web page area to be designed can be accessed with 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.
ccmjs offers the following services:
-
Embedding Components:
ccm.start(),ccm.component(),ccm.instance() -
Loading Resources:
ccm.load() -
Data Management:
ccm.store(),ccm.get()
In addition, ccmjs also offers useful Helper Functions for component developers under ccm.helper.
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].
Examples:
const config = {
html: ["ccm.load", "./templates.html"], // 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 CCM are expressed declaratively and resolved automatically at runtime.
ccmjs intentionally keeps its core minimal. 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.
Similarly, ccmjs does not prescribe a specific HTML Templating system.
Component developers are free to choose how rendering is implemented.
For convenience, ccmjs offers optional utilities such as <ccm-template> for HTML templates
and JSON-based HTML representation, which can be used but are not required.
In addition to JavaScript-based embedding, ccmjs also supports declarative component embedding via HTML:
<!DOCTYPE html>
<meta charset="UTF-8">
<body>
<script src="https://ccmjs.github.io/framework/ccm.js"></script>
<ccm-app component="./ccm.hello.mjs" config='{"name":"Mika"}'></ccm-app>This feature is optional and intended as a convenience mechanism.
The primary and recommended interaction model of CCM remains explicit embedding via JavaScript (ccm.start()),
which enables dynamic composition, runtime configuration, and full programmatic control.
Versioning and Isolation are core design principles of ccmjs. Both the framework and CCM 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.