Introduction
CBWIRE is a ColdBox module that uses Livewire and Alpine.js to help you build modern, reactive CFML applications in record time without building backend APIs.

Your First Component
Download and install CommandBox. From your CLI, start CommandBox by typing 'box'. Then run the following:
mkdir cbwire-playground --cd
coldbox create app
install cbwire@4
server start
Let's insert a counter element into our Main layout using wire( "Counter" ).
<!--- ./layouts/Main.cfm --->
<cfoutput>
<!doctype html>
<html>
<body>
<!--- Insert a counter here --->
#wire( "Counter" )#
</body>
</html>
</cfoutput>
Let's define our Counter component.
// ./wires/Counter.cfc
component extends="cbwire.models.Component" {
// Data properties
data = {
"counter": 0 // default value
};
// Action
function increment() {
data.counter++;
}
}
Finally, define our counter template.
<!--- ./wires/counter.cfm --->
<cfoutput>
<div>
<div>Count: #counter#</div>
<button wire:click="increment">+</button>
</div>
</cfoutput>
You now have a reactive counter that increments when you click the plus button without any page refreshing or writing JavaScript! 🤯
What!? How?
CBWIRE renders the component with default values (starting at 0).
A button click triggers Livewire.js to send a request to the server.
CBWIRE processes the request, runs
increment()
, and updates the data.The updated HTML is sent back in the response.
Livewire.js refreshes the display using DOM comparison.
Awesome, right?
We developed a responsive counter.
We avoided writing any JavaScript code.
We didn't need to create an API.
There was no need for page refreshes.
We skipped using webpack or dealing with JavaScript compilation.
We stayed entirely within the CFML environment. 🤓
Better With Alpine
The example shows how easily components interact with your CFML back-end. But for quick UI updates, JavaScript can handle changes without unnecessary server requests. While we don’t need a request to increment the counter, we might if we want to save it. This is where CBWIRE and Alpine work perfectly together.
Alpine.js is a lightweight JavaScript framework that was built for simplicity and designed to work alongside Livewire ( and therefore CBWIRE ).
Below, let's change our component to use Alpine.js and add a method to save the counter.
// ./wires/Counter.cfc
component extends="cbwire.models.Component" {
data = {
"counter": 0
};
function onMount() {
// Load the counter from the session
data.counter = session.counter ?: 0;
}
function save( counter ) {
// Save the counter to the session
session.counter = arguments.counter;
}
}
<!--- ./wires/counter.cfm --->
<cfoutput>
<div
x-data="{
counter: $wire.counter,
increment() {
this.counter++
},
async save() {
// Call the save method on our component
await $wire.save( this.counter );
}
}"
wire:ignore.self>
<div>Count: <span x-text="counter"></span></div>
<button @click="increment">+</button>
<button @click="save">Save</button>
</div>
</cfoutput>
The counter updates instantly on the client side, sending a server request only when clicking "Save" to store the value in the session. On page load, onMount()
sets the counter from the session. Using $wire
, Alpine communicates with the component, giving full control over server requests. CBWIRE is redefining CFML development—we think you'll love it!
Credits
CBWIRE uses the JavaScript bits from Livewire and Alpine.js for its DOM diffing and client-side functionality. CBWIRE wouldn't exist without the incredible work of Caleb Porzio, the creator of both Livewire and Alpine. CBWIRE was created to bring these excellent tools into the ColdBox and CFML ecosystem.
The CBWIRE module for ColdBox is written and maintained by Grant Copley, Luis Majano, and Ortus Solutions.
Project Support
Please consider becoming one of our lovingly esteemed Patreon supporters.
Last updated
Was this helpful?