Building Agent-Native Apps After Claude Code: Principles and Practices

The article outlines the Agent‑native architecture introduced by Claude Code, detailing five core principles, file‑as‑interface design, mobile considerations, dynamic capability discovery, implementation patterns, product implications, and anti‑patterns, providing a concrete roadmap for building self‑improving AI agents.

AI Engineering
AI Engineering
AI Engineering
Building Agent-Native Apps After Claude Code: Principles and Practices

Claude Code has sparked a shift in how intelligent agents are built, moving from glue‑code or drag‑and‑drop approaches toward Agent‑native applications that describe desired outcomes and let a continuously running agent achieve them.

Claude Code illustration
Claude Code illustration

The recent "Agent‑Native Architecture" guide co‑authored by Dan Shipper and Claude defines five core principles and explores implementation details.

Five Core Principles

1. Parity

Any operation a user can perform via the UI must be achievable by the agent through tools. This is the foundational requirement.

Test method: Choose any UI action and verify the agent can complete it.

2. Granularity

Tools should be atomic primitives; features are the results described in prompts that the agent repeatedly executes until achieved.

Judgment criterion: When changing behavior, are you editing the prompt or refactoring code?

3. Composability

With atomic tools and parity, new functionality can be created simply by writing a new prompt. For example, a "weekly report" can be generated with a prompt that asks the agent to review modified files, summarize key changes, and suggest three priorities for the next week.

Typical tool usage: list_files, read_file.

4. Emergent Capability

The agent can accomplish tasks that were not explicitly designed. The operational loop is:

Build with atomic tools and parity.

Receive a user request that was not anticipated.

The agent composes tools to attempt the request, exposing gaps on failure.

Observe request patterns.

Add domain‑specific tools or refine prompts to handle common patterns.

Repeat.

Test standard: Can the agent handle open‑ended requests within your domain?

5. Self‑Improvement

Agent‑native apps improve by accumulating context and optimizing prompts, without publishing new code.

Context accumulation: State persists across sessions via context files.

Developer‑level optimization: Update prompts for all users.

User‑level customization: Users modify prompts for their own workflows.

File as a Universal Interface

Instead of traditional APIs, files become the primary interaction medium. Agents already understand commands like cat, grep, mv, and mkdir, making file operations a natural fit.

Benefits include user visibility, easy export/backup, cross‑device sync via iCloud, and self‑documentation (e.g., /projects/acme/notes/ is more readable than a SQL query).

Directory Structure Design

Documents/
├── AgentCheckpoints/     # temporary files
│   └── {sessionId}.checkpoint
├── AgentLogs/           # debug logs
│   └── {type}/{sessionId}.md
└── Research/            # user workspace
    └── books/{bookId}/
        ├── full_text.txt
        ├── notes.md
        └── agent_log.md

Context Injection Pattern

# Context

## Who I Am
Reading assistant for the Every app.

## What I Know About This User
- Interested in military history and Russian literature
- Prefers concise analysis

## What Exists
- 12 notes in /notes
- three active projects

## Recent Activity
- User created "Project kickoff" (two hours ago)

## My Guidelines
- Don't spoil books they're reading
- Use their interests to personalize insights

The agent reads this file at session start and updates it as state changes, providing portable working memory without code changes.

Mobile‑Specific Opportunities and Challenges

Opportunities

File‑system support: Agents can use the same file‑based primitives on mobile.

Rich device context: Access to health data, location, photos, calendar, etc., unavailable on desktop.

Local app copies: Each user has an independent app instance that can evolve autonomously.

State sync via iCloud: All devices share the same file system, eliminating the need for a server.

Challenges

Agents may run for seconds, minutes, or hours, but iOS suspends inactive apps after a few seconds, potentially terminating them.

Design considerations include checkpointing, resume functionality, judicious background execution, and deciding which components run locally versus in the cloud.

Checkpoint and Resume Implementation

struct AgentCheckpoint: Codable {
  let agentType: String
  let messages: [[String: Any]]
  let iterationCount: Int
  let taskListJSON: String?
  let customState: [String: String]
  let timestamp: Date
}

