---
title: "Run Puck locally and assign data bindings"
section: "Builder Guide"
canonical_url: "https://support.buildwithhq.com/builder-guide/local-puck-binding-editor.html"
reviewed_at: "2026-09-14"
authority: Official
---

# Run Puck locally and assign data bindings

Open canonical BuildWithHQ page JSON in a self-contained local Puck editor, assign registered binding keys, and save a validated unpublished draft without exposing credentials to Vite.

## In brief

- **Editor:** Puck 0.23.0
- **Browser access:** Local files only
- **Remote save:** Trusted Node command

Developer Kit 1.20.66 contains a complete local Puck editor under `local-puck/`. It uses the same pinned Puck adapter, canonical page conversion, component catalogs and validation rules as the hosted BuildWithHQ designer. It is not a lookalike editor and it does not introduce another page format.

[Download Developer Kit 1.20.66](../downloads/BuildWithHQ-API43-Developer-Kit-1.20.66.zip) [Convert existing HTML first](html-to-puck-converter.html) [Component and theme guide](professional-template-foundation.html)

Note

The local browser opens and downloads files only. It receives no app credential, tenant data, database route, user identity, DataRole or Location. A separate Node command performs the optional authenticated draft save.

## Start the local editor

### Windows PowerShell

```
Expand-Archive.\BuildWithHQ-API43-Developer-Kit-1.20.66.zip.\bwhq-kit
cd.\bwhq-kit\local-puck
npm ci
npm run dev
```

### Linux or macOS

```
unzip BuildWithHQ-API43-Developer-Kit-1.20.66.zip -d bwhq-kit
cd bwhq-kit/local-puck
npm ci
npm run dev
```

Open `http://127.0.0.1:4175`. The server binds only to loopback and applies a restrictive local Content Security Policy. Dependency versions are pinned in `package-lock.json`, so use `npm ci`.

## Assign a binding visually

1. Select **Open page JSON** and choose a converted or existing canonical page file.
2. Select the block that should receive live data.
3. Choose a shipped key in **API data binding key (optional)**. The closed list comes from `catalog/bindings.json`, not a guessed module name.
4. Choose its bounded child path in **Nested API data path (optional)**.
5. Use **Advanced** only when this SaaS has separately installed a registered binding that is not in the distributed golden catalog. Manual text still has to pass real server validation.
6. Select **Save draft** or **Download JSON**. Both produce canonical BuildWithHQ page JSON; neither publishes.

```
{
  "_id": "home-work-table",
  "_type": "core.presentation-grid",
  "bindingKey": "work-orders.presentation",
  "dataKey": "table",
  "props": {}
}
```

Multiple blocks can reuse one binding and select different children. For example, a page can bind metrics, progress, a table and timeline to `work-orders.presentation` while choosing `metrics`, `byStatus`, `table` and `timeline` through each block's `dataKey`. The server executes the binding once under the signed-in user's real scope; the browser does not load a broad dataset and aggregate it itself.

Note

capabilities.json inventories modules and API routes; it is not an installed-binding registry. The separate bindings.json file contains the three presentation bindings shipped by the current golden tenant template: Work Orders, Checklists & Signoffs, and Contacts.

## What the editor can and cannot create

| Local action | Result |
| --- | --- |
| Set `bindingKey` | References an already installed and active server binding. |
| Set `dataKey` | Selects a bounded property from that binding's returned JSON document. |
| Type an unknown key | Does not create an API or SQL query; real server validation rejects the draft. |
| Download JSON | Writes a local canonical page document suitable for Git review, Puck, Monaco or the draft API. |
| Save through the trusted command | Uses the current page-version fence, creates immutable draft history and immediately runs server validation. |
| Publish | Not available in the local editor or draft command. Publication requires a separate live credential and exact validated history. |

## Save and validate a real unpublished draft

Keep the `bwk_draft_` credential in the terminal environment. Never put it in a `VITE_*` variable, frontend source, page JSON, browser storage or Git.

### Windows PowerShell

```
$env:BWHQ_SAAS_APP_ID = Read-Host "SaaS app ID"
$env:BWHQ_DRAFT_CREDENTIAL = Read-Host "Draft credential"
npm run save-draft -- --page.\home.page.json --page-key Home `
  --change-note "Local Puck binding edit"
```

### Linux or macOS

```
read -rp "SaaS app ID: " BWHQ_SAAS_APP_ID && export BWHQ_SAAS_APP_ID
read -rsp "Draft credential: " BWHQ_DRAFT_CREDENTIAL && export BWHQ_DRAFT_CREDENTIAL
npm run save-draft -- --page./home.page.json --page-key Home \
  --change-note "Local Puck binding edit"
```

`save-draft.mjs` calls the real Developer API. It gets the current `pageVersion`, saves with `expectedPageVersion`, then calls validation and returns the immutable `pageHistoryId`. A validation failure exits non-zero. The command never publishes and never logs the credential.

Important

A page can only reference a registered binding. Creating a new binding is a separate reviewed template/application contract. It must define a bounded operation and output shape and retain server-derived SaaS, AppAccount, user, DataRole and Location scope.

## Verify before use

```
npm ci
npm run build
```

The Developer Kit release gate also compares the distributed Puck adapter and page runtime with their production sources, hashes every local-editor file in the integrity manifest, and builds the extracted app before release.

---

Capability review: 2026-09-14. [View the canonical guide](https://support.buildwithhq.com/builder-guide/local-puck-binding-editor.html).
