Features
Core features of the apx development toolkit
apx provides a comprehensive set of features designed to streamline Databricks App development for both humans and AI assistants.
Development Server
The apx dev server provides a seamless full-stack development experience with hot reloading, automatic API client generation, and detached mode operation.
Key Features
Hot Reload
Automatic refresh on code changes for both frontend and backend
Detached Mode
Run servers in background, continue working in terminal
Unified Logs
OpenAPI Sync
Auto-generate TypeScript client from Python models
Quick Start
# Start all servers in detached mode
uv run apx dev start
# Check status
uv run apx dev status
# View logs
uv run apx dev logs -f
# Stop when done
uv run apx dev stopArchitecture
When you run dev start, apx launches:
- Backend Server - FastAPI application with hot reload via uvicorn
- Frontend Server - Vite dev server with HMR (Hot Module Replacement)
- OpenAPI Watcher - Monitors Python models and regenerates TypeScript client
- Database Sidecar - PGlite in-memory PostgreSQL instance (for stateful template)
All services run in detached mode, allowing you to continue working in your terminal. Logs are collected and can be streamed with dev logs -f.
Using Generated API Client
The generated TypeScript client provides type-safe hooks for calling your API. Import from @/lib/api:
// Query hook for GET requests
import { useListItems, useListItemsSuspense } from "@/lib/api";
const Component = () => {
const { data, isLoading, error } = useListItems();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>{/* render data */}</div>;
};
// Suspense variant (use with React Suspense boundary)
const SuspenseComponent = () => {
const { data } = useListItemsSuspense();
return <div>{/* render data */}</div>;
};
// Mutation hook for POST/PUT/DELETE requests
import { useCreateItem } from "@/lib/api";
const FormComponent = () => {
const { mutate, isPending } = useCreateItem();
const handleSubmit = () => {
mutate({ data: { name: "New Item" } });
};
return <button onClick={handleSubmit}>Create</button>;
};Types are also exported for use in your components:
import type { ListItemsQueryResult, CreateItemMutationBody } from "@/lib/api";OpenAPI Integration
apx automatically generates a TypeScript API client from your FastAPI backend:
# backend/models.py
from pydantic import BaseModel
class Order(BaseModel):
id: str
customer_name: str
total: floatThis automatically generates:
// Generated TypeScript client
interface Order {
id: string;
customer_name: string;
total: number;
}The watcher monitors your Python files and regenerates the client whenever you modify Pydantic models or FastAPI routes.
Built-in Components CLI
apx provides a CLI for working with shadcn registries, allowing you to add components from any shadcn-compatible registry to your project. Additional curated registries for animations, AI components, and icons are preconfigured.
Note: apx does not use a components.json file. Component registries are
configured in pyproject.toml under the [tool.apx.ui.registries] section.
The shadcn/ui registry is used as the default, so
there's no need to add it manually.
Adding Components
uv run apx components add button
uv run apx components add card
uv run apx components add dialog
uv run apx components add @animate-ui/sidebar # Add a component from a specific registryAvailable Registries
apx comes preconfigured with high-quality component registries:
| Repository | Alias | Description | License |
|---|---|---|---|
| shadcn/ui | (default) | Core UI components | MIT |
| animate-ui | @animate-ui | Animation components | MIT |
| ai-sdk | @ai-elements | AI components (chat, prompts) | Apache-2.0 |
| svgl | @svgl | SVG icons collection | MIT |
Example: Building a Dashboard
# Add required components
uv run apx components add card
uv run apx components add table
uv run apx components add chart
uv run apx components add tabsThen use them in your React code:
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table";
export function Dashboard() {
return (
<div className="grid gap-4 md:grid-cols-2">
<Card>
<CardHeader>
<CardTitle>Orders</CardTitle>
</CardHeader>
<CardContent>
<Table>{/* ... */}</Table>
</CardContent>
</Card>
</div>
);
}Customization
Components are installed directly into your project at src/<app>/ui/components/, giving you full control to customize styles and behavior.
Registry configuration is stored in pyproject.toml:
[tool.apx.ui.registries]
"@animate-ui" = "https://animate-ui.com/r/{name}.json"
"@ai-elements" = "https://registry.ai-sdk.dev/{name}.json"
"@svgl" = "https://svgl.app/r/{name}.json"You can add any shadcn-compatible registry by adding its URL pattern to this section.
Local Development Database
The stateful template includes integrated database support via SQLModel, with PGlite running as an in-memory PostgreSQL sidecar during development that maps to Lakebase in production.
Initializing with Database Support
uvx --index https://databricks-solutions.github.io/apx/simple apx init --template statefulOr apply to an existing project:
uv run apx dev apply statefulHow It Works
When you run apx dev start with the stateful template, apx automatically spins up a PGlite instance as a sidecar process. PGlite provides a fully PostgreSQL-compatible database running in-memory, giving you the same SQL dialect and features you'll have in production with Lakebase.
Defining Models
SQLModel combines Pydantic and SQLAlchemy for type-safe database models:
from sqlmodel import SQLModel, Field
from typing import Optional
from datetime import datetime
class Order(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
customer_name: str
total: float
status: str = "pending"
created_at: datetime = Field(default_factory=datetime.utcnow)Database Operations
from sqlmodel import Session, select
from backend.runtime import get_engine
def get_orders():
with Session(get_engine()) as session:
return session.exec(select(Order)).all()
def create_order(order: Order):
with Session(get_engine()) as session:
session.add(order)
session.commit()
session.refresh(order)
return orderDevelopment vs Production
| Environment | Database | Configuration |
|---|---|---|
| Development | PGlite | In-memory PostgreSQL sidecar |
| Production | Lakebase | Configured via PGAPPNAME environment variable inside Apps runtime |
The same SQLModel code works in both environments - apx handles the connection configuration automatically. Since PGlite is PostgreSQL-compatible, you get the same SQL behavior in development as you will in production.
Project Templates
apx offers two project templates to get you started:
Essential Template
The basic template includes:
- FastAPI backend with example routes
- React frontend with Vite
- TypeScript API client generation
- shadcn/ui component integration
- Tailwind CSS styling
uvx --index https://databricks-solutions.github.io/apx/simple apx init --template essentialStateful Template
Everything in Essential, plus:
- SQLModel database integration
- PGlite development database (PostgreSQL-compatible)
- Lakebase configuration for production
- Example CRUD operations
uvx --index https://databricks-solutions.github.io/apx/simple apx init --template statefulAI Assistant Rules
apx can generate configuration files for popular AI coding assistants:
# During init
uvx --index https://databricks-solutions.github.io/apx/simple apx init --assistant cursor
# Or apply later
uv run apx dev apply cursor
uv run apx dev apply vscode
uv run apx dev apply claude
uv run apx dev apply codexThese rules help AI assistants understand your project structure and conventions, enabling more effective code generation and assistance.