---
title: "@flowiseai/agentflow - Architecture"
description: "This document describes the internal architecture of the `@flowiseai/agentflow` package."
type: skill
canonical_url: https://claudary.paisolsolutions.com/skills/architecture-6
source: "Claudary"
difficulty: intermediate
author: "Claude Code Knowledge Pack"
date: 2026-07-10T11:07:07.924Z
license: CC-BY-4.0
attribution: "@flowiseai/agentflow - Architecture — Claudary (https://claudary.paisolsolutions.com/skills/architecture-6)"
---

# @flowiseai/agentflow - Architecture
This document describes the internal architecture of the `@flowiseai/agentflow` package.

## Overview

# @flowiseai/agentflow - Architecture

This document describes the internal architecture of the `@flowiseai/agentflow` package.

## Overview

The package follows a **Domain-Driven Modular Architecture** with clear separation of concerns. The goal is to separate low-level UI primitives from high-level business logic to ensure high reusability and easy testing.

```
src/
├── index.ts                    # Public Package API ("Public Face")
├── Agentflow.tsx               # Main component
├── AgentflowProvider.tsx       # Root provider (composition)
├── useAgentflow.ts             # Primary public hook
│
├── atoms/                      # ⚛️ UI Primitives ("What it looks like" (Dumb))
├── features/                   # 🧩 Domain Features ("What it does" (Smart))
├── core/                       # 🧠 Business Logic ("Business Rules" (Types/Logic))
└── infrastructure/             # 🌐 External Services ("Outside World" (API/Storage))
```

---

## Directory Structure

### `atoms/` - UI Primitives

**"What it looks like."** Tiny, irreducible UI components with no business logic. These are the building blocks used by features.

```
atoms/
├── MainCard.tsx            # Styled card wrapper
├── NodeInputHandler.tsx    # Form input for node properties
├── ...                     # Other UI primitives
└── index.ts                # Central export
```

**Rules:**

-   Must be "dumb" and stateless
-   No business logic
-   No API calls
-   Stateless or minimal local state
-   Imported by features, never the reverse
-   **Forbidden**: Importing from `features/` or `infrastructure/` (except types from `core/types` for prop definitions, design tokens from `core/theme`, and primitives from `core/primitives`)

**Goal:** 100% visual consistency.

---

### `features/` - Domain Features

**"What it does."** Complex, self-contained domain modules (silos) that house the application's core functionality. Each feature owns its components, hooks, and utilities.

```
features/
├── canvas/                 # Core ReactFlow canvas
│   ├── containers/         # Smart components with state/logic
│   │   ├── AgentFlowNode.tsx
│   │   ├── AgentFlowEdge.tsx
│   │   ├── ...             # Other node containers
│   │   └── index.ts
│   ├── components/         # Presentational components
│   │   ├── ConnectionLine.tsx
│   │   ├── NodeOutputHandles.tsx
│   │   ├── ...             # Other presentational components
│   │   └── index.ts
│   ├── hooks/              # Canvas-related hooks
│   │   ├── useFlowHandlers.ts
│   │   ├── useDragAndDrop.ts
│   │   ├── ...             # Other canvas hooks
│   │   └── index.ts
│   ├── styled.ts           # Styled components
│   └── index.ts            # Public API
│
├── node-palette/           # Add nodes drawer
│   ├── AddNodesDrawer.tsx
│   ├── search.ts           # Feature-specific utility (private)
│   ├── ...
│   └── index.ts
│
├── generator/              # AI flow generation
│   ├── GenerateFlowDialog.tsx
│   ├── ...
│   └── index.ts
│
└── node-editor/            # Node property editing
    ├── EditNodeDialog.tsx
    └── index.ts
```

**Rules:**

-   Each feature has an `index.ts` gatekeeper
-   **Features never import from other features directly** - If `canvas` needs logic from `generator`, move that logic to `core/`
-   Feature-specific utils stay in the feature folder
-   Styles are co-located with their feature
-   Use `containers/` for smart components (with state, hooks, side effects)
-   Use `components/` for presentational components (props in, JSX out)

**Goal:** High cohesion. Should be able to delete a feature folder without breaking others.

---

### `core/` - Business Logic

