Skip to main content

02-appkit-build

Build full-stack UI and backend features on a Databricks AppKit project from a PRD or feature spec. Covers SQL query design, type generation, React frontend with AppKit UI components, backend plugin wiring, and distinctive visual design. Use when asked to implement a UI, build features from a PRD, create pages or dashboards, add components, develop the frontend/backend of an existing AppKit app, build with mock data, or use static data for visual prototyping. Triggers on "build UI", "implement PRD", "create dashboard", "add page", "build features", "implement design", "create components", "build app from PRD", "develop frontend", "mock data", "static data", "two-phase data".

インストールへ移動

ソース情報

リポジトリ
databricks-solutions/vibe-coding-workshop-template
ソースの最終更新活動
2026年6月25日 06:16
検出された SKILL.md の言語
英語
スター
6
フォーク
7

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
3 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
02-appkit-build
description
Build full-stack UI and backend features on a Databricks AppKit project from a PRD or feature spec. Covers SQL query design, type generation, React frontend with AppKit UI components, backend plugin wiring, and distinctive visual design. Use when asked to implement a UI, build features from a PRD, create pages or dashboards, add components, develop the frontend/backend of an existing AppKit app, build with mock data, or use static data for visual prototyping. Triggers on "build UI", "implement PRD", "create dashboard", "add page", "build features", "implement design", "create components", "build app from PRD", "develop frontend", "mock data", "static data", "two-phase data".
license
Apache-2.0
compatibility
Requires an existing AppKit project scaffolded via 01-appkit-scaffold skill, Node.js v22+, Databricks CLI >= 0.295.0
clients
["ide_cli","genie_code"]
bundle_resource
apps
deploy_verb
apps_deploy
deploy_note
Building features is **source editing** (`.sql` queries, `server/server.ts`, `client/src/**`) — fully client-agnostic; the same files are written on both clients. Deploy is delegated to `03-appkit-deploy`. The local toolchain steps are an **IDE convenience**: `npm run typegen`, `npm run dev`, `npx tsc --noEmit`, `npm run build`, and the `http://localhost:8000` checks have **no Genie Code equivalent** (no local Node) — on Genie Code typegen/tsc/build run **server-side on deploy**; write UI against the SQL schema + the appkit-ui docs and verify on the deployed app. `npx @databricks/appkit docs` is IDE-only (WebFetch on Genie Code). `databricks apps validate` is skipped on Genie Code (hard-blocked) — rely on `bundle validate` + server-side build logs.
coverage
full
metadata
{"author":"prashanth subrahmanyam","version":"1.1.0","domain":"apps","role":"build","standalone":false,"last_verified":"2026-06-02","volatility":"medium","upstream_sources":[]}
# Build Features on Databricks AppKit Implement full-stack UI and backend features on an already-scaffolded AppKit project, driven by a PRD or feature spec. ## When to Use - Implementing a PRD or feature spec on an existing AppKit project - Building pages, dashboards, or components with `@databricks/appkit-ui` - Adding SQL queries and wiring them to type-safe React hooks - Creating a visually distinctive, production-grade frontend **Not for scaffolding.** Use `01-appkit-scaffold` to create a new project first. **Not for adding plugins.** Use `04-appkit-plugin-add` to register new plugins. --- ## Before You Begin ### Working in Genie Code (client routing) This skill is **source editing** — designing SQL queries, writing `server/server.ts`, and building React under `client/src/`. All of that is **identical on both clients**; only the local-toolchain gates differ: | IDE/CLI (as written) | Genie Code substitution | |----------------------|--------------------------| | `npm run typegen` (generates `client/src/appKitTypes.d.ts`) | no local Node — typegen runs **server-side on deploy**. Write UI against the `.sql` `-- @param` annotations + the appkit-ui docs; the generated types land at deploy/build time | | `npm run dev` / `http://localhost:8000` checks (Step 6) | no local dev server — verify UI/queries on the **deployed** app (browser, or the OAuth-session test in `03-appkit-deploy`) | | `npx tsc --noEmit` (Step 4b) / `npm run build` | no local typecheck — `npm`/`npx`/`tsc` cannot resolve `@databricks/appkit-ui` without `node_modules`. The platform builds **server-side** on deploy, but TS errors do **NOT** come back through `databricks apps logs <name>` (OAuth error from compute) — they appear only at `<app-url>/logz` in a browser. The one viable static pre-flight is the **import-specifier regex gate** in the `99-deploy_databricks_app.genie-code.md` fork (Step 2b) — run it before deploy | | `npx @databricks/appkit docs …` | npx absent (P9) — WebFetch https://databricks.github.io/appkit/ | | `ls node_modules/@databricks/appkit-ui/…` | no local `node_modules` — consult the appkit-ui docs (WebFetch) instead | | `databricks apps validate --profile $PROFILE` (checklist) | hard-blocked on Genie Code — skip; rely on `bundle validate` (`runDatabricksCli`, omit `--profile`) + server-side build logs per `03-appkit-deploy` / `07-appkit-chat-history` Step 9 | Edit files **in your workshop project** — paths are relative to the top-level app dir `$APP_ROOT` (= `<artifact_root>/<app_name>`; on Genie Code, under `/Workspace/Users/<your-email>/vibe-coding-workshop/<app_name>` — your git-cloned workshop project, NOT the `.assistant/skills` copy), never `/tmp`. See `skills/genie-code-environment` for the full manifest. **Optional upstream checks** (skip if latency-constrained or the `last_verified` date above is < 30 days old): 1. **Databricks Apps skill (source of truth for AppKit workflow):** Fetch the latest from https://github.com/databricks/databricks-agent-skills/tree/main/skills/databricks-apps If accessible, check the "Breaking Changes" and "New Patterns" sections. 2. **Anthropic frontend-design skill (inspiration for design quality):** Fetch the latest from https://github.com/anthropics/skills/blob/main/skills/frontend-design/SKILL.md Skim for new aesthetic examples. Skip if latency-constrained. **Additional live docs (always prefer over bundled references):** ```bash npx @databricks/appkit docs # documentation index npx @databricks/appkit docs "<query>" # specific topic ``` Key upstream doc pages: - LLM guardrails: https://databricks.github.io/appkit/docs/development/llm-guide - Type generation: https://databricks.github.io/appkit/docs/development/type-generation - UI components: https://databricks.github.io/appkit/docs/api/appkit-ui/ - Configuration: https://databricks.github.io/appkit/docs/configuration - Architecture: https://databricks.github.io/appkit/docs/architecture The bundled references below are fallbacks when live docs cannot be reached. > **Workshop Mode (blank app):** If you are following the AppKit+Lakebase workshop (**Scaffold, Build & Test** step) and scaffolded a blank app without plugins, skip Step 2 (SQL Queries) and the `analytics()` plugin references in Step 4. Use static mock data arrays instead of `useAnalyticsQuery`. The backend only needs `server()` — no `analytics()` plugin. All SQL/typegen sections are not applicable until the Lakebase plugin is added in the **Wire Lakebase Backend** step. --- ## Architecture Overview AppKit is a TypeScript full-stack framework with two packages: - **`@databricks/appkit`** — backend: Express server, plugin system, SQL query execution, caching, telemetry - **`@databricks/appkit-ui`** — frontend: React hooks (`useAnalyticsQuery`), UI primitives (Shadcn/Radix), data visualization (ECharts) ``` client/src/App.tsx → useAnalyticsQuery("key", params) → server/server.ts → config/queries/key.sql → SQL Warehouse ``` --- ## Step 1: Read the PRD Before writing any code, thoroughly understand: - **User personas** and their needs - **Key user journeys** (focus on Happy Path first) - **Core features** and requirements - **Data requirements** — what tables/queries will the UI need? --- ## Step 2: Plan and Create SQL Queries Create `.sql` files in `config/queries/`. Each file becomes a query key. ```sql -- config/queries/active_users.sql -- @param startDate DATE -- @param endDate DATE SELECT user_id, email, last_login FROM catalog.schema.users WHERE last_login BETWEEN :startDate AND :endDate ORDER BY last_login DESC ``` **Rules:** - Use `:paramName` placeholders — NEVER construct SQL strings dynamically - Annotate params with `-- @param name TYPE` (types: `STRING`, `NUMERIC`, `BOOLEAN`, `DATE`, `TIMESTAMP`) - `:workspaceId` is auto-injected by the server — do NOT annotate it - `queryKey.sql` runs as service principal; `queryKey.obo.sql` runs as user Then generate types: ```bash npm run typegen ``` **Do NOT write UI code until types are generated.** Read `client/src/appKitTypes.d.ts` to see available query types. --- ## Step 3: Design the UI Before coding components, commit to a design direction. READ [references/design-quality.md](references/design-quality.md) for detailed guidelines. Key principles: - Choose a **bold aesthetic direction** — not generic AI aesthetics - Use AppKit UI primitives (`@databricks/appkit-ui`) as the foundation, then layer distinctive styling on top - Plan the page layout, component hierarchy, and navigation flow - Pay special attention to the "CSS Variables → Components" section — it prevents the most common styling anti-pattern --- ## Step 4: Build the Backend **First action:** Open `server/server.ts`. The scaffold may generate `createApp({...}).catch(console.error)` — this must be replaced. **Replace the file contents** with: ```typescript import { createApp, server, analytics } from "@databricks/appkit"; await createApp({ plugins: [server(), analytics()], }); ``` Verify the file uses `await createApp()` before proceeding. Do not leave `.catch(console.error)`. For non-query APIs (writes, ML endpoints, custom logic), extend the server: ```typescript const appkit = await createApp({ plugins: [server({ autoStart: false }), analytics()], }); appkit.server.extend((app) => { app.post("/api/custom-action", (req, res) => { /* ... */ }); }); await appkit.server.start(); ``` **NEVER use tRPC or custom routes for SELECT queries** — always use SQL files in `config/queries/`. --- ## Step 4b: TypeScript Validation Gate **You MUST run `npx tsc --noEmit` and fix all errors before proceeding to Step 5.** TypeScript errors in the backend will cascade to the frontend build and cause deploy failures. Fix them now while the scope is small. --- ## Step 5: Build the Frontend Implement components in `client/src/`. Start with `App.tsx`. ### Two-Phase Data Pattern Build the UI in two phases so you get immediate visual feedback before SQL queries are wired up. **Scaffold step — Static data for immediate visual feedback:** Use the `data` prop on AppKit data components (charts, tables) with representative sample data. This lets you build and iterate on the UI visually before wiring up live query-driven data. ```tsx <BarChart data={[ { month: "Jan", revenue: 4200 }, { month: "Feb", revenue: 5100 }, { month: "Mar", revenue: 3800 }, ]} xKey="month" yKey="revenue" /> ``` **Even with static data, add loading/error/empty branches** so components are ready for the query-driven swap: ```tsx const properties = MOCK_PROPERTIES; // Will become API response const loading = false; // Will become true during fetch const error: string | null = null; // Will capture API errors if (loading) return <Skeleton className="h-64 w-full" />; if (error) return <div className="text-destructive">{error}</div>; if (!properties.length) return <EmptyState />; ``` **Later — Swap to query-driven data (final state):** Once SQL files exist in `config/queries/` and `npm run typegen` has generated types, replace static `data` with `queryKey` + `params`: ```tsx import { useAnalyticsQuery } from "@databricks/appkit-ui/react"; import { sql } from "@databricks/appkit-ui/js"; function RevenueChart() { const params = useMemo(() => ({ year: sql.number(2025), }), []); const { data, loading, error } = useAnalyticsQuery("monthly_revenue", params); if (loading) return <Skeleton className="h-32 w-full" />; if (error) return <div className="text-destructive">{error}</div>; if (!data?.length) return <div className="text-muted-foreground">No data</div>; return <BarChart data={data} xKey="month" yKey="revenue" />; } ``` All static demo data must be replaced with query-driven data before declaring the build complete. ### Hard Rules **GATE:** Read [references/llm-guardrails.md](references/llm-guardrails.md) before writing any code in this step. Violations of these rules cause runtime bugs and deployment failures. Key rules (not a substitute for reading the file): - **SQL results return strings** — `useAnalyticsQuery` may return all values as strings at runtime, even for numeric columns. Always coerce with `Number()` before arithmetic to avoid string concatenation bugs - **Always `useMemo`** on query parameters — prevents infinite refetch loops. For parameterless queries (`Record<string, never>`), pass `useMemo(() => ({}), [])` - **Always handle loading/error/empty states** — use `Skeleton` for loading - **Always use `sql.*` helpers** for parameters (`sql.date()`, `sql.string()`, `sql.number()`) - **Use `import type`** for type-only imports when `verbatimModuleSyntax` is enabled - **Never invent APIs** — only use documented exports from `@databricks/appkit` and `@databricks/appkit-ui` - **Never build SQL strings dynamically** — use parameterized queries - **`createApp()` is async** — always `await` it - **Wrap root with `<TooltipProvider>`** — many AppKit components use tooltips internally; add this to `App.tsx` by default (imported from `@databricks/appkit-ui/react`, per the specifier rule below) - **AppKit import specifiers are exact:** - Components/hooks: `import { … } from "@databricks/appkit-ui/react"` — **never** the bare `@databricks/appkit-ui` (the bare path has no React export and the build cannot resolve it). - Global stylesheet: `@import "@databricks/appkit-ui/styles.css";` in `client/src/index.css` — **never** the extension-less `@import "@databricks/appkit-ui/styles";` (the package only exports the `.css` path; the extension-less form is unresolvable). These two are the exact paths the scaffold ships. - **Preserve the scaffold — do NOT regenerate from memory.** Edit `client/src/App.tsx` and `client/src/index.css` **incrementally**; never overwrite them with hand-authored versions. Regenerating these from memory is how the wrong (shorter) import specifiers get reintroduced. Likewise, **keep the scaffold's `client/src/ErrorBoundary.tsx`** — it is the only thing that surfaces a client-side runtime crash in the browser (a crash that otherwise deploys "green"). - **Images: external CDN primary, deterministic `onError` fallback (mandatory).** A generated mock has no realistic photo library to bundle, so external CDN hotlinks (Unsplash / Pexels) are the practical default `src` for realistic, use-case-varied imagery. But those requests are made by the **user's browser** and are routinely blocked by corporate/network egress — and the block is invisible at build time. So **every `<img>` must carry a runtime `onError` handler** that swaps `src` to an **inline data-URI SVG** placeholder (zero-network, embedded bytes — nothing to fetch or block), so a blocked CDN degrades to a clean placeholder instead of a blank/broken image: `<img src={cdnUrl} onError={(e) => { e.currentTarget.src = DATA_URI_SVG_PLACEHOLDER; }} alt="…" />`. When you actually have real images to ship, bundle them with the app (`client/public/…` or a Vite `import`) — served same-origin behind the OAuth gate, they render anywhere with no egress. - **No decorative controls that silently no-op.** Every visible interactive control (filter, tab, date/guest picker, search box) must either function against the mock data OR be visibly marked as a later-phase placeholder (disabled, or a "coming soon" affordance). A control that looks live but does nothing reads as a broken app. ### UI Components AppKit UI components are Shadcn/Radix-based. Data charts are ECharts-based — use props (`xKey`, `yKey`, `colors`), NOT Recharts children. Check the live docs for the latest component list: ```bash npx @databricks/appkit docs "appkit-ui API reference" ``` **Note:** The `docs` search matches section headings only. Searching for a component name like `"DataTable"` may fail. Use the full doc path for specific components: ```bash npx @databricks/appkit docs "./docs/api/appkit-ui/data/DataTable.md" ``` ### Chart Components Quick Reference Available chart components from `@databricks/appkit-ui`:
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る