Skip to content

Add appkit-lakeflow-designer template - #267

Draft
edcheung1 wants to merge 10 commits into
databricks:mainfrom
edcheung1:add-appkit-lakeflow-designer
Draft

edcheung1 wants to merge 10 commits into
databricks:mainfrom
edcheung1:add-appkit-lakeflow-designer

Conversation

@edcheung1

Copy link
Copy Markdown

What

Adds appkit-lakeflow-designer, an AppKit template for the published Lakeflow Designer app: a Vite + React client and a Node/AppKit server. One Databricks App is deployed per published Designer flow, all sharing this source, deployed git-backed (the app points at this repo; Databricks pulls, builds, and runs it).

Per-app configuration is injected at deploy time rather than committed to the shared source:

  • the runner Job is bound via the job app resource, surfaced to the server as DATABRICKS_JOB_ID;
  • the manifest (designerApp.json) is written by the publish flow to a per-app workspace path keyed by the job id and read at startup via the app's workspace client.

Notes

  • build/server.js is authored source (not a build artifact); .gitignore intentionally does not ignore build/.
  • Added to the README AppKit table.
  • Draft: opened for git-backed deploy validation, not yet merge-ready.

This pull request and its description were written by Isaac.

Ed Cheung and others added 10 commits September 15, 2026 19:41
Extracts the published Lakeflow Designer app source (previously the .src fixtures
embedded in universe) as a standalone AppKit app for git-backed deployment. The
server reads its per-app manifest at runtime from a workspace path keyed by the
runner job id (DATABRICKS_JOB_ID), and the runner job is bound via the `job` app
resource surfaced as that env var. Includes server, client, app.yaml, package.json,
tsconfig, vite config, .gitignore, README, and a dev-only databricks.yml.

Co-authored-by: Isaac <no-reply@databricks.com>
The published Designer app server is now server/server.ts, type-checked with
tsc (strict) and bundled to dist/server.js by tsdown; start runs the bundle.
This restores the server that was missing from the template because the old
build/ path was git-ignored.

Adds the shared/server/client tsconfig projects, the tsdown server config, a
committed package-lock.json, and the server's build/runtime dependencies
(@databricks/sdk-experimental, @types/express, tsdown). The app reads its
per-app manifest at startup through the workspace client, keyed by
DATABRICKS_JOB_ID.

Co-authored-by: Isaac <no-reply@databricks.com>
…t deploys

The git-backed deploy timed out at the 8-minute build cap during npm install:
plain vite pulled the rollup + esbuild native-binary fan-out on top of rolldown
(three bundler toolchains), and unpinned transitive deps (systeminformation)
bloated the tree. Mirror the working appkit-* templates: move the build
toolchain to devDependencies, switch vite to npm:rolldown-vite, and add the
overrides block (rolldown-vite, @opentelemetry/core, systeminformation).

Clean install now completes in ~1m (was >8m timeout); build passes with
rolldown-vite for the client and tsdown for the server.

Co-authored-by: Isaac <no-reply@databricks.com>
…s polls

The manifest was memoized for the process lifetime, so a republish was not
reflected until the app restarted. Read it fresh on the non-polled paths
(/config page load and POST /run submit) and reuse a cached read on the
frequently-polled status endpoints (last-run, run/:id, runs via declaredOutputs).
A republish now shows up on the next page load with no redeploy; the status
polls avoid a per-poll workspace export. A failed fresh read falls back to the
last good manifest so a transient export blip does not flip the app to
unconfigured.

Co-authored-by: Isaac <no-reply@databricks.com>
The git-backed (and bundle) deploy hung ~8 minutes in npm install and hit the
build cap. The Apps build sandbox installs from a workspace-configured npm
registry; the 0.70 tree pulled transitive packages that registry does not serve,
so npm fell back to a route blocked in the sandbox and stalled. The reference
appkit-* templates deploy on 0.65 (843 packages in ~16s on the same workspace).
Aligning to 0.65 fixes it with no code changes: server + client typecheck and
build stay green (toLegacyWorkspaceClient and the appkit-ui/react components are
unchanged).

Co-authored-by: Isaac <no-reply@databricks.com>
Not a keeper — reverted once we've read /logz. Sets loglevel=silly and adds a
preinstall that prints the effective npm registry and whether it serves
react-markdown/micromark (vs react as a control), from inside the build sandbox.

Co-authored-by: Isaac <no-reply@databricks.com>
…nstall)

The lockfile was generated locally against npm-proxy.cloud.databricks.com, so its
resolved tarball URLs used that host. npm only rewrites default-registry
(registry.npmjs.org) URLs to the configured registry, so in the Apps build sandbox
every .tgz fetch hit npm-proxy.cloud.databricks.com (unreachable there) and timed
out, exhausting the 8-min build cap. Rewrite resolved URLs to registry.npmjs.org so
the sandbox rewrites them to its own proxy (package-proxy.host.local), matching the
reference templates. Also removes the temporary loglevel/preinstall diagnostic.

Co-authored-by: Isaac <no-reply@databricks.com>
The 0.65 pin was chasing the wrong cause; the real deploy blocker was the
lockfile's tarball host, now fixed. Back on 0.70.0 with the lockfile regenerated
and its resolved URLs kept at registry.npmjs.org (portable), so the Apps build
sandbox rewrites them to its own proxy. Typecheck + build stay green.

Co-authored-by: Isaac <no-reply@databricks.com>
…dencies

With NODE_ENV=production set as an app env var, the Apps build ran npm install
with --omit=dev, so the build toolchain (typescript/tsc, tsdown, vite — all
devDependencies) was missing and `npm run build` failed with `tsc: not found`.
The runtime still runs in production via the start script
(NODE_ENV=production node ./dist/server.js), matching the reference templates,
which don't set NODE_ENV in app.yaml.

Co-authored-by: Isaac <no-reply@databricks.com>
The published-app manifest now lives beside the runner notebook in the publisher's
workspace folder rather than a world-writable shared path. The app no longer reads a
DESIGNER_MANIFEST_ROOT env: it resolves its runner job (jobs.get on DATABRICKS_JOB_ID),
takes the runner notebook's folder, and reads designerApp.json from there. Falls back
gracefully if the job or notebook path can't be resolved.

Co-authored-by: Isaac <no-reply@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant