Filesystem
When you clone a Bubble branch, Buildprint writes a normalized filesystem projection of the Bubble app. This projection is designed for agents and git: small files, deterministic JSON, and ordinary diffs.
The filesystem is not a raw Bubble export. Volatile fields are stripped, derived fields are recomputed, and several Bubble fields are represented by directory placement instead of JSON properties.
Top-level layout
<app-root>/
.buildprint/
app.json
remote.git/
<branch>/
.git
.gitignore
app.json
settings/
data_types/
option_sets/
styles/
pages/
element-definitions/
mobile-views/
global-elements/
api/
tests/
issues/The app root is shared by every branch workspace for one Bubble app. The branch folder is the editable git worktree.
Branch folder contents
app.jsoncontains top-level Bubble app scalars.settings/client-safe.jsoncontains client-safe Bubble settings that were not lifted elsewhere.settings/api-connector/<plugin-id>/plugin.jsonandsettings/api-connector/<plugin-id>/calls/<call-id>.jsoncontain API Connector configuration.data_types/<type-id>/type.jsoncontains one Bubble data type. Fields and privacy roles stay inline.option_sets/<set-id>/option-set.jsoncontains one option set. Values and attributes stay inline.styles/<ElementType>/<style-id>.jsoncontains styles grouped by element type.styles/__bp_no_type__/contains styles whose source JSON has notypefield.styles/tokens.json,styles/defaults.json, andstyles/fonts.jsoncontain lifted design token and default style settings.pages/,element-definitions/,mobile-views/, andglobal-elements/contain canvas roots.api/contains backend workflows and workflow folders.tests/contains Buildprint project test definitions and reusable test components.issues/is a read-only projection of Bubble issue checker output. It is ignored during assemble/apply.
Canvas roots
Pages, reusable elements, mobile views, and global elements share the same shape:
pages/<page-key>/
page.json
elements/
<element-map-key>/
element.json
<child-map-key>/
element.json
workflows/
<workflow-key>/
workflow.json
actions/
0.json
1.jsonThe element folder name is the element map key from its parent's elements object. It is not necessarily the same as the id field inside element.json.
Child folders mirror Bubble containment. The parent body contains a children array, and buildprint check enforces that the set of child folders matches the set of entries in children. The order in children is the local display-order manifest.
Do not invent properties.order or properties.zindex. Those are real Bubble fields and are preserved only when Bubble emitted them.
Workflows and actions
Each workflow folder contains workflow.json and an actions/ folder. Action filenames are integer keys such as 0.json, 1.json, and 2.json; the filename is the execution order. Sparse integer keys are preserved when Bubble uses them.
Bubble workflow folders are represented by directories with config.json:
api/
billing/
config.json
create-order/
workflow.json
actions/0.json
orphan-workflow/
workflow.json
actions/0.jsonThe same folder structure applies below canvas workflow roots such as pages/home/workflows/.
properties.wf_folder is stripped from workflow bodies. To move a workflow between folders, move the workflow directory. To rename a folder, edit its config.json.
Tests as code
Buildprint project tests live under tests/:
tests/<folder-key>/
config.json
checkout.json
tests/__ungrouped__/
login.jsonProject tests are app-global rather than Bubble-branch-specific. project clone and sync materialize the current test snapshot into each branch workspace. apply sends changed test definitions back to Buildprint along with app changes. If only tests changed, apply can skip the Bubble write request and only apply the test-code changes.
Use buildprint new test and buildprint new test-step to create valid test files.
Canonical JSON
Every JSON file written by the CLI uses the same canonical format:
UTF-8, LF line endings, and a trailing newline.
Two-space indentation.
No tabs, CR characters, or trailing whitespace.
Non-integer object keys are alpha-sorted.
Integer-keyed maps preserve insertion order.
buildprint check formats changed JSON files before running rules. If a hand edit drifts, the canonical-form rule reports it.
IDs and filenames
Buildprint mints short bp IDs for new entities. For manual edits, generate fresh IDs with:
buildprint utils generate-ids 12The count must be between 1 and 1000. The command prints one ID per line in lexicographic order.
Existing Bubble apps can contain Bubble's native short IDs or timestamp-style IDs. Readers accept both. New Buildprint-authored entities should use generated Buildprint IDs.
What not to edit
Do not edit
.buildprint/or.git/internals.Do not add lifted fields back into body files, such as
properties.wf_folderon workflows ortypeon style bodies.Do not author unknown
_bp_*or__bp_*keys by hand.Do not treat
issues/as an editable source of truth.Do not add volatile Bubble fields such as
last_change,creation_date,screenshot, oruid_counter.
Git refs
The branch workspace is a normal git worktree. Useful refs:
refs/heads/<branch>is your local branch.refs/bubble/<branch>is the latest synced Bubble snapshot in the Buildprint bare repo.refs/published/<branch>tracks the last local commit successfully applied to Bubble.refs/remotes/buildprint/<branch>mirrors the published ref into the worktree.
Use git status, git diff, and git log buildprint/<branch>..HEAD like you would in any other git checkout.