Quick Start
This guide takes a new user from zero setup to custom UI in production.
Prerequisites
- Python 3.12+ (
python --version) - uv package manager (install)
One-Click Development Environment (Recommended)
The fastest way to get started is using a pre-configured cloud development environment. This handles all dependencies, database setup, and the studio environment for you.
Project Setup (from scratch)
mkdir my-project && cd my-project
uv init
# Core runtime
uv add framework-m
# Developer tooling
uv add --dev framework-m-studio
Optional Feature Groups
Framework M is highly modular. You can install optional groups to add specific capabilities without bloating the core installation:
[server]: High-performance ASGI server, fast JSON, and secure sessions. Required to run web servers.[postgres]: PostgreSQL database driver and migration tools.[redis]: Redis cache and pub/sub support.[nats]: NATS JetStream support for distributed event bus.[elastic]: Elasticsearch driver.[metrics]: Prometheus client for metrics.[oauth]: OAuth and OIDC providers for federated authentication.[tracing]: OpenTelemetry SDK and auto-instrumentation for distributed tracing.[aws]: Async Boto3 (aioboto3) for AWS services like S3 storage integration.
Because these features belong to the standard adapters, you install them by targeting the standard package directly:
uv add "framework-m-standard[server,postgres]"
1) Base App
Create your first app package:
uv run m new app crm
cd crm
uv sync
Create your first DocType:
uv run m new doctype Contact
Example Contact DocType (src/crm/doctypes/contact/doctype.py):
from __future__ import annotations
from typing import ClassVar
from framework_m import DocType, Field
class Contact(DocType):
__doctype_name__: ClassVar[str] = "Contact"
first_name: str = Field(description="First name")
last_name: str = Field(description="Last name")
email: str = Field(default="", description="Email address")
class Meta:
requires_auth: ClassVar[bool] = False # Allow access without login (dev)
apply_rls: ClassVar[bool] = False # All users can access all records (dev)
naming_rule: ClassVar[str] = "autoincrement"
api_resource: ClassVar[bool] = True
show_in_desk: ClassVar[bool] = True
permissions: ClassVar[dict[str, list[str]]] = {
"create": ["All"],
"read": ["All"],
"write": ["All"],
"delete": ["All"],
}
Note: if your project has not implemented authentication and a custom permission model yet,
keep these Meta defaults so Desk create/read/update/delete works during development.
If you want to implement authentication and role-based access control (RBAC), refer to:
Install database dependencies (important):
Because Framework M is modular and supports database-free edge deployments, persistent storage dependencies are optional. To use a database, install the framework with your preferred engine's extra group:
# Development (SQLite requires aiosqlite)
uv add aiosqlite
# Production (PostgreSQL requires standard extras)
uv add "framework-m-standard[postgres]"
Set database URL in your app .env (important):
Create crm/.env (the same directory where you run uv run m ...):
# Development (SQLite)
DATABASE_URL=sqlite+aiosqlite:///./dev.db
# Production example (PostgreSQL)
# DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/crm
# Stateless / Database-Free Mode (Pure Message Passing, CLI, or Edge)
# DATABASE_URL=none
If DATABASE_URL is set to none (or completely omitted), Framework M boots in Stateless Mode. In this mode, the database engine is bypassed, migrations are skipped, and the framework runs entirely database-free—perfect for transient edge microservices, real-time calculators, or CLI applications.
Run migrations:
For rapid development, use sync to automatically update your database schema based on your DocType definitions:
uv run m migrate sync
Alternatively, use all to run both versioned patches and schema synchronization:
uv run m migrate all
Or follow the traditional Alembic workflow:
uv run m migrate init
uv run m migrate create "Add Contact doctype" --autogenerate
uv run m migrate run
2) Base Desk UI
Start with bundled Desk UI:
uv run m prod
Open http://127.0.0.1:8888/desk/.
Use this when you want ready UI with no custom frontend build.
3) Frontend
Initialize your frontend scaffold:
# Execute from crm root
uv run m new frontend
This creates ./frontend under your crm app and installs dependencies.
Build custom UI when ready:
cd ./frontend
pnpm build
# Switch back to crm root
cd ..
4) Extended UI Apps
Install additional app packages (example):
uv add business-m wms-app
Discovery model:
framework_m.appsentry points → backend DocTypes/routesframework_m.frontendentry points → frontend plugin discovery in dev/build flows
5) Extended UI Plugins
Add local/custom plugin entries in your app frontend modules for composition.
Typical flow:
- add plugin entry files
- run
uv run m devfor live composition - run frontend build for production artifacts
Reference docs:
6) m dev
Use this for day-to-day development:
uv run m dev
Current behavior:
- Backend API server on
127.0.0.1:8888 - Frontend Vite dev server on
127.0.0.1:5173 - Hot reload for frontend + backend workflows
7) m prod
Use this for production-style runtime:
# Bundled Desk via backend
uv run m prod
# Custom UI deployment mode (prebuilt dist served by backend)
uv run m prod --with-frontend
Important for --with-frontend:
- Backend serves prebuilt static from
frontend/dist(viaFRAMEWORK_M_FRONTEND_DIST) m prod --with-frontenddoes not run frontend build
For high-scale production, nginx/CDN static serving is optional. Use this reusable nginx template:
It includes placeholders:
${APP_NAME}${STATIC_ROOT}${BACKEND_UPSTREAM}
Quick API Check
curl http://127.0.0.1:8888/health
curl http://127.0.0.1:8888/api/meta/doctypes