{"id":40587318,"url":"https://github.com/ortus-docs/cbwire-docs","last_synced_at":"2026-01-21T03:07:52.524Z","repository":{"id":43374269,"uuid":"381728303","full_name":"ortus-docs/cbwire-docs","owner":"ortus-docs","description":"The official docs for cbwire.","archived":false,"fork":false,"pushed_at":"2025-12-03T04:57:50.000Z","size":13364,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":6,"default_branch":"v4.x","last_synced_at":"2025-12-06T01:53:21.887Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ortus-docs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-06-30T14:22:32.000Z","updated_at":"2025-11-22T14:08:26.000Z","dependencies_parsed_at":"2025-09-29T20:46:55.392Z","dependency_job_id":null,"html_url":"https://github.com/ortus-docs/cbwire-docs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ortus-docs/cbwire-docs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ortus-docs%2Fcbwire-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ortus-docs%2Fcbwire-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ortus-docs%2Fcbwire-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ortus-docs%2Fcbwire-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ortus-docs","download_url":"https://codeload.github.com/ortus-docs/cbwire-docs/tar.gz/refs/heads/v4.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ortus-docs%2Fcbwire-docs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28624344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T02:47:06.670Z","status":"ssl_error","status_checked_at":"2026-01-21T02:45:44.886Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-21T03:07:52.458Z","updated_at":"2026-01-21T03:07:52.513Z","avatar_url":"https://github.com/ortus-docs.png","language":null,"funding_links":["https://www.patreon.com/ortussolutions"],"categories":[],"sub_categories":[],"readme":"---\ndescription: \u003e-\n  CBWIRE is a ColdBox module that uses Livewire and Alpine.js to help you build\n  modern, reactive BoxLang and CFML applications in record time without building\n  backend APIs.\n---\n\n# Introduction\n\n\u003cfigure\u003e\u003cimg src=\".gitbook/assets/CBWIRE-Logo.png\" alt=\"\"\u003e\u003cfigcaption\u003e\u003c/figcaption\u003e\u003c/figure\u003e\n\nCBWIRE revolutionizes BoxLang and CFML web development by bringing reactive UI capabilities directly to your server-side code. Build dynamic, interactive interfaces without writing JavaScript, managing APIs, or dealing with complex frontend frameworks.\n\n## Your First Component\n\nLet's create a reactive counter component to demonstrate CBWIRE's power. Download and install [CommandBox](https://www.ortussolutions.com/products/commandbox), then run these commands:\n\n```bash\nmkdir cbwire-playground --cd\ninstall cbwire@4\ninstall commandbox-boxlang\ncoldbox create app\nserver start cfengine=boxlang javaVersion=openjdk21_jdk\n```\n\n### 1. Add Component to Layout\n\nInsert a counter component into your Main layout using `wire(\"Counter\")`:\n\n{% tabs %}\n{% tab title=\"BoxLang\" %}\n```html\n\u003c!-- layouts/Main.bxm --\u003e\n\u003cbx:output\u003e\n\u003c!doctype html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eCBWIRE Demo\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003c!-- Insert our reactive counter --\u003e\n        #wire(\"Counter\")#\n    \u003c/body\u003e\n\u003c/html\u003e\n\u003c/bx:output\u003e\n```\n{% endtab %}\n\n{% tab title=\"CFML\" %}\n```html\n\u003c!-- layouts/Main.cfm --\u003e\n\u003ccfoutput\u003e\n\u003c!doctype html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eCBWIRE Demo\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003c!-- Insert our reactive counter --\u003e\n        #wire(\"Counter\")#\n    \u003c/body\u003e\n\u003c/html\u003e\n\u003c/cfoutput\u003e\n```\n{% endtab %}\n{% endtabs %}\n\n### 2. Create the Component\n\nDefine your Counter [component](the-essentials/components.md):\n\n{% tabs %}\n{% tab title=\"BoxLang\" %}\n```javascript\n// wires/Counter.bx\nclass extends=\"cbwire.models.Component\" {\n    \n    data = {\n        \"counter\": 0\n    };\n\n    function increment() {\n        data.counter++;\n    }\n    \n    function decrement() {\n        data.counter--;\n    }\n}\n```\n{% endtab %}\n\n{% tab title=\"CFML\" %}\n```javascript\n// wires/Counter.cfc\ncomponent extends=\"cbwire.models.Component\" {\n    \n    data = {\n        \"counter\" = 0\n    };\n\n    function increment() {\n        data.counter++;\n    }\n    \n    function decrement() {\n        data.counter--;\n    }\n}\n```\n{% endtab %}\n{% endtabs %}\n\n### 3. Create the Template\n\nDefine the counter [template](the-essentials/templates.md):\n\n{% tabs %}\n{% tab title=\"BoxLang\" %}\n```html\n\u003c!-- wires/counter.bxm --\u003e\n\u003cbx:output\u003e\n\u003cdiv\u003e\n    \u003ch1\u003eCount: #counter#\u003c/h1\u003e\n    \u003cbutton wire:click=\"increment\"\u003e+\u003c/button\u003e\n    \u003cbutton wire:click=\"decrement\"\u003e-\u003c/button\u003e\n\u003c/div\u003e\n\u003c/bx:output\u003e\n```\n{% endtab %}\n\n{% tab title=\"CFML\" %}\n```html\n\u003c!-- wires/counter.cfm --\u003e\n\u003ccfoutput\u003e\n\u003cdiv\u003e\n    \u003ch1\u003eCount: #counter#\u003c/h1\u003e\n    \u003cbutton wire:click=\"increment\"\u003e+\u003c/button\u003e\n    \u003cbutton wire:click=\"decrement\"\u003e-\u003c/button\u003e\n\u003c/div\u003e\n\u003c/cfoutput\u003e\n```\n{% endtab %}\n{% endtabs %}\n\n### 4. See the Magic\n\nNavigate to your application in the browser. Click the + and - buttons to see the counter update instantly without page refreshes or JavaScript code! 🤯\n\n![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEWvXvmxEDxwnAJzKYkxz%2Fuploads%2FPESERLoILEJOeO4yXCCn%2F2022-02-08%2016.02.25.gif?alt=media\\\u0026token=7846eb9)\n\n## How Does It Work?\n\nCBWIRE seamlessly bridges your server-side BoxLang or CFML code with dynamic frontend behavior:\n\n1. **Initial Render**: CBWIRE renders your component with its default data values\n2. **User Interaction**: When a user clicks a button with `wire:click`, Livewire.js captures the event\n3. **Server Request**: The interaction triggers an AJAX request to your CBWIRE component's action method\n4. **Data Processing**: Your server-side action method processes the request and updates component data\n5. **Response \u0026 Update**: The updated HTML is sent back and Livewire.js efficiently updates only the changed parts of the DOM\n\nThis approach gives you the responsiveness of modern JavaScript frameworks while keeping your logic in familiar server-side code.\n\n## Why CBWIRE?\n\nBuilding our reactive counter with CBWIRE meant we:\n\n* ✅ **Developed a responsive interface** without writing JavaScript\n* ✅ **Avoided creating backend APIs** - everything stays in your ColdBox application\n* ✅ **Eliminated page refreshes** while maintaining server-side control\n* ✅ **Skipped complex build processes** like webpack or JavaScript compilation\n* ✅ **Stayed in our BoxLang/CFML environment** using familiar syntax and patterns\n\n## Better With Alpine.js\n\nWhile CBWIRE handles server communication beautifully, sometimes you need instant client-side updates without server round-trips. This is where [Alpine.js](https://alpinejs.dev/) shines - a lightweight JavaScript framework designed to work perfectly with Livewire (and therefore CBWIRE).\n\nLet's enhance our counter to use Alpine.js for instant updates and add persistence:\n\n{% tabs %}\n{% tab title=\"BoxLang\" %}\n```javascript\n// wires/Counter.bx\nclass extends=\"cbwire.models.Component\" {   \n    \n    data = {\n        \"counter\": 0\n    };\n\n    function onMount() {\n        data.counter = session.counter ?: 0;\n    }\n    \n    function save(counter) {\n        session.counter = arguments.counter;\n    }\n}\n```\n{% endtab %}\n\n{% tab title=\"CFML\" %}\n```javascript\n// wires/Counter.cfc\ncomponent extends=\"cbwire.models.Component\" {   \n    \n    data = {\n        \"counter\" = 0\n    };\n\n    function onMount() {\n        data.counter = session.counter ?: 0;\n    }\n    \n    function save(counter) {\n        session.counter = arguments.counter;\n    }\n}\n```\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"BoxLang\" %}\n```html\n\u003c!-- wires/counter.bxm --\u003e\n\u003cbx:output\u003e\n\u003cdiv \n    x-data=\"{\n        counter: $wire.counter,\n        increment() { this.counter++; },\n        decrement() { this.counter--; },\n        async save() {\n            await $wire.save(this.counter);\n        }\n    }\"\n    wire:ignore.self\u003e\n    \n    \u003ch1\u003eCount: \u003cspan x-text=\"counter\"\u003e\u003c/span\u003e\u003c/h1\u003e\n    \u003cbutton @click=\"increment\"\u003e+\u003c/button\u003e\n    \u003cbutton @click=\"decrement\"\u003e-\u003c/button\u003e\n    \u003cbutton @click=\"save\"\u003eSave\u003c/button\u003e\n\u003c/div\u003e\n\u003c/bx:output\u003e\n```\n{% endtab %}\n\n{% tab title=\"CFML\" %}\n```html\n\u003c!-- wires/counter.cfm --\u003e\n\u003ccfoutput\u003e\n\u003cdiv \n    x-data=\"{\n        counter: $wire.counter,\n        increment() { this.counter++; },\n        decrement() { this.counter--; },\n        async save() {\n            await $wire.save(this.counter);\n        }\n    }\"\n    wire:ignore.self\u003e\n    \n    \u003ch1\u003eCount: \u003cspan x-text=\"counter\"\u003e\u003c/span\u003e\u003c/h1\u003e\n    \u003cbutton @click=\"increment\"\u003e+\u003c/button\u003e\n    \u003cbutton @click=\"decrement\"\u003e-\u003c/button\u003e\n    \u003cbutton @click=\"save\"\u003eSave\u003c/button\u003e\n\u003c/div\u003e\n\u003c/cfoutput\u003e\n```\n{% endtab %}\n{% endtabs %}\n\nNow the counter updates instantly on the client side, but only makes server requests when \"Save\" is clicked to persist the value. The `onMount()` method loads the saved counter from the session on page load. Using `$wire`, Alpine.js communicates seamlessly with your CBWIRE component.\n\nThis combination gives you complete control: instant UI feedback when needed, and server communication when you want to persist data or run complex business logic.\n\n## What's Next?\n\nReady to dive deeper? Explore these essential concepts:\n\n* [**Getting Started**](getting-started.md): Complete installation and setup guide\n* [**Components**](the-essentials/components.md): Learn how to build and organize CBWIRE components\n* [**Templates**](the-essentials/templates.md): Master template syntax and data binding\n* [**Actions**](the-essentials/actions.md): Handle user interactions and component methods\n* [**Properties**](the-essentials/properties.md): Understand data binding and reactivity\n* [**Events**](the-essentials/events.md): Communicate between components and handle lifecycle events\n\n## Credits\n\nCBWIRE leverages the incredible JavaScript libraries [Livewire](https://laravel-livewire.com/) and [Alpine.js](https://alpinejs.dev/) for DOM diffing and client-side functionality. CBWIRE wouldn't exist without the brilliant work of [Caleb Porzio](https://x.com/calebporzio), creator of both Livewire and Alpine.js. CBWIRE brings these powerful tools into the ColdBox and BoxLang/CFML ecosystem.\n\nThe CBWIRE module is developed and maintained by [Grant Copley](https://twitter.com/grantcopley), [Luis Majano](https://twitter.com/lmajano), and the team at [Ortus Solutions](https://www.ortussolutions.com/).\n\n## Project Support\n\nPlease consider becoming one of our [Patreon supporters](https://www.patreon.com/ortussolutions) to help us continue developing and improving CBWIRE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fortus-docs%2Fcbwire-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fortus-docs%2Fcbwire-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fortus-docs%2Fcbwire-docs/lists"}