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/
- Automatically redirects to
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:
| Process | Port |
|---|---|
| Backend | 8888 |
| Frontend | 5173 |
| Studio | 9999 |
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
-
Install dependencies:
uv sync -
Install your app (if custom):
cd apps/myapp
uv pip install -e . -
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 devfor frontend development - Rely on CI/CD for release builds
- Local
pnpm buildis only necessary to verify production artifacts
Troubleshooting
UI Downloads Instead of Rendering
If the browser downloads HTML files instead of rendering them, check:
- Content-Type Headers: Ensure responses have
Content-Type: text/html; charset=utf-8 - Route Handlers: Verify return type is
Responsenot union types - Browser Cache: Clear browser cache and hard reload (Ctrl+Shift+R)
404 Errors on Deep Links
If refreshing a page like /desk/doctypes/User gives 404:
- Check Route Handler: Ensure
/desk/{path:path}wildcard route exists - SPA Fallback: Verify the handler returns
index.htmlfor non-file paths - Base Path: Confirm React Router uses
basename="/desk"
API Calls Failing
If API calls return errors:
- CORS: Check CORS configuration allows your origin
- Path Prefix: Ensure API calls use
/api/*prefix - Server Running: Verify
m startorm devis running on the correct port
Hot Reload Not Working
If changes aren't being detected:
Backend:
- Check WatchFiles is enabled (look for "Started reloader process" in logs)
- Verify file is in watched directory
- Try
--reloadflag explicitly
Frontend:
- Ensure
m devis running (notm start) - Check Vite dev server is on port 5173
- Verify WebSocket connection in browser DevTools
DocTypes Not Appearing
If your custom DocTypes don't show in the sidebar:
- Install your app:
cd apps/myapp && uv pip install -e . - Check entry points: Verify
pyproject.tomlhas[project.entry-points."framework_m.apps"] - Restart server: DocTypes are discovered at startup
- Check logs: Look for "Discovered X DocType(s) from app 'myapp'"
Quick Reference
| Command | Use Case | Hot Reload |
|---|---|---|
m start | Production, bundled UI | Optional (--reload) |
m dev | Development, both servers | ✅ Always |
m dev --studio | Development + Studio | ✅ Always |
m dev --no-frontend | Backend only dev | ✅ Backend only |