How NodeGX stores an app
A NodeGX project is a folder of plain text files. Claude reads and changes those files through the NodeGX connector, which checks every change before it is saved.
What is in the folder
A recent project looks like this (trimmed):
My app/
├── nodegx.project.json settings, design tokens, the link to a backend
├── components/
│ ├── _registry.json the list of every component
│ ├── App/
│ ├── Components/PuppyCard/
│ │ ├── component.json its name, path and type
│ │ ├── nodes.json the nodes and their settings
│ │ └── connections.json the wires between them
│ └── Pages/Landing/
├── docs/ the brief and build plan from scoping
├── noodl_modules/ fonts and icon sets
├── CLAUDE.md a note for AI tools opened in this folder
└── .mcp.json connects Claude to this projectEvery file is JSON (a plain text format for structured data) or Markdown. You can open any of them in a text editor.
Components, nodes and wires
A component is a reusable piece of the app: a page, a card, a form. Each one is a folder with three files.
nodes.json lists the component's nodes. Each node has an id, a type, a label and its settings. Visual nodes also name their parent and children, which is how the screen's layout is stored. This is the text on a real puppy card (a few settings trimmed):
{
"id": "breedText",
"type": "Text",
"label": "Breed",
"parameters": {
"fontSize": "var(--text-sm)",
"color": "var(--primary)"
},
"parent": "body-2"
}connections.json holds the wires. Each wire runs from one node's output to another node's input:
{
"fromId": "cardInputs",
"fromProperty": "breed",
"toId": "breedText",
"toProperty": "text"
}Here cardInputs is the card's Component Inputs node: the list of values the card accepts. This wire sends the card's breed value into the Text node above.
Why plain files suit AI and git
Claude can read them. A graph stored as text is something Claude reads the same way it reads code.
Git can compare them. A change shows up as a few changed lines. Swapping a colour on one card is one line in one nodes.json. See GitHub basics.
You and Claude can both work on them. NodeGX reads the files fresh from disk. If a file has changed since Claude last read it, because you saved in the editor for example, Claude's write is refused instead of overwriting your work. Claude then has to read it again. Changing things yourself covers this.
Do not edit the JSON by hand. It skips the checks below, and a broken file often still loads, which makes the mistake hard to find later. CLAUDE.md tells AI tools the same thing.
The brief and the build plan
When Claude creates a project, it first scopes the app with you. It then writes that conversation into docs/:
| File | What it holds |
|---|---|
docs/BRIEF.md | What the app is, who uses it, and what it deliberately does not do |
docs/ARCHITECTURE.md | The page map, the data model and the backend |
docs/CONVENTIONS.md | Rules for how this app is built. Editing it changes what gets built |
docs/decisions/000-initial-scope.md | The full record: what you asked for, what was decided, what was rejected, what is still open, the proposed build plan and the conversation itself |
The build plan has one step for each page you agreed. It is written down but not run. A new project holds only an empty App and Home page until you have reviewed the plan and asked Claude to build it.
Every change is checked
Every write goes through validation: a check against NodeGX's file format and its rules about how nodes fit together. The check runs before any file is created. A rejected write leaves nothing on disk and comes back to Claude with an explanation and a suggested fix.
For a bigger job, Claude uses a plan. It adds each component to the plan, and nothing is written to disk until the plan is applied in one go.
The style vocabulary
Nodes do not store raw colours or sizes. They store design tokens: named styles such as --primary, --space-5 or --radius-xl, written in a node's settings as var(--primary).
The project's own token values are kept in nodegx.project.json. Change one, and every node that uses it changes. The connector tells Claude to read the full list before it builds anything bigger than a small fix, so a new page matches the rest. Describing how it should look shows how to use this.
The local backend
An app with Record, User or Cloud Function nodes needs a backend (somewhere to save data and user accounts). Claude sets one up on your computer, starts it and links it to the project. It can create the collections (tables of records) the app needs at the same time.
The backend's data lives in NodeGX's own folder on your computer (~/.noodl/backends), not in the project folder. The project stores the link to it, in nodegx.project.json (trimmed):
"cloudservices": {
"endpoint": "http://localhost:8581",
"type": "nodegx"
}So your saved records do not go into git with the project. A live app needs a backend of its own: see Putting your app online.
The render check
After Claude builds anything visual, it can render the project: run it without a window and take screenshots. It gets back measurements and the pictures, and looks at them to check its own work. A graph says what should appear. A render shows what does.
The observe connector
The observe connector is a second connector that watches the app while it runs in NodeGX. You set it up from Editor Settings.
It lets Claude list the nodes in the running app, read a value on any of them, and click or type in the app. The main loop is: start a trace, reproduce the problem (Claude can click, or you can), then ask why a value on screen is empty. It works out from the graph and the trace where the data stopped.
Try it when something shows the wrong thing or nothing at all:
The puppy list on the Landing page is empty. Use the observe connector to trace it and find where the data stops.Quick reference
- A project is a folder of plain files. Each component is a folder with
component.json,nodes.jsonandconnections.json. - Nodes hold settings; wires run from one node's output to another's input.
docs/holds the brief, the conventions and the build plan from scoping.- Every write is validated first. A rejected write changes nothing.
- Styles are design tokens (
var(--primary)), stored innodegx.project.json. - Backend data lives in
~/.noodl/backends, outside the project folder. - The render check and the observe connector let Claude see what the app really does.