Skip to main content

Architecture Strategy

To build a robust Agent UI (like the one in this course) using Vibe Coding, do not just tell the AI to "Make an app." You must guide it through a structured pattern.

We recommend the Redux Pattern (even without using the Redux library itself) because it forces the AI to be predictable.

The Mental Model

In this architecture, the View never changes data directly. It dispatches an Action, which flows through Middleware (for API calls/Side Effects) before reaching the Reducer to update the State.

Glossary of Terms

  • Store: The single source of truth. It is a container that holds your entire application's data in one place.
  • State: A snapshot of data at a specific moment in time (e.g., isLoading: true, user: null).
  • Action: A plain object describing what happened (e.g., { type: 'LOGIN_CLICKED' }). It does not change data itself; it just announces an event.
  • Middleware: The "Man in the Middle." It sits between the Action and the Reducer to handle side effects like API calls, logging, or delays.
  • Reducer: A pure function that takes the Current State and an Action, calculates the logic, and returns the New State.
  • Mutation: The act of changing the state. In this pattern, we don't modify variables directly; we replace the old state object with a new one.

The Vibe Coding Workflow

This "Cheat Sheet" outlines the 7 sequential steps required to prompt an AI effectively for complex UIs.

#PhaseCritical Actions & Output
1User Journeys

Map specific user actions, entry points, and success states.
Output: A bulleted list of "User clicks X, expects Y".

2Define State

Create the AppState interface. Define the Shape of Data (User object, Message history, Loading flags) before writing UI code.

3Define Actions

List event types (LOGIN_SUCCESS, SEND_MESSAGE).
Goal: Prevent spaghetti logic by standardizing events.

4Map to Views

Connect State to UI Components. Determine conditional rendering logic (e.g., If authStatus === 'anonymous', show Login).

5Logic & Auth

Implement Reducers and Side Effects. Handle the complexity of OAuth/Firebase and asynchronous data fetching.

6Persistence

Define hydration strategies. Use localStorage for sessions and cache expensive API data to improve UX.

7Security

Crucial Step: Secure API keys, sanitize inputs, and remove sensitive console logs before deployment.


Detailed Breakdown

AI-Assisted Implementation

Recommendation: Use an AI agent or coding tool while implementing these steps to explore different architectural patterns.

Software best practices evolve rapidly. Before committing to a specific implementation, research the latest standards for your stack. The code snippets and examples provided below are placeholders meant to illustrate the "Vibe Coding" mental model; they are not comprehensive production specifications.

Below is the detailed explanation of the process visualized above.

Step 1: Describe the User Journeys

First, write down exactly what the user does.

  • Journey A: User lands on the page and sees a "Login with Google" button.
  • Journey B: User types a message in the chat box and hits enter.
  • Journey C: User enters their Gemini API Key in a settings modal.
  • Journey D: User views a visual canvas of their agent graph.

Step 2: Define the State (The Source of Truth)

In modern UI development, UI = f(State). The User Interface is just a function of the data currently held in memory. Tell the AI to define the state interface first.

interface AppState {
// Authentication
user: User | null;
authStatus: 'idle' | 'authenticated' | 'anonymous';

// The Conversation
messages: Array<{
role: 'user' | 'model';
text: string;
timestamp: number;
}>;

// Configuration
apiKey: string | null;
isSettingsOpen: boolean;
}

Step 3: Define Actions (Interactions)

Define how the state changes. This prevents "Spaghetti Code" where random components modify data unpredictably.

  • LOGIN_SUCCESS: Sets authStatus to 'authenticated'.
  • SEND_MESSAGE: Adds a user message to the messages array.
  • RECEIVE_RESPONSE: Adds a model message to the messages array.
  • OPEN_SETTINGS: Toggles isSettingsOpen to true.

Step 4: Map State to Views (Screens)

Now, ask the AI to build components based on that state.

  • If authStatus === 'anonymous', Show <LoginScreen />.
  • If authStatus === 'authenticated', Show <MainLayout />.
  • Inside <ChatWindow />, render the list of messages.

Step 5: Authentication & Login

Explicitly tell the AI how to handle security.

  • Requirement: Use Firebase Auth or OAuth.
  • Action: When the user clicks login, trigger the provider popup. On success, dispatch LOGIN_SUCCESS.

Step 6: Data Models & Persistence

Decide where the data lives.

  • Ephemeral: Chat history might live only in React State (RAM) for this session.
  • Persistent: The API Key should be stored in localStorage (Client-side) so it persists across reloads but never leaves the browser.

Step 7: Security & Credential Management

When Vibe Coding, you must explicitly instruct the AI on security boundaries:

  • Rule: "Never hardcode API keys."
  • Rule: "The User's Gemini API Key must be stored in the browser's LocalStorage and only passed to the AI model function when needed."
  • Rule: "Do not log sensitive data to the console in production."