---
title: "Declarative and code modes"
description: "The two ways a Guuey agent runs: a declarative definition the platform keeps current, or your own code that you build and ship. What each is good for, side by side."
---

Every Guuey agent runs in one of two modes. A **declarative** agent is a definition: a system prompt, a model, a framework and the MCP servers it may call. Guuey's runtime loads that definition and runs it. A **code** agent is your own program: framework-native Node code that the [CLI](/cli/) builds into an image and ships. Both run on the same isolated, long-running pods, stream the same way, and keep history the same way (see [How hosting works](/concepts-hosting/)).

In `guuey.json`, the mode is `agent.mode`: `"declarative"` or `"code"`.

## Side by side

|                     | Declarative                                                                                         | Code                                                                                    |
| ------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| What you write      | A definition: system prompt, model, framework, MCP servers                                          | Framework-native code, built into a worker bundle                                       |
| Language            | Nothing to write                                                                                    | Node today                                                                              |
| Where you edit it   | The console, or a `guuey.json` in your repo                                                         | Your repo                                                                               |
| How changes go live | **Save & redeploy** in the console, or [`guuey agent apply`](/agents-as-code/): no build step       | `guuey deploy` builds your image and ships it                                           |
| Runtime updates     | The platform rolls the app to each new runtime image, unless you pin it                             | The framework and worker code in your image change when you rebuild with `guuey deploy` |
| Scaffold            | `npx @guuey/create-agentic-app my-agent --template agent`, or create it in the [console](/console/) | `npx @guuey/create-agentic-app my-agent`                                                |

## When declarative suits you

- **Nothing to build or keep running.** Your definition is the agent. A console edit goes live in about a minute, and nothing builds on your side.
- **The platform keeps it current.** When Guuey releases a new runtime image, it rolls each declarative app to it, starting a ready replacement before the old pod exits, so in-flight turns complete. You don't redeploy to get it. If you'd rather choose the moment, `guuey agent config --runtime-auto-update off` pins the app to the image from its last deploy (see [Runtime updates](/concepts-hosting/#runtime-updates)).
- **Edit from the console or from a repo.** The console's **Behavior** page edits the system prompt in place. From a repo, [Agents as code](/agents-as-code/) gives you a dry-run plan (`guuey agent apply --dry-run`), a drift check (`guuey agent status --check`), a rollback that re-serves an earlier build's exact bytes (`guuey agent rollback --to <n>`), and the repo and commit each build came from.
- **A framework without the code.** Declare `claude-agent-sdk`, `openai-agents-sdk` or `google-adk` in `guuey.json`, and the platform drives that framework for you (see [Frameworks](/hosting/#frameworks)).

## When code suits you

- **Your own logic.** Write framework-native code with the Claude Agent SDK, the OpenAI Agents SDK or Google ADK. The CLI builds it and ships it. Code mode is Node today. From another language, write your tools as an MCP server and connect it to your agent by URL as an `external` server (see [MCP servers](/hosting/#mcp-servers-bring-your-own)).
- **Local development.** A code-mode project runs locally with hot reload (`pnpm dev`) before you deploy (see [Local dev](/cli/#local-dev)).
- **You choose when changes land.** Your image carries the framework and worker code it was built with. The platform does not rebuild your image for you, so a newer framework or worker reaches your app when you next run `guuey deploy`.

## What changes when an app runs code

A code-mode app changes from its project. `guuey agent apply` refuses a code-mode app (see [Agents as code](/agents-as-code/)). The console's **Redeploy** button re-runs a declarative app's most recent deploy. A code-mode app redeploys with `guuey deploy` (see [the Console](/console/)).

## Switch to code mode

As of `@guuey/cli` 0.33.0, `guuey eject` moves a declarative app to code mode:

```bash
npx guuey eject --app-id <id>
```

Before it changes anything, it asks:

```text
  Switch app <id> to code mode? This cannot be undone:
    - guuey can no longer update this app's runtime. A code app runs an image built from your project;
      you rebuild it with guuey deploy to take runtime updates.
    - guuey agent apply, the console and Studio can no longer publish to it.
  Eject? [y/N]
```

Answer `y` and it scaffolds a code project bound to the app, in a new folder named after the app (`--dir <path>` picks another). The project uses the live definition's framework, or the one you pass with `--framework` (`claude-agent-sdk`, `openai-agents-sdk` or `google-adk`). It pulls the app's live definition into the project and deploys it with `guuey deploy`. The first code build replaces the no-code one in place, and the no-code build keeps serving until the code build is live. The app keeps its id, its endpoint host and its conversation threads. Outside a terminal there is no one to ask, so it refuses unless you pass `--yes`.

When it finishes, it prints `App <id> is in code mode. Your project is <dir>; redeploy it with guuey deploy.` If the code build is still deploying, it says so instead: watch `guuey deployments list`, and don't run eject again.

The switch goes one way. Once an app runs code, the server refuses a no-code build for it, so `guuey agent apply`, the console and Studio can no longer publish to it. You update it from the project with `guuey deploy`, and a newer framework or worker reaches it when you rebuild. As of 0.33.0, `guuey deploy` itself doesn't make the switch. On an app whose live build is declarative, it stops and points you to eject:

```text
App <id> is live on guuey's no-code runtime. A code deploy would switch it to code mode for good, so guuey deploy will not do it on its own.
  To switch, run: guuey eject --app-id <id>
  To keep it no-code, edit its definition and run: guuey agent apply
```

With a CLI before 0.33.0, which a scaffold may pin, there is no `eject`. There, the first `guuey deploy` from a code-mode project replaces a live no-code deployment without asking (see [Deploy](/cli/#deploy) in the CLI guide).