**"The Brain."** Framework-agnostic logic, types, and utilities. No React, no UI - pure TypeScript. Contains validation schemas, node registries, domain constants, and shared types.

```
core/
├── types/                  # Global interfaces (Node, Edge, Flow)
│   └── index.ts
├── primitives/             # Domain-free utilities (safe for atoms)
│   ├── inputDefaults.ts    # getDefaultValueForType
│   └── index.ts
├── node-config/            # Node configuration (icons, colors, default types)
│   ├── nodeIcons.ts        # AGENTFLOW_ICONS, DEFAULT_AGENTFLOW_NODES
│   └── ...
├── node-catalog/           # Node catalog and filtering logic
│   ├── nodeFilters.ts      # filterNodesByComponents, isAgentflowNode
│   └── ...
├── theme/                  # Design tokens and MUI theming
│   ├── tokens.ts           # Color palettes, spacing, shadows
│   ├── createAgentflowTheme.ts
│   └── ...
├── validation/             # Flow validation logic
│   ├── flowValidation.ts   # validateFlow, validateNode
│   ├── connectionValidation.ts  # isValidConnectionAgentflowV2
│   └── ...
├── utils/                  # Domain-aware utilities (NOT importable by atoms)
│   ├── nodeFactory.ts      # initNode, getUniqueNodeId
│   └── ...
└── index.ts                # Barrel export (use sparingly)
```

**Rules:**

-   **No React components allowed** - Pure TypeScript only
-   No browser-specific APIs if possible
-   No side effects
-   Pure functions where possible
-   Can be tested in isolation

#### `core/primitives/` vs `core/utils/`

`core/` contains two utility directories with different import permissions:

-   **`primitives/`** — Domain-free, general-purpose functions with no knowledge of nodes, flows, or any business concept. These are pure data transformations (e.g., computing a default value from a type string). **Safe to import from `atoms/`.**
-   **`utils/`** — Domain-aware utilities that understand node structures, flow data, or validation logic (e.g., `initNode`, `buildDynamicOutputAnchors`). **Only importable by `features/` and `infrastructure/`.**

When adding a new utility, ask: _"Does this function need to know what a Node or Flow is?"_ If no → `primitives/`. If yes → `utils/`.

**Goal:** To be the framework-agnostic source of truth.

---

### `infrastructure/` - External Services

**"The Outside World."** Handles communication with external systems: data persistence, network requests, and global state management.

```
infrastructure/
├── api/                    # API client layer (network requests)
│   ├── client.ts           # Axios factory
│   ├── ...                 # Endpoint modules (nodes, chatflows, etc.)
│   └── index.ts
│
└── store/                  # State management
    ├── AgentflowContext.tsx # Flow state context
    ├── agentflowReducer.ts # Reducer for flow state actions
    ├── ...                 # Other contexts (ApiContext, ConfigContext)
    └── index.ts
```

**Rules:**

-   All external communication goes here
-   Contexts are internal (composed in AgentflowProvider)
-   API hooks live with their API modules

**Goal:** To wrap external dependencies so they can be easily swapped or mocked in tests.

---

## Dependency Flow

**Dependencies must only flow downwards.**

```
┌─────────────────────────────────────────────────────────┐
│                  Root Files (Public API)                │
│    (index.ts, Agentflow.tsx, AgentflowProvider.tsx)     │
│                   "The Public Face"                     │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│                      features/                          │
│   (canvas, node-palette, generator, node-editor)        │
│                   "What it does"                        │
└─────────────────────────────────────────────────────────┘
          │                                    │
          ▼                                    ▼
┌──────────────────┐              ┌────────────────────────┐
│      atoms/      │              │    infrastructure/     │
│  (UI primitives) │              │    (api, store)        │
│ "What it looks   │              │ "The Outside World"    │
│     like"        │              │                        │
└──────────────────┘              └────────────────────────┘
          │                                    │
          └──────────────┬─────────────────────┘
                         ▼
              ┌─────────────────────┐
              │        core/        │
              │  (types, constants, │
              │   validation, etc.) │
              │     "The Brain"     │
              └─────────────────────┘
```

**Import Rules:**

