modal-fundamentals
Skill4 starsChanged 3 months agoApache-2.0View on GitHub
Core Modal Apps, Functions, entrypoints, deploy/run/serve, environments, and CLI workflows (including app/container logs and shell). Use when creating or structuring Modal apps, running ephemeral or deployed workloads, or looking up Modal CLI commands. Sibling primitives: Servers (modal-servers) and Auto Endpoints (modal-endpoints). For deep log debugging playbooks, use modal-observability.
- Installs packages
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 2 are distinctive, and 11 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 14
Use this skill when building, running, or deploying Modal applications from scratch or when you need to understand the core execution model …
- Very specific: line 150
All Modal methods have async counterparts via .aio suffix:
- Very specific: line 194
Use modal.Mount to add non-importable files explicitly
- Distinctive: line 253
When using AI assistants to write Modal code:
- Very specific: line 256
Use modal run for rapid iteration (not full deployments)
- Very specific: line 257
Use modal serve for web endpoint development with live reload
- Very specific: line 265
Ensure you have a @app.local_entrypoint() or exactly one @app.function()
- Very specific: line 266
Check modal setup / auth was completed
- Very specific: line 278
Ensure include_source=True (default) and file is importable from entrypoint
- Very specific: line 295
Use --detach for long-running ephemeral jobs where the client may disconnect
- Very specific: line 296
Use modal.is_local() to guard local-only code paths
- Very specific: line 297
Use .aio suffix for async operations, not raw await on sync methods
- Very specific: line 298
Prefer single_use_containers=True over deprecated max_inputs=1
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Modal Fundamentals
Use this skill when building, running, or deploying Modal applications from scratch or when you need to understand the core execution model and CLI.
Related serving primitives (SDK 1.5+): Servers (modal-servers) for long-lived HTTP processes; Auto Endpoints (modal-endpoints) for managed LLM APIs; Function web decorators remain in modal-web-serving.
When to Use This Skill
- Creating a new Modal App or Function
- Running ephemeral apps with
modal runormodal serve - Deploying persistent apps with
modal deploy - Writing
local_entrypointor remote entrypoints - Managing Modal environments (dev/staging/prod)
- Understanding the App/Function/container relationship
- Looking up Modal CLI commands (run/serve/deploy/app/container/shell/secrets/volumes)
- Using async Modal APIs
- Structuring Modal projects
Runtime log debugging playbooks (fetch/filter/follow, hung containers, Live Profiling) belong in modal-observability — this skill only lists the CLI surface.
Core Concepts
App
modal.App groups one or more Functions for atomic deployment.
import modal
app = modal.App(name="my-app")
@app.function()
def f():
print("Hello world!")Function
Each Function is an independent autoscaling unit. Zero containers run (zero cost) when idle.
Single-use containers (replace one-shot max_inputs=1):
@app.function(single_use_containers=True)
def one_shot():
...Entrypoints
@app.local_entrypoint()— runs locally, typically calls.remote()on Functions- A single
@app.function()can be the entrypoint if nolocal_entrypointexists modal run script.py::app.func_nameto specify a particular function
Argument parsing is automatic for primitive types:
@app.local_entrypoint()
def main(foo: int, bar: str):
some_function.remote(foo, bar)Execution Modes
| Command | Behavior |
modal run script.py | Ephemeral app, stops when script exits |
modal run --detach script.py | Ephemeral but keeps running after client disconnects |
modal serve script.py | Ephemeral with live-reload for web endpoint development |
modal deploy script.py | Persistent deployed app |
Programmatic execution
with modal.enable_output():
with app.run():
some_function.remote()Deployment
app.deploy(name="my-app", strategy="rolling")Strategies (parity across deploy / rollover / rollback): rolling (default, gradual traffic shift) or recreate (terminate all, then start new).
modal deploy script.py
modal app rollover my-app --strategy=rolling # refresh containers, no code change
modal app rollover my-app --strategy=recreate
modal app rollback my-app --strategy=rolling # same strategy flagsVersion pinning
Pin lookups so inputs stay on one App version after later redeploys (transitive within the App):
f = modal.Function.from_name("my-app", "f", version=3)
Cls = modal.Cls.from_name("my-app", "MyCls", version=3)Environments
Environments isolate resources (Secrets, Volumes, deployed Apps):
modal environment create staging
modal run --env staging script.py
modal deploy --env production script.pySet default: modal config set-environment staging
Dashboard access
modal dashboard # Apps homepage for current environment
modal app dashboard my-app
modal volume dashboard my-volfc = f.spawn()
print(fc.get_dashboard_url()) # object logs / dashboard deep-linkPython versions
- Supported: Python 3.10–3.14 (3.14 supported; 3.9 dropped)
- Experimental 3.14t (free-threaded) via registry +
add_python(Image Builder 2025.06):
modal.Image.from_registry("debian:bookworm-slim", add_python="3.14t")Async API
All Modal methods have async counterparts via .aio suffix:
# Sync
result = f.remote(arg)
# Async
result = await f.remote.aio(arg)
# Async volumes
await vol.read_file.aio("/path")Async functions run concurrent inputs as asyncio tasks (not threads). Sync functions use threading.
Global Variables
Container-scope globals persist across invocations. Use modal.is_local() for conditional init:
if modal.is_local():
weights = None # don't download locally
else:
weights = download_weights()Project Structure
Recommended layout:
my-modal-project/
├── my_module/
│ ├── __init__.py
│ ├── app.py # modal.App() and function definitions
│ └── utils.py
├── pyproject.toml
└── .modal/
└── environment # default environment nameDeploy with: modal deploy -m my_module.app
Key rules:
include_source=True(default) adds files reachable from entrypoint to container- Use
modal.Mountto add non-importable files explicitly - Set
MODAL_ENVIRONMENTenv var or.modal/environmentfile for default environment
Go SDK
The Go SDK can call deployed Functions, create Sandboxes, and manage resources — but cannot define Functions.
import modal "github.com/modal-labs/modal-client/go"
// Create client
mc, _ := modal.NewClient()
// Reference an App
app, _ := mc.Apps.FromName(ctx, "my-app", &modal.AppFromNameParams{CreateIfMissing: true})
// Call a deployed Function
fn, _ := mc.Functions.FromName(ctx, "my-app", "my_function", nil)
result, _ := fn.Remote(ctx, []any{"arg1"}, nil)Install: go get -u github.com/modal-labs/modal-client/go (requires Go 1.23+)
TypeScript SDK
The TypeScript SDK mirrors Go capabilities — call Functions, create Sandboxes, manage resources.
import { ModalClient } from "modal";
const modal = new ModalClient();
// Reference an App
const app = await modal.apps.fromName("my-app", { createIfMissing: true });
// Call a deployed Function
const fn = await modal.functions.fromName("my-app", "my_function");
const result = await fn.remote(["arg1"]);Install: npm install modal (requires Node.js 22+)
SDK Feature Parity
| Feature | Python | Go | TypeScript |
| Define Functions | Yes | No | No |
| Call Functions | Yes | Yes | Yes |
| Sandboxes | Yes | Yes | Yes |
| Volumes | Yes | Yes | Yes |
| Queues | Yes | Yes | Yes |
| Secrets | Yes | Yes | Yes |
| Images | Yes | Yes | Yes |
| Scheduling | Yes | No | No |
| Web endpoints | Yes | No | No |
| Servers / Endpoints | Yes (define) | Call/manage where exposed | Call/manage where exposed |
Developing with LLMs
When using AI assistants to write Modal code:
- Install
modallocally for type checking - Provide Modal Python SDK stubs for autocomplete
- Use
modal runfor rapid iteration (not full deployments) - Use
modal servefor web endpoint development with live reload - Install/update the official Modal agent skill:
modal skills install/modal skills update - Surface new SDK features:
modal changelog --since=1.5ormodal changelog --newer - Bootstrap starter apps (experimental):
modal bootstrap
Symptom Triage
"modal run does nothing"
- Ensure you have a
@app.local_entrypoint()or exactly one@app.function() - Check
modal setup/ auth was completed
"App deploys but Functions don't run"
- Scheduled Functions need
modal deploy, notmodal run - Non-scheduled Functions need explicit invocation (web URL,
.remote(), etc.)
"Logs are missing"
- Programmatic
app.run(): wrap withmodal.enable_output() - Dashboard deep links:
modal dashboard/.get_dashboard_url() - Otherwise load
modal-observability(references/logging-debugging.md) — do not improvise from dashboard-only advice
"Import error: module not found in container"
- Ensure
include_source=True(default) and file is importable from entrypoint - Or add explicit
modal.Mount.from_local_dir()in image definition - Reproduce in a fresh image shell:
modal shell script.py::fn
Reference Map
references/apps-and-functions.md— App/Function lifecycle, naming, entrypoints,single_use_containers, version pinningreferences/cli-commands.md— run/serve/deploy, app/container logs, shell, rollover, bootstrap, changelog, skills, dashboard, envreferences/environments.md— Environment isolation and configurationreferences/local-development.md— serve, hot reload, interactive debug, shells- Sibling skills:
modal-servers,modal-endpoints,modal-web-serving,modal-observability
Guardrails
- Everything is code — no YAML configuration files
modal.Stubis removed since Modal 1.0; usemodal.App- Protect
app.run()inif __name__ == "__main__"blocks to avoid running in containers - Use
--detachfor long-running ephemeral jobs where the client may disconnect - Use
modal.is_local()to guard local-only code paths - Use
.aiosuffix for async operations, not rawawaiton sync methods - Prefer
single_use_containers=Trueover deprecatedmax_inputs=1 - Deploy / rollover / rollback share
--strategy=rolling|recreate - Python 3.9 is unsupported; pin client
~=1.5.0when tracking 1.5 features - Official agent skill:
modal skills install/modal skills update(version-aligned refs when installed via CLI)
In this repository80 other files it gives its agents.
- a11y-accessibility-designSkill
- agentic-ui-patternsSkill
- ai-native-ui-designSkill
- ai-ui-anti-patternsSkill
- ai-ui-heuristicsSkill
- calm-technology-uiSkill
- conversion-growth-designSkill
- cross-platform-designSkill
- dark-mode-designSkill
- data-visualizationSkill
- design-systemsSkill
- design-thinking-processSkill
- error-empty-statesSkill
- ethical-design-patternsSkill
- form-uxSkill
- information-architectureSkill
- interaction-design-patternsSkill
- internationalization-uiSkill
- mobile-touch-designSkill
- modal-classes-lifecycleSkill
- modal-container-imagesSkill
- modal-dicts-queuesSkill
- modal-endpointsSkill
- modal-gpu-computeSkill
- modal-networkingSkill
- modal-observabilitySkill
- modal-parallel-executionSkill
- modal-sandboxesSkill
- modal-scaling-performanceSkill
- modal-schedulingSkill
- modal-secretsSkill
- modal-serversSkill
- modal-storageSkill
- modal-web-servingSkill
- modal-workspace-adminSkill
- motion-design-principlesSkill
- notifications-permissionsSkill
- onboarding-uxSkill
- rust-api-designSkill
- rust-async-programmingSkill
- rust-cargo-masterySkill
- rust-cli-applicationsSkill
- rust-clippy-lintsSkill
- rust-closures-iteratorsSkill
- rust-compiler-internalsSkill
- rust-concurrencySkill
- rust-design-patternsSkill
- rust-editionsSkill
- rust-embeddedSkill
- rust-error-handlingSkill
- rust-game-developmentSkill
- rust-lifetimes-borrowingSkill
- rust-macrosSkill
- rust-performanceSkill
- rust-rustdocSkill
- rust-rustup-toolchainSkill
- rust-smart-pointersSkill
- rust-testing-benchmarkingSkill
- rust-type-systemSkill
- rust-unsafe-ffiSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

