In v2, Agentuity owns the app container. In v3, your framework owns the app and Agentuity adds services, local development, build metadata, and deploy.
import { createApp } from '@agentuity/runtime';
import api from './src/api';
import agents from './src/agent';
export default await createApp({
router: { path: '/api', router: api },
agents,
});When you switch to the v3 CLI after migration, the commands below use agentuity ... for readability. If the CLI is only installed locally, run the same command through your package manager's exec wrapper, for example npx agentuity ... or bunx agentuity ....
Keep the Framework Entry Point
A v3 app keeps the framework's normal entry point. In a Hono app, that means new Hono() and normal route mounting:
import { Hono } from 'hono';
import { agentuity } from '@agentuity/hono';
import api from './api';
import type { Services } from '@agentuity/hono';
type Variables = Services;
const app = new Hono<{ Variables: Variables }>();
app.use('*', agentuity());
app.route('/api', api);
export default app;For Next.js, React Router, Remix, TanStack Start, Astro, SvelteKit, or Nuxt, keep that framework's route and server conventions instead of recreating the v2 runtime structure.
Replace Runtime Concepts
| v2 concept | v3 replacement |
|---|---|
createApp() | framework entry point, such as src/index.ts for Hono or route handlers for Next.js |
createRouter() | the framework router directly, such as new Hono() |
createAgent() | plain functions, AI SDK calls, server functions, or route handlers |
ctx.kv, ctx.vector, ctx.queue | standalone service clients imported where needed |
c.var.kv in Hono routes | standalone clients, or @agentuity/hono middleware when c.var.* fits the route |
ctx.thread, ctx.session, ctx.sessionId | explicit app state, cookies, databases, KV records, or platform session inspection |
agentuity.config.ts | framework config plus agentuity.json |
app-level setup() and shutdown() | module initialization, framework lifecycle hooks, or process cleanup |
The @agentuity/runtime package in v3 exists to catch old imports and point you at the framework model. Existing v2 apps can keep using their v2 packages until they migrate. Do not install the v3 runtime package expecting the v2 app container to run unchanged.
Prefer Service Clients First
Direct service clients are the portable default because the same code can run in routes, server functions, scripts, and workers.
import { KeyValueClient } from '@agentuity/keyvalue';
export const kv = new KeyValueClient();import { Hono } from 'hono';
import { kv } from '../services';
const router = new Hono();
router.post('/', async (c) => {
const body: unknown = await c.req.json();
const id = crypto.randomUUID();
await kv.set('events', id, {
id,
body,
createdAt: new Date().toISOString(),
});
return c.json({ id }, 201);
});
export default router;Use @agentuity/hono when a Hono route reads better with injected services:
import { Hono } from 'hono';
import { agentuity } from '@agentuity/hono';
import type { Services } from '@agentuity/hono';
type Variables = Pick<Services, 'kv'>;
const app = new Hono<{ Variables: Variables }>();
app.use('*', agentuity());
app.get('/api/latest', async (c) => {
const latest = await c.var.kv.get('events', 'latest');
return c.json({ latest });
});
export default app;Move Agents into App Code
Simple v2 agents usually become plain functions:
export async function summarize(input: {
readonly text: string;
}): Promise<{ readonly summary: string }> {
// Call your model provider or AI SDK here
return { summary: input.text.slice(0, 120) };
}Then call that function from the route, queue consumer, scheduled job, task handler, or server function that owns the request.
import { Hono } from 'hono';
import { z } from 'zod';
import { summarize } from '../agent/summarize';
const inputSchema = z.object({
text: z.string(),
});
const router = new Hono();
router.post('/', async (c) => {
const body: unknown = await c.req.json();
const input = inputSchema.parse(body);
const result = await summarize(input);
return c.json(result);
});
export default router;Complex agents need review when they use lifecycle hooks, event listeners, ctx.config, or ctx.app. Those concepts were tied to the v2 runtime container, so the right v3 replacement depends on where that state belongs in your framework app.
Thread and session state also need a design pass. A chat app might move message history to KV or a database keyed by an app session cookie. A debugging tool might use platform session and thread records only for inspection.
Register and Build the Framework App
After the app shape is framework-native, link it to Agentuity Cloud and run the packaging check:
agentuity project import --validate-only
agentuity project import
agentuity buildagentuity project import writes agentuity.json and creates or updates .env with AGENTUITY_SDK_KEY. agentuity build detects the framework, runs the framework build, writes .agentuity, and packages launch metadata for deploy.
Next Steps
- Migrating from v2: run the migration in order
- Migration CLI: inspect what the tool changes automatically
- Frameworks: choose framework-specific setup guidance