-   `features` → `atoms`, `infrastructure`, `core` ✅
-   `infrastructure` → `core` ✅
-   `atoms` → `core/types`, `core/theme`, and `core/primitives` only ✅
-   `core` → nothing (leaf node) ✅
-   **Atoms and Core are "leaf" nodes** - they cannot import from `features/` or `infrastructure/`

---

## Gatekeeper Pattern

Each module exposes only what's needed via its `index.ts`:

```typescript
// features/canvas/index.ts
// ✅ Public API
export const nodeTypes = { ... }
export const edgeTypes = { ... }
export { ConnectionLine, AgentflowHeader, createHeaderProps }
export { useFlowNodes, useFlowHandlers, useDragAndDrop }

// Container components are re-exported for advanced usage
export { AgentFlowNode, AgentFlowEdge, StickyNote, IterationNode }

// ❌ Internal sub-components stay private within containers/components
```

This enables:

-   **Encapsulation**: Internal refactoring doesn't break consumers
-   **Tree-shaking**: Bundlers can eliminate unused code
-   **Clarity**: Clear contract of what each module provides

---

## Adding a New Feature

1. Create folder under `features/`:

    ```
    features/my-feature/
    ├── containers/         # Smart components (optional)
    │   └── MyContainer.tsx
    ├── components/         # Presentational components (optional)
    │   └── MyComponent.tsx
    ├── hooks/              # Feature-specific hooks (optional)
    │   └── useMyHook.ts
    ├── helper.ts           # Feature-specific util
    └── index.ts            # Public exports only
    ```

2. Export only what's needed:

    ```typescript
    // index.ts
    export { MyContainer } from './containers'
    export { MyComponent } from './components'
    export { useMyHook } from './hooks'
    export type { MyComponentProps } from './components'
    ```

3. Import from infrastructure/core, never from other features:

    ```typescript
    // ✅ Good
    import { useApiContext } from '../../infrastructure/store'
    import type { NodeData } from '../../core/types'

    // ❌ Bad - cross-feature import
    import { AgentFlowNode } from '../canvas/containers/AgentFlowNode'
    ```

---

## Root Files (`src/*.ts`)

**"The Public Face."** The entry point of the package.

-   **`AgentflowProvider.tsx`**: Injects infrastructure (stores/api) into the app
-   **`Agentflow.tsx`**: The primary component users will drop into their apps
-   **`useAgentflow.ts`**: Primary public hook for accessing flow state and actions
-   **`index.ts`**: The "Barrel" that exports the public API for npm

---

## Public API

The package exposes a minimal public API via `src/index.ts`:

```typescript
// Components
export { Agentflow } from './Agentflow'
export { AgentflowProvider } from './AgentflowProvider'

// Hooks
export { useAgentflow } from './useAgentflow'
export { useApiContext, useConfigContext, useAgentflowContext } from './infrastructure/store'

// Types
export type { AgentflowProps, FlowData, NodeData, ... } from './core/types'

// Utilities (for advanced usage)
export { AGENTFLOW_ICONS, validateFlow, ... } from './core/...'
```

Everything else is internal implementation detail.

---

## Development Principles

### Barrel Exports

Every directory must have an `index.ts` that acts as a gatekeeper.

**✅ Good:**

```typescript
import { Button } from '@atoms'
import { useFlowHandlers } from '@features/canvas'
```

**❌ Bad:**

```typescript
// Never deep-link into files
import { Button } from '@atoms/Button/Button'
import { useFlowHandlers } from '@features/canvas/hooks/useFlowHandlers'
```

### Prop Drilling vs. Context

-   **Atoms**: Use props for all configuration
-   **Features**: Use context/state for shared data

### Naming Convention

| Type        | Convention                | Example                               |
| ----------- | ------------------------- | ------------------------------------- |
| Component   | PascalCase.tsx            | `AgentFlowNode.tsx`                   |
| Hook        | camelCase.ts (use prefix) | `useFlowHandlers.ts`                  |
| Logic/Types | camelCase.ts              | `flowValidation.ts`, `nodeFilters.ts` |
| Styles      | kebab-case (co-located)   | `canvas.css`                          |

---

Source: [Claudary](https://claudary.paisolsolutions.com/skills/architecture-6) · https://claudary.paisolsolutions.com