func isValid(maxAge: TimeInterval = 3600) -> Bool {
  Date().timeIntervalSince(timestamp) < maxAge
}

Checkpoints are saved when the app backgrounds, after each tool result, and periodically during long operations.

Resume flow:

Scan the checkpoint directory with loadInterruptedSessions().

Filter using isValid(maxAge:).

Show a resume prompt.

Reload messages and continue the agent loop.

Delete the checkpoint on successful exit.

Advanced Mode: Dynamic Capability Discovery

Static mapping (e.g., one tool per data type) requires code changes for new metrics. Dynamic discovery uses two generic tools:

// Two tools handle everything
list_available_types() → returns ["steps", "heart_rate", "sleep", ...]
read_data(type) → reads any discovered type

// Adding a new metric: the agent automatically discovers it.

This follows the granularity principle: atomic tools enable the agent to handle types that were unknown at build time.

Applicable scenarios include full user‑level API access (HealthKit, HomeKit, GraphQL), systems that evolve over time, and any task where the agent should be able to use any supported API.

Implementation Patterns

Shared Workspace

Agents and users operate in the same data space rather than isolated sandboxes.

UserData/
├── notes/          ← read/write by both
├── projects/       ← agent can organize, user can override
└── preferences.md  ← agent reads, user edits

Users can inspect and modify agent work.

Agents can build on user‑created content.

No synchronization layer is needed.

Full transparency.

Sandboxing should be reserved for specific security or data‑damage concerns.

Agent Execution Model

Agents need an explicit completion signal rather than heuristic detection.

struct ToolResult {
  let success: Bool
  let output: String
  let shouldContinue: Bool
}

.success("Result")   // continue
.error("Message")    // retry
.complete("Done")    // stop loop

Model level selection: not every operation requires the same AI capability; choose the appropriate model tier for the task.

Agent‑to‑UI Communication

Agent actions must be immediately reflected in the UI.

enum AgentEvent {
    case thinking(String)        // show thinking indicator
    case toolCall(String, String) // show tool in use
    case toolResult(String)      // optionally display result
    case textResponse(String)    // stream to chat
    case statusChange(Status)    // update status bar
}

Principle: no silent operations; visible progress builds trust.

Product‑Level Impact

Progressive Disclosure

Simple entry: basic requests work immediately with no learning cost.

Discoverable depth: users uncover new capabilities as they explore.

Unlimited expansion: power users can push the system in unforeseen directions.

Demand Discovery

Observe what users ask agents to do. Successful requests signal demand; failures reveal gaps in tools or parity.

Anti‑Pattern Warnings

Using the agent merely as a router that decides which function to call.

Building the application first and then adding an agent on top.

Request/response mindset that ignores the iterative loop.

Overly defensive tool design that restricts input too much.

Embedding all logic in code and letting the agent only execute it.

Success‑Criteria Checklist

Architecture

Parity: agent can perform any UI action.

Granularity: tools are atomic primitives.

Composability: new features arise from new prompts.

Emergent capability: agent handles un‑designed tasks.

Behavior modification via prompt edits, not code changes.

Implementation

System prompt lists available resources and capabilities.

Shared data space between agent and user.

Real‑time UI feedback.

Full CRUD for each entity.

Dynamic capability discovery where appropriate.

Explicit completion signals.

Product

Progressive disclosure with zero learning curve.

Unlimited extensibility for advanced users.

Demand discovery through observation of agent requests.

Approval mechanisms that match risk and reversibility.

Mobile

Checkpoint/recovery to survive interruptions.

iCloud‑first storage with local fallback.

Background execution using limited iOS time.

Ultimate test: describe a result in your domain that the app does not yet implement. If the agent can devise a way to achieve it through the loop, the app is truly Agent‑native; otherwise, the architecture is too constrained.

mobile AIAI agentsself-improvementClaude CodeAgent-native architectureemergent capabilityshared workspace
AI Engineering
Written by

AI Engineering

Focused on cutting‑edge product and technology information and practical experience sharing in the AI field (large models, MLOps/LLMOps, AI application development, AI infrastructure).

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.