apx

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

Stream logs from all services in one place

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 stop

Architecture

When you run dev start, apx launches:

  1. Backend Server - FastAPI application with hot reload via uvicorn
  2. Frontend Server - Vite dev server with HMR (Hot Module Replacement)
  3. OpenAPI Watcher - Monitors Python models and regenerates TypeScript client
  4. 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: float

This 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 registry

Available Registries

apx comes preconfigured with high-quality component registries:

RepositoryAliasDescriptionLicense
shadcn/ui(default)Core UI componentsMIT
animate-ui@animate-uiAnimation componentsMIT
ai-sdk@ai-elementsAI components (chat, prompts)Apache-2.0
svgl@svglSVG icons collectionMIT

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 tabs

Then 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 stateful

Or apply to an existing project:

uv run apx dev apply stateful

How 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 order

Development vs Production

EnvironmentDatabaseConfiguration
DevelopmentPGliteIn-memory PostgreSQL sidecar
ProductionLakebaseConfigured 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 essential

Stateful 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 stateful

AI 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 codex

These rules help AI assistants understand your project structure and conventions, enabling more effective code generation and assistance.

On this page