Data Apps - Nash App Builder UI
App Builder lets you describe a Data App to Nash and watch it take shape in a live preview, with nothing to install. To build with code and the CLI instead, see the Data App quickstart. Not sure which to use? See Choose how to build.
Nash App Builder (Builder) is in Private Preview and is off by default. Builder prepares the starter and installs its packages; Nash edits the saved project using Builder’s tools. Use your normal Astrato login. The CLI installation, terminal login and local-server steps in the external workflow do not apply here.
Where enabled, open Analytics → Apps → Create → App, then select a semantic layer. You can also choose Create app beside the workbook controls in the full Semantic Layer Editor. The creation form preselects that layer; you can change it before submitting. Opening the form creates nothing. Choose Create app in the form to create your private app, then describe what you want to build in its empty Nash conversation. In Nash, the open app is the default target for app edits. Live preview uses published dimensions and measures; publish semantic changes before querying new items. Nash can read and run the draft business questions of the app’s own semantic layer, as long as they use published items. On any other layer it uses published questions.
App projects and versions are independent of publications: developing and previewing an app does not require publication permission. Projects are currently private to their creator; shared app access controls are not available. Opening a project automatically connects this browser for editing through Nash and external MCP tools when its editing lock is available.
One browser can edit an app at a time. Other tabs show Viewing app, display its latest compiled preview and identify the current editor. Open Builder tabs receive saved changes, preview updates and editing status without reloading the page. After 60 seconds without a heartbeat, the editor loses ownership and another tab of the same user can acquire it. A newly opened tab waits for the editing lock to become available and connects automatically when the other editing session ends. Nash builds and checks the preview in the tab that is editing, so a message sent from a tab showing Viewing app waits, and Nash says the app is being edited in another tab. Send from that tab instead, or close it: this tab then takes over editing and Nash starts on your message. If your editing session ends or is paused, choose Resume editing, then send Nash a continuation request. Brief connection interruptions retry automatically while the editing session remains valid. Closing the browser stops compilation; execution does not move to another computer automatically.
In Analytics → Apps, use Drafts to find your private app projects before their first publication. All combines these drafts with publications in the same searchable list or grid. Choose a draft to continue in App Builder. Once linked to a publication, it appears under that publication’s Published or Unpublished status, with Edit app returning to its source project.
To rename an app while editing, hover over its title and select the pencil. Press Enter or click outside the field to save; press Escape to cancel.
Builder uses the standard Astrato navigation and Nash panel on the left. Switch between Preview and Source files beside the conversation. The shared Nash panel provides model selection and its normal conversation modes. Privacy mode keeps the conversation in your browser, while app files and versions are saved on the server. Inference still sends relevant conversation and preview images to your configured AI provider. You can send your first request while Builder is still preparing the app. Nash keeps it, shows that Builder is preparing, and starts on it as soon as Builder is ready for editing. Choose Edit to take it back into the message box. If Builder is not ready within five minutes, for example because the app is still being edited in another tab, the request returns to the message box unsent. Builder source and version history belong to the server project. Edit app opens that project; publication permissions alone do not grant access to its editable source.
Nash uses Astrato visualizations for charts and analytical data tables, with live data from the selected semantic layer. For scalar KPI cards, Nash chooses native numbers or ordinary app UI according to the presentation needed, without a renderer exception. Decorative SVG and ordinary UI remain available. The shared chart rendering policy requires your direct, specific instruction for another chart or analytical-table solution, or a verified current capability gap and your explicit approval, normally after offering a viable Astrato alternative. Copying data into app source or bundled assets requires a separate explicit request for static or mock data. Build or query errors should be repaired or reported, not hidden behind static sample data. Nash’s activity list identifies preview builds, inspections, documentation reads, commands and preview interactions separately. A documentation read names the page and section, and routine reads of the app’s source fold into one counted row.
For static copy or surrounding style edits, Nash’s workflow calls for reading the current affected source and preserving queries, field bindings, visualization definitions, filters and null handling. It builds and inspects the changed result, checking the desktop layout and controls the edit can affect. Data-dependent annotations, units and currency still need semantic checks. Unrelated problems should be reported separately instead of silently changing the app’s analytics.
An inspection shows only the page on screen. After a change that reaches more than one page, or something pages share such as navigation or a filter, Nash opens each page the change could affect and inspects it once before it reports. A new multi-page app counts as every page. Nash says which pages it checked and which it did not, for example when a long turn ran short or the preview was not on screen.
A large request can take more than one turn. In a This device only chat without browser-private recovery, a reply ends with its connection, so when time runs short Nash stops starting new work and reports what it finished, what it checked and what is left. You can send a message to continue from there.
In every chat, a summary Nash has written stays on screen while it makes a last check, and the updated summary replaces it when it is ready. If the AI model reaches its output limit during a request, Nash stops that step and reports what is saved and what is not finished. A short notice stands in if it cannot write that summary. Your saved changes are kept either way, so you can send a message to continue.
Builder’s WebFetch tool is restricted to the documentation site configured for its environment
unless additional sites are explicitly approved. Its activity shows the page being read and any
continuation, and reports missing pages or refused redirects explicitly. It defaults to https://docs.astrato.io, starts
at the site’s /llms.txt index and prefers its exact plain-text or Markdown reference links over HTML pages.
It follows index continuations instead of guessing text-page URLs. Pages may be up to 3 MB; oversized
responses report the limit and suggest a smaller page or a linked text version. Its instructions identify the
available sites. Documentation reads do not
require the editing browser to remain connected. Building, inspecting and editing the app still
require their normal connection and editing authority. Current documentation does not establish
compatibility with every project’s installed packages. Nash should check the app’s saved package
versions before using an API, then verify the build, startup, relevant data bindings and controls.
Documentation reads change neither saved source nor published files.
A link to a section of a plain-text or Markdown page, such as one ending in #setnumberfontsize,
returns only that section; if no heading matches, Nash receives the page’s headings instead of its
start.
When you ask for a dashboard without saying what it should show, Nash reads the semantic layer first and works out which questions the data can answer, so a short or vague request still gets a full dashboard. Views with no join between them each get their own labelled section, and Nash tells you which parts aren’t connected and what it left out. On a very large layer it reads part of the layer and tells you what the dashboard leaves out. When you name what you want, such as the measures, breakdowns or a chart, Nash builds that and then suggests what else the data could show. Ask for something small if that is what you want. Nash asks at most three questions, and only about what the layer cannot settle and no sensible default answers: which measure you mean when several fit, the period, the grain, the comparison or the decision the dashboard serves. It tells you the defaults it chose for the rest. It then plans each panel with fixed rules for the chart form and a descriptive title and subtitle. A title states a finding only when the app works it out from live results, so it stays true as data and selections change. Nash then builds straight away, however many pages or charts the plan has. A small working version reaches the preview first, and Nash adds to it in steps, saving each one, so you see progress early. If a request stops before it finishes, Try again carries on from what was saved.
Nash saves business questions alongside a dashboard, for reuse once the layer is published. The app can’t read them and runs its own queries on published items, so it doesn’t wait for that. Nash reuses the questions that fit. When a layer has none, or they leave part of the dashboard uncovered, Nash saves the few that matter to the layer’s draft after the first build, without asking. It then carries on with the work and names them in its closing summary, with any further views worth building; ask in the chat if you want more questions saved. It never replaces a question someone else saved, and it never publishes the layer: the questions stay in the draft until you publish it. If you can’t edit the layer, Nash builds the same app without saving and tells you so.
For a new app or a redesign, Nash starts from your direction and works out the layout, style, palette and type from the app’s subject, reader and data, so apps on unrelated subjects look different. Each page leads with what the data says, built from live results, with comparisons and change over time where the data allows them. Nash makes one design pass once the app works. Asking it to improve how an app looks recomposes the page rather than only changing its colours; metrics, bindings and interactions stay as they are. Give Nash your brand’s colours, logo and font names, because it cannot read other websites. Account review shows a live takeaway in one complete app.
Before finishing, Nash checks that a new dashboard uses what the data offers. It also reviews the latest preview screenshot for weak hierarchy, cramped or truncated content, blank charts and a generic look, and fixes what it can see, once per request. A chart that mounts and returns data can still fail this review if its labels are too small to read. If no screenshot is available, for example while Builder is not on screen, Nash carries on with everything else and reports the visual check as pending. Nash restores your preview size if it changed it to test the app.
When it has a screenshot, Nash also reads what the page says, because a label, sentence or comparison can render fine and still be false. When a request adds or changes a comparison, Nash checks the view the page opens on, the range it chose and periods with missing or partial earlier data. Where there is no complete earlier period, the app leaves the comparison out or says why. Any chart can be clicked, so a chart Nash adds comes with a visible way to clear that click, even if you never asked for interaction.
After building a dashboard, Nash checks the preview as it is drawn. It looks for text that is cut
off, overlapping or smaller than 10px, charts too small to read, charts that return no rows, and
charts that show several series without a legend. It also compares each chart with the plan: the
chart type, the sort, the date grain and the aggregation. Nash repairs what fails and checks again.
These checks see the charts of apps that register their visualization runtime with the preview, as
new apps do in src/astrato.ts; give each chart’s query the chart’s instance id as its object id.
A new app opens with an empty Nash conversation. Reopening an app restores the last selected conversation started for that app. Opening another app’s or workspace conversation from chat history does not replace that selection. The untouched starter shows Your preview will appear here. Later setup revisions show Preparing your preview until the app code is connected and built; saving files or installing packages alone is not a completed preview. Once an authored preview is available, it stays visible while later revisions build.
The editing connection renews while Builder receives live updates, including when background-tab timers slow down. If that connection is lost, Resume editing reconnects without a page refresh and clears the editing notice. Saved source is preserved, and unrelated build errors stay visible. If Nash stopped during the interruption, send a message to continue its work.
Live updates retry temporary connection failures with increasing delays, up to three times. If retries stop, choose Retry live updates after checking your connection. Sign-in, access, missing-app and invalid-data failures stop automatic retries and show guidance. Resolve the reported problem, then retry; if invalid data persists, reload Builder. Retrying live updates preserves saved source and build errors. A lost editing session still requires Resume editing.
You do not need to upgrade the Builder engine for each app. Builder uses the current engine when it next runs a build or project command; the saved preview can reopen immediately. If an engine update is briefly out of sync, Builder automatically tries again twice before showing an error. Retry the failed action shortly afterwards if the update is still in progress. Updating Builder does not choose different library versions for your app.
Source files and preview
Section titled “Source files and preview”Use Source files to browse the folder tree and open files in tabs. A dot marks unsaved edits. Press Cmd+S (Mac) or Ctrl+S to save the active file, or choose Save all. Switching files preserves unsaved edits. If Nash changes a file you are editing, compare your text with the server version before choosing which to keep. Failed saves preserve your text.
Saving builds a new preview; unsaved text does not change it. The header shows the saved version and identifies an older preview while the build catches up. Temporary connection failures show a retrying notice while Builder retries automatically a limited number of times. If the build still fails, correct any source errors and save, or choose Retry preview to rebuild the saved version. A successful preview for the current saved version clears its build error and retry option, including when Nash builds it. If a newer version is saved while a build runs, Builder discards the older build without an error and builds the newer version. Errors from other operations remain visible. Compilation errors appear immediately without automatic connection retries. Network interruptions while loading compiler assets or uploading the preview use the bounded automatic retry instead. Preview ready confirms that the saved source built; it does not confirm that the app rendered correctly. Nash can inspect the current preview for runtime errors and check the visible result before reporting success. When the app reports errors while it runs, a notice at the bottom of the preview summarizes them, for example a visualization that uses a setting it doesn’t support. Choose Show details to see the technical messages, and Copy details to copy them. Nash sees the same errors when it checks the preview, so you can ask it to fix them. Errors stay listed until the preview reloads, even if the app has since recovered. Choose Reload preview to start the app again in the version the preview shows, for example when the preview has stopped. It doesn’t build newer saved changes. A dismissed notice returns when a new error appears. When an action Nash requested in Builder fails, the header names it, for example Preview inspection failed. Choose Details for the reason and the technical message Nash received.
Use the desktop, tablet and phone icons to the left of Versions to check different preview widths. App Builder targets desktop screens for now, so Nash builds and checks the desktop layout, and works on tablet or phone widths only when you ask. Publish sits at the right end of the toolbar, as in the semantic layer editor.
A new preview replaces the previous one without adding to your browser history, so the browser’s Back and Forward move between pages rather than through earlier previews. If the app in the preview reloads or navigates away from its own page, Builder starts the same preview again, which resets the app’s state. Builder does this a limited number of times for each build; after that it shows a notice, and the preview stays unavailable until the app is built again or you reload Builder.
Package setup in App Builder
Section titled “Package setup in App Builder”For a new Builder app, Builder automatically installs the current public SDK, App runtime, visualization, React and React DOM packages together using npm’s strict peer dependency checks. Builder saves the exact direct versions and npm-generated lock with your source. You do not install these starter packages or choose their versions before opening the app. Reopening and building use the saved lock. To change libraries, ask Nash for the specific dependency change, save the updated lock, build, and check the preview and relevant data interactions before publishing. A deployment does not automatically upgrade app libraries.
A new app also starts with grey design tokens and reusable chart, filter and state behaviour, which you and Nash can change freely. It has no styling or page layout. A chart that fails stays within its own object. To use a font other than the default, bundle it from npm as Load visualization fonts shows.
Builder opens saved source before Nash continues. If setup cannot finish, your saved source and last successful preview remain available. Use View details for the technical error. After a network interruption, restore connectivity and choose Retry setup in the same app. Retrying checks for already saved source before installing again; it does not create another app. If npm reports an unavailable package or peer dependency conflict, share the View details diagnostics with Astrato support. Retrying does not help until the package availability or conflict is resolved.
The Builder source format supports new apps only. Existing apps are not migrated by this change. First setup requires access to public npm.
Constraints on app code
Section titled “Constraints on app code”- Start the app from a function. Builder builds the app as one classic script, not an ES
module, so a top-level
awaitfails the build with “Top-level await is currently not supported with the “iife” output format”. Run startup in an async function that the entry module calls, as the starter does. Examples elsewhere in these docs that use top-levelawaitneed the same change. - Guard browser storage. In the preview, reading
sessionStorageorlocalStoragethrows aSecurityError, and an uncaught one leaves the preview blank. Wrap every storage access intry/catchand keep the app working without saved state.
Version history
Section titled “Version history”Versions opens version history in both Preview and Source files, including when another browser owns editing. Select a version to compare changed files in a code diff. The comparison uses saved source; unsaved edits are preserved separately. If a file is deleted remotely, its unchanged tab closes; a tab with unsaved edits stays open so you can resolve the conflict. Restoring requires editing ownership and saved or discarded local edits. Restoration creates a new version and preserves later history. It does not restore conversation, live data, semantic-layer changes or the currently published app. Source history has a quota; reaching it blocks new changes without deleting existing versions.
Browser execution and limits
Section titled “Browser execution and limits”Nash can request npm commands and builds in the connected browser, receive compile errors, inspect
a screenshot of the visible preview, and exercise supported controls. Inspection and interactions
other than viewport changes wait up to 15 seconds for the app’s data requests to finish. If the app
is still loading or keeps requesting data after that, the operation fails with an error that says
whether a request is still running or the app kept starting new ones. When Nash requests multiple
operations together, source changes and browser operations for one app run in order; operations for
other apps can run concurrently. Package code runs in an
isolated environment. Browser execution uses the publication location configured for the selected semantic layer’s data exit node;
if that location is unavailable, the build stops with an error. Creating and previewing an app still
does not require publication permissions. Saved dependency versions are not silently replaced. Source limits exclude installed
npm files. You can save up to 128 text files, each up to 1,000,000 UTF-8 bytes. Ordinary source files
share a 2,000,000-byte budget; the root package-lock.json has a separate 1,000,000-byte allowance,
so it does not reduce the room for authored source. Both budgets together allow up to 3,000,000 bytes;
the lock still counts toward the 128-file limit. Oversized generated files stop the whole source
export and preserve your saved source. The error identifies the path, actual bytes and limit.
Each package process has a three-minute limit. One browser operation, including preparation and
source export, has a total ceiling of 10 minutes 45 seconds; time already spent waiting for the
connected browser reduces that allowance. Work that expires before result acceptance cannot
replace saved source. If execution completed but its detailed result could not be delivered,
read the current source before continuing. A cancelled call may also have changed saved source;
read it again before requesting another execution. Commands are not automatically replayed after execution
starts; inspect the reported result before requesting another run. Builder is not an unattended
build service.
To test a path through the preview in one operation, an agent sends action.type sequence to
astrato_app_builder_execute: up to six clicks, fills, scrolls, navigations or viewport changes in
order, then one inspection. A step names its control by the ref from the latest inspection or by
its exact label, ignoring case, with role if several controls share it. A label reaches a control
that appears only after an earlier step, such as an option in a menu; it replaces earlier refs, so
later steps use labels too. Each step waits for the app’s data as a single interaction does. The
sequence stops at the first step that fails, and the result reports failedStep, stepsCompleted and
stepsTotal with the preview as it stands. A sequence changes only the preview, never saved source,
and is not replayed automatically. It returns one screenshot, so comparing two states takes two
sequences.
A screenshot needs the preview on screen. The browser stops drawing the preview while the Builder tab or window is in the background, while Source files or a version comparison is open, or while Builder is otherwise off screen, for example in a minimised window or a hidden browser panel. An inspection then waits, within the same 15 seconds, for the preview to be drawn again, and takes its screenshot if it is. If it is not, the inspection takes no screenshot and leaves the visual check pending, rather than returning a blank or out-of-date one. This is not an error: Nash carries on with the build result and checks that need no screenshot, and says the visual check is pending when it reports. Builder’s status shows no failure; with Source files or a comparison open it reads Preview not checked. You can keep working in other tabs while Nash works.
An inspection screenshot shows the preview’s visible viewport at its current scroll position, and
the result reports that position in pixels as scrollX and scrollY. To check content lower on the
page, scroll the preview window and inspect again; the screenshot size does not change. Content that
scrolls inside an element, such as a scrollable table or panel, appears at that element’s starting
position even after it is scrolled. A preview built before scroll positions were reported omits both
values and always shows the top of the page.
An inspection also lists up to 60 of the preview’s controls, each with a reference that Nash uses to
click, fill or scroll it. The controls of an open dropdown, menu, calendar or dialog come first, then
those in the visible viewport, then the rest of the page. When more controls exist, elementsOmitted
says how many were left out; closing what is open, scrolling or searching within a dropdown brings
others into the list. On a very large page, that count also includes elements not checked for
controls. Each control has a role and a label, and states whether it is disabled and,
where the control reports it, whether it is checked, selected or expanded. A table cell’s label gives
its column and its value. Elements that show a pointer cursor without being marked as controls, such
as the From and To fields and the calendar days of a native date picker, are listed with the role
clickable. A click presses, focuses and releases the control before clicking it, as a mouse does.
This lets Nash test native filters and date pickers where they are: it opens one, chooses a value, or a start day and then an end day, and inspects the result, instead of replacing the control with its own inputs.
Chart marks such as bars and slices are drawn on a canvas, so they are not among the listed controls.
To test what a mark does, an agent sends the clickAt interaction with the screenshotId from the latest
inspection, and x and y from 0 to 1000 across and down that image, whatever size it was read at.
A mark reports a click as a selection, so the agent then inspects again. The inspection’s route
holds the preview’s address fragment, which shows whether a drill opened a new route; it is empty for
an app that switches pages without changing its address. A screenshot covers one action, so clickAt
is sent on its own and is not a step in a sequence; a sequence’s own screenshot can be used for it. The click
is refused if the preview was rebuilt, resized, scrolled or navigated after the screenshot, or if the
point is not on a chart, is covered by something else, or is inside a scrolled panel. While the
preview is not drawn, no click is made and the check stays pending, as for an inspection.
Publishing from App Builder
Section titled “Publishing from App Builder”Choose Publish explicitly to compile and publish the saved revision. The first publish creates a separate publication and requires publication Create and Publish permissions, a published semantic layer and supported hosting. Saving or restoring source does not change the published app. Changing dependencies also leaves the published app unchanged until you explicitly publish again.
Only the browser that owns editing shows Publish. Keep that Builder tab open until publishing finishes. Builder uploads the compiled app, and Astrato verifies it before updating the publication. Source version history remains separate from the published app.
If publishing fails, Builder shows the reason. Resolve any reported problem, such as an unpublished semantic layer or missing permission, before choosing Publish again. When Builder asks you to review the preview first, do so; the next Publish builds the saved revision again. For an upload error that says “Retry with the same publish key”, keep Builder open, leave the source unchanged and choose Publish again. You do not need to supply a key. The previously published app remains available until publishing succeeds.
External agents using App Builder
Section titled “External agents using App Builder”This optional MCP workflow lets an external AI agent work on source saved in Builder. Builds and preview interactions still run through your connected Builder browser. Use the Builder project and its tools; the local CLI setup below does not apply to this workflow. Choose either Builder execution or local CLI builds for a project and keep using that workflow; see using both approaches.
External agents can use these MCP tools:
workspace:read:astrato_app_builder_list,astrato_app_builder_readandastrato_app_builder_versions.workspace:write:astrato_app_builder_open,astrato_app_builder_edit,astrato_app_builder_restoreandastrato_app_builder_execute.
For the open app in Builder, Nash can omit appId on read, edit, versions, restore and
execute after checking your access. Explicit IDs still target the specified app and keep all
applicable checks. External MCP callers must provide each tool’s required appId.
The signed-in caller must own the project. Use astrato_app_builder_list to find an existing app by name.
External MCP returns a full browser URL. Open that
URL while logged in before requesting changes. If Builder shows that editing disconnected, choose
Resume editing, then tell the agent to continue. The agent must continue through the same
Builder project and its saved source.
astrato_app_builder_read returns up to 12,000 characters of content per call. To continue a file,
send that one path with its nextOffset; an offset of 0 reads every path from its start. In
astrato_app_builder_edit, a patch’s oldText must match the file exactly once, whitespace included.
Edits apply in order, and one refused edit applies none of them: the refusal names each patch that
missed and what differs, so correct those and send the whole call again.
Builder builds every saved revision from its saved npm lock, so an edit cannot change package.json
dependencies that package-lock.json does not record, or remove the lock: it is refused as
dependency_lock and nothing in it is applied. Add, change or remove packages with an npm command
through astrato_app_builder_execute, such as npm install --ignore-scripts <package> or
npm uninstall <package>, which saves both files together. Other package.json changes are edits as usual.
Edits, restores and executions send the lease generation and the source revision from the agent’s
latest source read, or from its latest edit, restore or execution result: each of those returns
generation and revision, so the agent can continue without reading source again. A result with
no generation, such as one saying execution finished but its details were lost, means read source
first. The server checks both values on every call, however the agent got them. The lease renews while Builder stays open, however long the agent works. Only these refusals report
a problem with the editing session:
lease_lost: the generation belongs to an earlier Builder editing session, for example one from before you reloaded Builder. The agent stops and waits until you ask it to continue.invalid_generation: the agent sent a generation it was not given. It reads source again. If the returned generation matches the one it read earlier, or it had not read one, it retries with that generation. Otherwise Builder editing restarted: the agent stops and waits until you ask it to continue.waiting_for_browser: no Builder tab is editing this app yet, because it is not open or Builder is still preparing the app. This does not mean editing was lost. The refusal includes the app URL: open it if it is not open. Editing connects automatically once Builder shows the app, with no separate step to start editing.
If the app’s source changes while an execution is still waiting or running, for example because
you saved an edit in Builder, the execution ends with execution_superseded and nothing from it is
saved. The agent reads source again and reruns the execution if it still needs it.
A source read before Builder has prepared a new app returns no source. For an external agent it
returns status: waiting_for_browser with the app URL: open it if you have not, and the agent reads
again once Builder shows the app. When Nash works from that app’s own Builder page, the read waits
briefly for Builder and then returns status: opening, and Nash reads again instead of asking you
to do anything. If Builder is still preparing the app after four minutes, Nash stops and asks you to
send a message once Builder shows it.