Skip to content

Modal.Dict reference

Source: packages/modal/src/CreateDict.ts

Create dicts by name at runtime: one per user, session or task. Modal’s native shape is get-or-create by name, so getOrCreate is idempotent and safe to call on every request.

Bind it to a Modal.Environment to keep these runtime objects in their own namespace (or to nothing, for the workspace’s default environment). They aren’t in Alchemy state: deleting the environment removes them.

Objects created at run time are tagged with the stack, stage and binding (alchemy::stack, alchemy::stage, alchemy::id) and are not deleted when the stack is destroyed. A Modal dict has only a name, so the tags become its name prefix, Modal.runtimePrefix({ stack, stage, id }): list them with modal dict list and delete the ones whose name starts with it.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import { HttpServerRequest } from "effect/http/HttpServerRequest";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Agents, Coder } from "./Coder.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const dicts = yield* Modal.CreateDict(Agents);
const sandboxes = yield* Modal.CreateSandbox(Coder);
return {
fetch: Effect.gen(function* () {
const request = yield* HttpServerRequest;
const user = request.headers["x-user"] ?? "anonymous";
const state = yield* dicts.getOrCreate(`state-${user}`);
yield* state.put("lastSeen", Date.now());
return HttpServerResponse.text("ok");
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Layer.mergeAll(Modal.CreateDictHttp, Modal.CreateSandboxHttp))),
) {}

Source: packages/modal/src/CreateDictHttp.ts Kind: Layer · Provides: Modal.CreateDict

CreateDict over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the environment.

Source: packages/modal/src/Dict.ts

A Modal Dict: a distributed key-value store shared by every container, Sandbox and client in the workspace. Entries expire 7 days after their last write.

Bind it with ReadDict, WriteDict or ReadWriteDict to use it from a Worker, Lambda or any other runtime. Values travel as bytes: the bindings encode them as JSON by default.

Modal dicts have no tags. Ownership is inferred from Alchemy state: a dict found under an explicit name without prior state is reported as unowned.

A dict with a generated name

import * as Modal from "@alchemy.run/modal";
export const Results = Modal.Dict("Results", {});

A named dict in an environment

import * as Modal from "@alchemy.run/modal";
export const Agents = Modal.Environment("Agents", {});
export const Sessions = Modal.Dict("Sessions", { name: "sessions", environment: Agents });
import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Results } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const results = yield* Modal.ReadWriteDict(Results);
return {
fetch: Effect.gen(function* () {
yield* results.put("last-run", { ok: true });
const last = yield* results.get("last-run");
return yield* HttpServerResponse.json(last ?? null);
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.ReadWriteDictHttp)),
) {}

Dict.lookup references a dict Alchemy doesn’t manage (created with the Modal CLI or by another stack). It is read during plan/deploy, never created, updated or deleted.

const cache = Modal.Dict.lookup({ name: "cache" });

Source: packages/modal/src/ReadDict.ts

Read a Modal Dict from any runtime: get, contains, len and entries. Keys and values are JSON.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Results } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const dict = yield* Modal.ReadDict(Results);
return {
fetch: Effect.gen(function* () {
const last = yield* dict.get("last-run");
return yield* HttpServerResponse.json(last ?? null);
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.ReadDictHttp)),
) {}

Source: packages/modal/src/ReadDictHttp.ts Kind: Layer · Provides: Modal.ReadDict

ReadDict over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the viewer role on the dict’s environment.

Source: packages/modal/src/ReadWriteDict.ts

Read and write a Modal Dict from any runtime. Keys and values are JSON.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Results } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const dict = yield* Modal.ReadWriteDict(Results);
return {
fetch: Effect.gen(function* () {
yield* dict.put("hits", ((yield* dict.get<number>("hits")) ?? 0) + 1);
return yield* HttpServerResponse.json({ hits: yield* dict.get("hits") });
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.ReadWriteDictHttp)),
) {}

Source: packages/modal/src/ReadWriteDictHttp.ts Kind: Layer · Provides: Modal.ReadWriteDict

ReadWriteDict over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the dict’s environment.

Source: packages/modal/src/WriteDict.ts

Write a Modal Dict from any runtime: put, update, pop and clear. Keys and values are JSON.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Results } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const dict = yield* Modal.WriteDict(Results);
return {
fetch: Effect.gen(function* () {
yield* dict.put("last-run", { ok: true });
return HttpServerResponse.text("saved");
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.WriteDictHttp)),
) {}

Source: packages/modal/src/WriteDictHttp.ts Kind: Layer · Provides: Modal.WriteDict

WriteDict over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the dict’s environment.