diff --git a/docz/docs/03-demos/30-cloud/03-oraclecloud.md b/docz/docs/03-demos/30-cloud/03-oraclecloud.md
new file mode 100644
index 0000000..b1d315d
--- /dev/null
+++ b/docz/docs/03-demos/30-cloud/03-oraclecloud.md
@@ -0,0 +1,541 @@
+---
+title: Oracle Cloud Services
+pagination_prev: demos/local/index
+pagination_next: demos/extensions/index
+---
+
+import current from '/version.js';
+import CodeBlock from '@theme/CodeBlock';
+
+[Oracle Cloud Services](https://www.oracle.com/cloud/) (OCI) is a cloud services
+platform which includes traditional virtual machine support, "Serverless
+Functions" and cloud storage.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo demonstrates how to integrate SheetJS with Oracle `Visual Builder Studio (VBS)`[^2]
+to build a web application that handles Excel files. You'll learn to create an application
+that can import spreadsheet data, store it in `Business Objects`[^1], display it in a table, and
+export it back to Excel format.
+
+:::caution pass
+
+Oracle Cloud Services iterates quickly and there is no guarantee that the referenced services
+will be available in the future.
+
+:::
+
+:::note Tested Deployments
+
+This demo was last tested on 2025-02-04.
+
+:::
+
+
+## Visual Applications
+Oracle Cloud Services offers Visual Builder Studio a browser-based development environment for
+creating web applications with drag-and-drop components.
+
+
+## Installation
+SheetJS libraries conform to the Oracle Cloud Visual Builder Studio (VBS) ECMAScript[^5] requirements.
+SheetJS libraries can be loaded in Oracle VBS site at different points in the app lifecycle.
+
+#### Configure in app-flow.json
+
+The `app-flow.json` method is recommended as it aligns better with Visual Builder Studio's
+module management system.
+
+1. Click 📄 `Source` from the left sidebar
+2. Open `webApps/sheetjs_demo_app/app-flow.json`
+3. Add the following configuration after line 5:
+
+{`\
+"requirejs": {
+    "paths": {
+      "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"
+    }
+ }
+`}
+
+
+#### HTML {#installation-html}
+
+Oracle Cloud VBS is typically loaded in `SCRIPT` tag in `webApps/sheetjs_demo_app/index.html`. Similarly,
+[SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
+can be loaded with a `SCRIPT` tag in the same HTML page:
+
+{`\
+
+`}
+
+
+This will expose the `XLSX` global object, which includes the functions listed
+in the ["API Reference"](/docs/api/) section of the documentation.
+
+
+## Internal State
+
+The various SheetJS APIs work with various data shapes. The preferred state
+depends on the application.
+
+
+### Business Objects
+
+`Business Objects`[^1] in Oracle VBS provides a server-side model implementation for persistent data storage.
+Think of them as a combination of a data model and database table that handles both data storage and
+UI binding.
+
+#### Business Object Definition
+
+The example [presidents sheet](https://docs.sheetjs.com/pres.xlsx) has one header row with "Name" and "Index"
+columns. In Oracle VBS, we model this as a Business Object with corresponding fields:
+
+
+  | Spreadsheet | Business Object Definition | 
|---|
+  | +
+
+
+ | +
+```json
+{
+  "items" : [ {
+    "name": "Pres",
+    "fields": {
+      "name": {
+        "type": "string",
+        "label": "Name"
+      },
+      "index1": {
+        "type": "number",
+        "label": "Index"
+      }
+    }
+  }]
+}
+```
+
+ | 
+
+Here is how the data is represented when queried from the Business Object via REST call:
+
+```json
+{
+  "items": [
+    { "name": "Bill Clinton", "index1": 42 },
+    { "name": "GeorgeW Bush", "index1": 43 },
+    { "name": "Barack Obama", "index1": 44 },
+    { "name": "Donald Trump", "index1": 45 },
+    { "name": "Joseph Biden", "index1": 46 }
+  ]
+}
+```
+
+#### Updating Business Object
+
+Starting from a spreadsheet file, the SheetJS [`read`](/docs/api/parse-options) method parses the data into a workbook object. After
+selecting a worksheet, [`sheet_to_json`](/docs/api/utilities/array#array-output) generates row objects that can be created as Business Object
+records using the auto-generated REST API.
+
+Here is a sample flow diagram and method for downloading a workbook, generating rows from the first worksheet, and updating a `Business Object`[^1]:
+
+```mermaid
+flowchart LR
+    xlsx[(Remote\nFile)]
+    bo1[(Data\nArrayBuffer)]
+    wb(SheetJS\nWorkbook)
+    ws(SheetJS\nWorksheet)
+    json(JSON\nData)
+    bo2[(Business\nObject)]
+
+    xlsx --> |fetch\n\n| bo1
+    bo1 --> |XLSX.read\n\n| wb
+    wb --> |wb.Sheets\nselect| ws
+    ws --> |sheet_to_json\n\n| json
+    json --> |REST API\ncreate| bo2
+    linkStyle 1,2,3 color:blue,stroke:blue;
+```
+
+{`
+  define(['vb/action/actionChain', 'vb/action/actions', 'xlsx'], (ActionChain, Actions, XLSX) => {
+    class ButtonActionChain extends ActionChain {
+      async run(context) {
+        // fetch XLSX file
+        const data = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
+        const wb = XLSX.read(data);
+        // get the first worksheet
+        const ws = wb.Sheets[wb.SheetNames[0]];
+        // convert to json
+        const jsonData = XLSX.utils.sheet_to_json(ws);
+
+        // process each row and create business object records
+        for (const row of jsonData) {
+            const presData = {
+                name: row.Name,
+                index1: Number(row.Index)
+            };
+
+            // update business object with new record
+            await Actions.callRest(context, {
+                endpoint: 'businessObjects/create_Pres',
+                body: presData
+            });
+        }
+      }
+    }
+    return ButtonActionChain;
+  });
+`}
+
+
+#### Rendering Data
+In Oracle VBS, the table component `oj-table` supports direct binding to Business Objects for data display.
+The view structure defines both the data source binding and column layout:
+
+The following example uses the `Table`[^4] component to display data.
+
+{`\
+
+  // highlight-start
+  
+  
+  
+  // highlight-end
+
+`}
+
+
+
+#### Exporting Data
+The export functionality converts Business Object data into an Excel spreadsheet. The process involves retrieving data through
+REST API call, transforming it into a format suitable for SheetJS, and generating an XLSX file. Here's the complete flow:
+
+```mermaid
+flowchart LR
+    bo[(Business\nObject)]
+    rest(REST API\nCall)
+    json(JSON\nArray)
+    ws(SheetJS\nWorksheet)
+    wb(SheetJS\nWorkbook)
+    xlsx[(XLSX\nFile)]
+
+    bo --> |getall_Pres\nendpoint| rest
+    rest --> |transform\nresponse| json
+    json --> |json_to_sheet\n\n| ws
+    ws --> |book_new\n\n| wb
+    wb --> |writeFileXLSX\n\n| xlsx
+
+    linkStyle 2,3,4 color:blue,stroke:blue;
+```
+
+{`
+  define(['vb/action/actionChain', 'vb/action/actions', 'xlsx'], (ActionChain, Actions, XLSX) => {
+    class ButtonActionChain1 extends ActionChain {
+      async run(context) {
+        // get pres data
+        const presDataResponse = await Actions.callRest(context, {
+          endpoint: 'businessObjects/getall_Pres',
+          parameters: {
+            fields: 'name,index1'
+          }
+        });
+
+        // transform to simple array
+        const simplifiedData = presDataResponse.body.items.map(item => ({
+          Name: item.name,
+          Index: item.index1
+        }));
+
+        // generate workbook
+        const ws = XLSX.utils.json_to_sheet(simplifiedData);
+        const wb = XLSX.utils.book_new(ws, "Presidents");
+
+        // export to XLSX which triggers a download
+        XLSX.writeFileXLSX(wb, "SheetJSOracleVisualBuilderAoO.xlsx");
+      }
+    }
+    return ButtonActionChain1;
+  });
+`}
+
+
+:::note pass
+
+Visual Builder Studio provides a visual development environment and handles the build and
+deployment process automatically.
+
+:::
+
+
+## Importing Data {#importing-data-snippet}
+The import functionality enables data transfer from an Excel spreadsheet into your Oracle VBS
+application. The process begins by fetching the XLSX file, parsing it using SheetJS, and then
+creating corresponding Business Object records.
+
+```javascript title=""
+define([
+    'vb/action/actionChain',
+    'vb/action/actions',
+    'vb/action/actionUtils',
+    'xlsx'
+], (
+    ActionChain,
+    Actions,
+    ActionUtils,
+    XLSX
+) => {
+    'use strict';
+
+    class ButtonActionChain extends ActionChain {
+
+        /**
+         * @param {Object} context
+         */
+        async run(context) {
+            const { $page, $flow, $application, $constants, $variables } = context;
+
+            // fetch XLSX file
+            const url = "https://docs.sheetjs.com/pres.xlsx";
+            const data = await (await fetch(url)).arrayBuffer();
+            const wb = XLSX.read(data);
+
+            // get the first worksheet
+            const ws = wb.Sheets[wb.SheetNames[0]];
+
+            // convert to json
+            const jsonData = XLSX.utils.sheet_to_json(ws);
+
+            // process each row and create business object records
+            for (const row of jsonData) {
+                const presData = {
+                    name: row.Name,
+                    index1: Number(row.Index)
+                };
+
+                // create a business object record
+                await Actions.callRest(context, {
+                    endpoint: 'businessObjects/create_Pres',
+                    body: presData
+                });
+            }
+        }
+    }
+    return ButtonActionChain;
+});
+```
+
+## Exporting Data {#exporting-data-snippet}
+The export functionality allows you to convert Business Object data into Excel spreadsheets.
+This process involves retrieving data from the Business Object using REST API calls, transforming
+it into a format suitable for SheetJS, and generating an XLSX file.
+
+```javascript
+define([
+    'vb/action/actionChain',
+    'vb/action/actions',
+    'vb/action/actionUtils',
+    'xlsx'
+], (
+    ActionChain,
+    Actions,
+    ActionUtils,
+    XLSX
+) => {
+    'use strict';
+
+    class ButtonActionChain1 extends ActionChain {
+
+        /**
+         * @param {Object} context
+         */
+        async run(context) {
+            const { $page, $flow, $application, $constants, $variables } = context;
+
+            // get pres data
+            const presDataResponse = await Actions.callRest(context, {
+                endpoint: 'businessObjects/getall_Pres',
+                parameters: {
+                    fields: 'name,index1'
+                }
+            });
+
+            // transform to simple array
+            const simplifiedData = presDataResponse.body.items.map(item => ({
+                Name: item.name,
+                Index: item.index1
+            }));
+
+            // generate workbook
+            const ws = XLSX.utils.json_to_sheet(simplifiedData);
+            const wb = XLSX.utils.book_new(ws, "Presidents");
+
+            /* export to XLSX */
+            XLSX.writeFileXLSX(wb, "SheetJSOracleVisualBuilderAoO.xlsx");
+
+        }
+    }
+    return ButtonActionChain1;
+});
+```
+
+## Oracle Visual Builder Studio Web Applications Demo
+
+:::note pass
+
+At the time of writing, Oracle Cloud offers a 30-day free trial that includes
+Visual Builder Studio access.
+
+:::
+
+0. If you do not have an account create a new Oracle Cloud free tier account[^3].
+
+### Visual Builder Setup
+
+1. Sign in to the [Oracle Cloud Management Console](https://cloud.oracle.com/) with your created account.
+
+2. Type "Visual Builder Studio" in the top search box and click Visual Builder Studio (under services).
+
+
+
+3. Before creating Visual Builder Studio Instances we need to create an instance. Click `Visual Builder` from the left sidebar and click Create an instance.
+
+
+
+- Give it a name: `sheetjs-demo-vb-instance`
+- Select network access: `Default (No access rules.)`
+- Nodes: `1`
+
+4. Now click `Visual Builder Studio` from the left sidebar and click `Create Visual Builder Studio` and give it instance name: `sheetjs-vbs-instance` and click next and set
+   select compartment to `yourusername (root)`. Lastly, click `Create Visual Builder Studio` (this will take 5-15 minutes to fully setup).
+
+- Click link name `sheetjs-vbs-instance`
+
+5. Click `Service Console`  create a new project and fill it with the following inputs.
+
+- Project Details: `sheetjs-demo-project`
+- Project Template: `Empty Project`
+- Project Properties: `Markdown`
+- Click Finish
+
+6. Select `Project Home` from the left sidebar and create an environment.
+- Environment Name: `sheetjs-demo-env`
+- Click Create
+- Click `Add Instance`
+
+
+
+7. In Environments select the Service Instances tab and search for `Instance URL` if not shown click details to expand Visual Builder `sheetjs-demo-vb-instance` and open `Instance URL`
+   This will open Visual Builder Studio.
+
+8. Click `New Application` and set
+
+- Application Display Name: `sheetjs-vbs-demo`
+- Application Template: `Empty Application`
+- Click Finish
+
+9. Create a new Business Object by clicking **Business Object** card in the Welcome tab or from the sidebar as shown
+   
+
+- Name: `Pres`
+- Display: `President`
+
+10. Click `Pres` Business Object and select Fields tab. Then, create a new field by clicking the `+Fields` button and select first drop-down `Field`.
+
+- Label1: `Name`
+- Type1: Click `A` (`String`)
+
+- Label2: `Index`
+- Type2: Click `#` (`Number`)
+
+
+
+11. Click 🖥️ Web Applications from the left sidebar and create a new Web Application by clicking `+Web Application`
+    You should have the following fields.
+
+- Application Name: `sheetjs_demo_app`
+- Navigation Style: `None`
+- Click Create
+
+12. [Adding SheetJS Module](#installation) to the App Click 📄 `Source` from the left sidebar and paste the following on `webApps/sheetjs_demo_app/app-flow.json`
+
+{`\
+"requirejs": {
+    "paths": {
+      "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"
+    }
+ }
+`}
+
+
+
+
+
+13. Let's create the UI for our application we will be creating a table and two buttons one for import XLSX and one for export XLSX.
+
+- From the left sidebar click the 🖥️ `Web Applications` and select `main-start`
+- Select Page Designer and drag and drop two `Button` components and one `Table` Component to the canvas
+
+
+
+14. Creating our button event handler
+- Now select the left button in the canvas and on the right side on `General` tab set ID to `import-xslx` and label to `Import XLSX`.
+- Now select the `Events` tab and click `+ Event Listener` drop down button and select `On 'ojAction'`
+- Now it should auto-select `Action Chains` if not click from top tab option.
+- Switch from  `Design` to `Code` from top right
+
+
+
+15. Replace `Action Chains > ButtonActionChain > Code` with the importing data snippet in the
+    ["Importing Data"](#importing-data-snippet) example code.
+
+16. Now repeat step 14 for the second button
+- Now select the first button in the canvas and on the right side on `General` tab set ID to `export-xslx` and label to `Export XLSX`.
+- Now select the `Events` tab and click `+ Event Listener` drop down button and select `On 'ojAction'`
+- Now it should auto-select `Action Chains` if not click from top tab option.
+- Switch from  `Design` to `Code` from top right
+
+17. Replace `Action Chains > ButtonActionChain1 > Code` with the exporting data snippet in the
+    ["Exporting Data"](#exporting-data-snippet) example code.
+
+18. Connect the Business Object `Pres` to the table.
+- Now select `Page Designer` and in the canvas select the table component from the right sidebar select `Quick Start` and then `Add Data`
+- This opens up a modal on `Choose the source of your data` select `Pres` Business Object and click next.
+
+
+
+- On Bind Data step 2 from the left sidebar named `Endpoint Structure` check box `name` and `index1` then click next and lastly click finish.
+
+
+
+19. Testing the Application
+  - a) Launch the Preview:
+    - Look for the Play (▶️) icon in the top-right corner of the Visual Builder Studio
+    - Click it to open your application in a new browser tab
+  - b) Test the Import Function:
+    - In the preview tab, click the "Import XLSX" button
+    - Navigate back to Visual Builder Studio
+    - Select the `Pres` business object
+    - Click the "Data" tab
+    - Verify that new records have been created with the president names and index
+    - Return to your application preview tab
+    - Refresh the page
+    - You should now see the table populated with the imported president data
+  - c) Test the Export Function:
+    - Click the "Export XLSX" button
+    - This will trigger an automatic download of a file named "SheetJSOracleVisualBuilderAoO.xlsx"
+    - Open the downloaded file using a spreadsheet editor.
+    - Verify that the exported data matches what was displayed in your application's table
+
+[^1]: See Oracle VBS working with [Business Objects](https://docs.oracle.com/en/cloud/paas/visual-builder/visualbuilder-building-applications/working-business-objects1.html) for more detail.
+[^2]: [Oracle Visual Builder Studio](https://docs.oracle.com/en/cloud/paas/visual-builder/)
+[^3]: Registering for a free account [on the Oracle Cloud Free Tier](https://www.oracle.com/cloud/free/) requires a valid phone number and a valid credit card.
+[^4]: See [Oracle VBS Table Component](https://docs.oracle.com/en/middleware/developer-tools/jet/13/reference-api/oj.ojTable.html) for more details.
+[^5]: See ["JavaScript Support in Oracle VBS"](https://docs.oracle.com/en/cloud/paas/visual-builder/visualbuilder-building-applications/work-javascript-editor1.html?utm_source=chatgpt.com) for more details on custom JavaScript functionality and module handling.
diff --git a/docz/static/oraclecloud/action_chain_select_code.png b/docz/static/oraclecloud/action_chain_select_code.png
new file mode 100644
index 0000000..ba42b96
Binary files /dev/null and b/docz/static/oraclecloud/action_chain_select_code.png differ
diff --git a/docz/static/oraclecloud/adding_sheetjs_to_app.png b/docz/static/oraclecloud/adding_sheetjs_to_app.png
new file mode 100644
index 0000000..667b149
Binary files /dev/null and b/docz/static/oraclecloud/adding_sheetjs_to_app.png differ
diff --git a/docz/static/oraclecloud/bind_columns_to_fields_name_index1.png b/docz/static/oraclecloud/bind_columns_to_fields_name_index1.png
new file mode 100644
index 0000000..f94affe
Binary files /dev/null and b/docz/static/oraclecloud/bind_columns_to_fields_name_index1.png differ
diff --git a/docz/static/oraclecloud/connecting_business_object.png b/docz/static/oraclecloud/connecting_business_object.png
new file mode 100644
index 0000000..49ae39e
Binary files /dev/null and b/docz/static/oraclecloud/connecting_business_object.png differ
diff --git a/docz/static/oraclecloud/create_business_object.png b/docz/static/oraclecloud/create_business_object.png
new file mode 100644
index 0000000..e0d54c6
Binary files /dev/null and b/docz/static/oraclecloud/create_business_object.png differ
diff --git a/docz/static/oraclecloud/create_vb_instance.png b/docz/static/oraclecloud/create_vb_instance.png
new file mode 100644
index 0000000..8abb4bd
Binary files /dev/null and b/docz/static/oraclecloud/create_vb_instance.png differ
diff --git a/docz/static/oraclecloud/creating_new_fields_name_index.png b/docz/static/oraclecloud/creating_new_fields_name_index.png
new file mode 100644
index 0000000..cac2a7d
Binary files /dev/null and b/docz/static/oraclecloud/creating_new_fields_name_index.png differ
diff --git a/docz/static/oraclecloud/drag_drop_components_to_canvas.png b/docz/static/oraclecloud/drag_drop_components_to_canvas.png
new file mode 100644
index 0000000..a189194
Binary files /dev/null and b/docz/static/oraclecloud/drag_drop_components_to_canvas.png differ
diff --git a/docz/static/oraclecloud/env_connect_to_instance.png b/docz/static/oraclecloud/env_connect_to_instance.png
new file mode 100644
index 0000000..0f5c5ff
Binary files /dev/null and b/docz/static/oraclecloud/env_connect_to_instance.png differ
diff --git a/docz/static/oraclecloud/launch_instance.png b/docz/static/oraclecloud/launch_instance.png
new file mode 100644
index 0000000..9b3b438
Binary files /dev/null and b/docz/static/oraclecloud/launch_instance.png differ
diff --git a/docz/static/oraclecloud/search_box_visual_builder.png b/docz/static/oraclecloud/search_box_visual_builder.png
new file mode 100644
index 0000000..8556800
Binary files /dev/null and b/docz/static/oraclecloud/search_box_visual_builder.png differ