Skip to main content

Desk Setup Guide

Running Desk

The Desk provides the main user interface for managing your Framework M application data and workflows.

Single Command (Production)

m start

This starts the backend server with the bundled Desk UI on port 8888.

Development Mode

For development with hot reload:

m dev

This starts both backend and frontend with automatic hot reload using honcho process manager.

URL Structure

The Desk uses a path prefix architecture for clean separation:

  • UI: http://127.0.0.1:8888/desk/

    • Main interface for managing data
    • All frontend routes are under /desk/*
  • API: http://127.0.0.1:8888/api/

    • Backend endpoints for data operations
    • All API routes are under /api/*
  • Root: http://127.0.0.1:8888/

    • Automatically redirects to /desk/

Commands

m start - Production Mode

Runs the backend with bundled static Desk UI:

# Default (port 8888)
m start

# Custom port
m start --port 3000

# Custom app module
m start --app myapp:create_app

# With auto-reload
m start --reload

Use Cases:

  • Production deployments
  • Testing bundled UI
  • Single-process server

m dev - Development Mode

Runs backend and frontend concurrently with hot reload:

# Backend + Frontend
m dev

# Backend + Frontend + Studio
m dev --studio

# Custom backend module
m dev --app myapp:create_app

# Custom frontend directory
m dev --frontend-dir ./custom-ui

# Backend only (no frontend)
m dev --no-frontend

# Custom ports
m dev --port 9000 --frontend-port 3000 --studio-port 9999

Features:

  • Hot Reload: Backend (uvicorn) and frontend (Vite HMR)
  • Process Management: Honcho manages multiple processes
  • Concurrent Output: Color-coded logs with process prefixes
  • Graceful Shutdown: Ctrl+C stops all processes cleanly

Default Ports:

ProcessPort
Backend8888
Frontend5173
Studio9999

Architecture

Path Prefix Separation

The Desk implements complete separation between UI and API routes:

/desk/*     → React SPA (HTML pages)
/api/* → JSON API endpoints
/ → Redirects to /desk/

This architecture:

  • ✅ Prevents route collisions
  • ✅ Enables clean URLs (no hash fragments)
  • ✅ Works with single-command deployment
  • ✅ Supports proper Content-Type headers

Static Assets

Static assets (JS, CSS, images) are served at:

/desk/assets/*

The Vite build process outputs to libs/framework-m/src/framework_m/static/ which is included in the Python package.

Process Management (m dev)

When running m dev, honcho orchestrates multiple processes:

┌─────────────────────────────────────────┐
│ honcho.manager.Manager │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────┐│
│ │ backend │ │ frontend │ │ studio ││
│ │ :8888 │ │ :5173 │ │ :9999 ││
│ └──────────┘ └──────────┘ └────────┘│
│ │
│ • Color-coded output │
│ • Concurrent execution │
│ • Graceful shutdown │
└─────────────────────────────────────────┘

API Endpoints

Health Check

curl http://127.0.0.1:8888/health

Authentication

curl http://127.0.0.1:8888/api/v1/auth/me

List DocTypes

curl http://127.0.0.1:8888/api/meta/doctypes

Translations

curl http://127.0.0.1:8888/api/v1/Translation?locale=en

Building for Production

Build Frontend

cd frontend
pnpm build

This outputs to dist/ which should be copied to libs/framework-m/src/framework_m/static/.

Update Bundled Static

# After building frontend
cp -r frontend/dist/* libs/framework-m/src/framework_m/static/

Package Python

cd libs/framework-m
uv build

The built wheel includes the static frontend assets.

Development Workflow

Initial Setup

  1. Install dependencies:

    uv sync
  2. Install your app (if custom):

    cd apps/myapp
    uv pip install -e .
  3. Start development server:

    m dev

Hot Reload in Action

Backend Changes:

# Edit any Python file
# WatchFiles detects changes
# Server automatically restarts

Frontend Changes:

# Edit any React/TS file
# Vite HMR updates instantly
# No page reload needed

Git Noise and Local Builds

Avoid running pnpm build locally during development.

Running pnpm build updates the static assets in libs/framework-m/src/framework_m/static/. Since Vite includes hashes in filenames (e.g., index-a1b2c3.js), every build modifies tracked files, creating unnecessary git noise.

Best Practice:

  • Use m dev for frontend development
  • Rely on CI/CD for release builds
  • Local pnpm build is only necessary to verify production artifacts

Troubleshooting

UI Downloads Instead of Rendering

If the browser downloads HTML files instead of rendering them, check:

  1. Content-Type Headers: Ensure responses have Content-Type: text/html; charset=utf-8
  2. Route Handlers: Verify return type is Response not union types
  3. Browser Cache: Clear browser cache and hard reload (Ctrl+Shift+R)

If refreshing a page like /desk/doctypes/User gives 404:

  1. Check Route Handler: Ensure /desk/{path:path} wildcard route exists
  2. SPA Fallback: Verify the handler returns index.html for non-file paths
  3. Base Path: Confirm React Router uses basename="/desk"

API Calls Failing

If API calls return errors:

  1. CORS: Check CORS configuration allows your origin
  2. Path Prefix: Ensure API calls use /api/* prefix
  3. Server Running: Verify m start or m dev is running on the correct port

Hot Reload Not Working

If changes aren't being detected:

Backend:

  1. Check WatchFiles is enabled (look for "Started reloader process" in logs)
  2. Verify file is in watched directory
  3. Try --reload flag explicitly

Frontend:

  1. Ensure m dev is running (not m start)
  2. Check Vite dev server is on port 5173
  3. Verify WebSocket connection in browser DevTools

DocTypes Not Appearing

If your custom DocTypes don't show in the sidebar:

  1. Install your app: cd apps/myapp && uv pip install -e .
  2. Check entry points: Verify pyproject.toml has [project.entry-points."framework_m.apps"]
  3. Restart server: DocTypes are discovered at startup
  4. Check logs: Look for "Discovered X DocType(s) from app 'myapp'"

Quick Reference

CommandUse CaseHot Reload
m startProduction, bundled UIOptional (--reload)
m devDevelopment, both servers✅ Always
m dev --studioDevelopment + Studio✅ Always
m dev --no-frontendBackend only dev✅ Backend only