BubbleScript schema
BubbleScript represents each Bubble app area with a small number of recognisable source shapes.
Use the generated types for exact syntax
The examples below show how the main structures work, not every available property.
The cloned workspace contains the canonical types for the current CLI and app under .buildprint/types. These types define the exact constructors, properties, names and references available to the agent.
Data types
A data type contains fields and can also contain privacy rules.
import {
currentUser,
dataType,
dataTypeRef,
thisItem,
} from "@buildprint/bubblescript";
export default dataType("Task", {
fields: [
{ display: "Title", type: "text" },
{ display: "Complete", type: "boolean", defaultValue: false },
{ display: "Owner", type: dataTypeRef("User") },
],
privacyRules: [
{
name: "Owner can view",
condition: thisItem()
.field("Owner")
.equals(currentUser()),
permissions: {
view_all: true,
search_for: true,
auto_binding: false,
view_attachments: false,
},
},
],
});Fields can contain built-in values, references to other data types, option-set values and lists. Privacy-rule conditions decide when the listed permissions are granted.
Option sets
An option set defines a fixed list of values and optional attributes for those values.
import { optionSet } from "@buildprint/bubblescript";
export default optionSet("Task Status", {
attributes: [
{ display: "Colour", type: "text" },
],
values: [
{ display: "To do", Colour: "#667085" },
{ display: "In progress", Colour: "#2E90FA" },
{ display: "Complete", Colour: "#12B76A" },
],
});The order of values is the order shown in Bubble. Each value can provide data for the attributes declared above it.
Pages and reusable elements
A UI root contains its Bubble settings and a nested tree of elements.
import {
button,
group,
page,
staticText,
text,
} from "@buildprint/bubblescript";
export default page("dashboard-page", {
name: "dashboard",
layout: {
container: "column",
width: "fill",
height: "fill",
},
properties: {
title: staticText("Dashboard"),
},
children: [
group("task-card", {
name: "Group task card",
layout: {
container: "column",
width: "fill",
height: "fit",
},
children: [
text("task-title", {
properties: {
text: staticText("Create the proposal"),
},
}),
button("complete-task", {
properties: {
text: staticText("Mark as complete"),
},
}),
],
}),
],
});A reusable element uses the same nested UI model with a reusable(...) root. Mobile views and global elements also have their own root constructors.
Elements and conditions
An element groups its settings by purpose and can include conditional overrides.
button("save-task", {
name: "Button save task",
layout: {
width: "fill",
height: "fit",
},
properties: {
text: staticText("Save task"),
},
conditions: [
condition({
when: currentPageWidth().lessThanOrEqual(600),
layout: {
width: "fill",
},
}),
],
})Different element constructors accept different properties. The generated types show what is available for a button, group, input, repeating group or another element.
Frontend workflows
A frontend workflow exports an event with actions that run in order.
import {
elementClicked,
goToPage,
pageRef,
} from "@buildprint/bubblescript";
export default elementClicked("Button open dashboard", {
actions: [
goToPage({
page: pageRef("dashboard"),
replaceHistory: false,
}),
],
});Frontend workflow files live with their page, reusable element or mobile view. The event determines when the workflow runs, and each action describes one Bubble operation.
Backend workflows
A backend workflow declares its parameters and server-side actions.
import {
apiWorkflow,
changeThing,
wfParam,
} from "@buildprint/bubblescript";
export default apiWorkflow("Complete task", {
parameters: [
{ name: "Task", type: "custom.task" },
],
actions: [
changeThing({
thing: wfParam("Task"),
fields: {
Complete: true,
},
}),
],
});Backend workflows can use backend actions and workflow parameters. UI-only actions and element references are not available in this context.
References and identities
References connect nodes without copying their full definition.
dataTypeRef("Task")
optionSetRef("Task Status")
pageRef("dashboard")
element("Button save task")
option("Task Status", "Complete")Existing nodes often include stable IDs. The agent keeps those IDs when renaming or editing a node so Buildprint updates the same Bubble object.
Deletion
Data types, fields, option sets, attributes and option values support soft deletion. At the moment, BubbleScript blocks hard-deletion on these node types as they are harder to recover.
{ id: "legacy_text", display: "Legacy", type: "text", deleted: true }Other node types have their own deletion rules. The agent uses buildprint check to review the planned deletion and any remaining references before applying it.
Use these shapes to understand BubbleScript. Use the generated types and buildprint check for the exact contract in a real workspace.