# Contents

Agents built on Convex have a good life. Their conversations are durable, their state is reactive, and every open browser tab agrees about what's happening without a single line of sync code. But the moment one of those agents needs to run something — execute the code it just wrote, poke a filesystem, start a dev server — it has to leave that world and call out to raw infrastructure.

We just closed that gap. `@daytona/convex` brings isolated cloud computers for your agents to the Convex component directory, installed into your backend like any other component.

Why this pairing works

Convex's whole thesis is that state should be one consistent, subscribable thing — the database is the sync engine. Daytona's thesis is that agent code should run on real, isolated, disposable machines. The component fuses them: every sandbox and every command execution becomes a row in reactive Convex tables.

That sounds like bookkeeping. It isn't. It means a command's status flips from running to completed in your UI the moment it exits — no polling, no websocket plumbing. It means a user can refresh mid-job and the progress picks up exactly where it is, because it never lived in the connection. It means a second tab, a teammate's browser, and an admin dashboard all see the same execution history for free. Execution stops being a side effect your UI chases and becomes state your UI simply reads.

What's in the box

From Daytona: sandboxes that start from snapshots or any Docker image, shell and code execution, filesystem operations, signed preview URLs for anything serving a port, and lifecycle hygiene (auto-stop, auto-delete) so experiments clean up after themselves.

From Convex: live queries over all of it, durable execution records, multi-client consistency, and the scheduler — which powers runBackground, our answer to long-running work: start a command, get an execution ID back immediately, and watch logs stream into the row while a chain of lightweight scheduled functions supervises it. No action held open, no 10-minute ceiling.

Crash course

1npm install @daytona/convex
2npx convex env set DAYTONA_API_KEY dtn_...
1// convex/convex.config.ts
2import daytona from "@daytona/convex/convex.config.js";
3app.use(daytona);
1// convex/agent.ts
2const daytona = new Daytona(components.daytona);
3
4export const codeInterpreter = action({
5 args: { code: v.string() },
6 handler: async (ctx, args) => {
7 const { sandboxId } = await daytona.createSandbox(ctx, { autoStopInterval: 15 });
8 return await daytona.runCode(ctx, { sandboxId, code: args.code, language: "python" });
9 },
10});

That's a working code-interpreter tool. Subscribe to daytona.listExecutions from your frontend and the run history renders itself, live.

To see how far the pattern stretches, we built an AI app builder on top of it: describe an app in one prompt, watch the LLM's code stream into the page as reactive state, and get the finished app running in an iframe via a Daytona preview URL — refresh-proof, multi-tab, ~200 lines total.

Get started

Tags::
  • convex
  • ai-agents
  • sandboxes
  • integrations