# Dify Chat Project Architecture: A Comprehensive Guide to the TypeScript Monorepo Structure

> Explore the Dify Chat project architecture a TypeScript monorepo. Understand its pnpm workspace structure separating utilities logic hooks and frontend apps for a clean user interface and admin console.

- Repository: [lexmin0412/dify-chat](https://github.com/lexmin0412/dify-chat)
- Tags: architecture
- Published: 2026-03-06

---

**Dify Chat is a TypeScript monorepo organized as a pnpm workspace that separates low-level utilities, business logic, React hooks, and multiple frontend applications into distinct packages, enabling a clean separation between the end-user chat interface and the admin console with API proxy capabilities.**

The Dify Chat project, hosted at `lexmin0412/dify-chat`, implements a sophisticated layered architecture designed to support both direct chat interactions and administrative management of Dify AI applications. Understanding the Dify Chat project architecture reveals how the codebase maintains type safety, code reuse, and clear separation of concerns across multiple frontend applications.

## Monorepo Package Structure

The repository follows a strict package-based organization under the `packages/` directory. Each package owns a specific architectural layer, from low-level network utilities to complete Next.js applications.

```

packages/
├── core/            # Shared business logic, React hooks & repository layer

├── helpers/         # Low-level utilities (HTTP client)

├── api/             # Node.js client SDK for the Dify API

├── theme/           # UI-theming primitives (colors, spacing)

├── components/      # Reusable UI components (deprecated, backward-compatibility)

├── react-app/       # User-facing chat UI (React 19 + Tailwind v3)

├── platform/        # Admin console & API proxy (Next.js 15 + Tailwind v4 + Prisma)

└── docs/            # Documentation site (Rspress)

```

## Workspace and Dependency Management

The root [`pnpm-workspace.yaml`](https://github.com/lexmin0412/dify-chat/blob/main/pnpm-workspace.yaml) defines the monorepo boundaries and centralizes version management through a **catalog** section. This ensures consistent dependency versions—such as React 19 and TypeScript 5—across all packages.

Packages reference each other via workspace imports (`@dify-chat/core`, `@dify-chat/helpers`), enabling the entire codebase to compile and type-check together as a unified system.

## Core Architectural Layers

### Low-Level Utilities

The `helpers` package provides the foundational HTTP infrastructure. The `BaseRequest` class in [`packages/helpers/src/base-request.ts`](https://github.com/lexmin0412/dify-chat/blob/main/packages/helpers/src/base-request.ts) wraps the native `fetch` API, handling base URL configuration, default headers, JSON conversion, and cleanup of undefined parameters.

```typescript
// packages/helpers/src/base-request.ts
export class BaseRequest {
  constructor(options: { baseURL: string; headers?: Record<string, string> })
  // …
  jsonRequest = async (url: string, options: RequestInit) => { … }
}

```

All higher-level modules build their HTTP clients on top of this class.

### Business Logic and State Management

The `core` package exposes type-safe repository abstractions (`DifyAppStore`, `DifyAppStoreReadonly`) that define CRUD operations for Dify applications. It also supplies React hooks—`use-dify-chat` and `use-apps`—that consume these repositories and expose the current user, selected application, and service objects to the UI.

The `useDifyChat` hook operates in **single-app** or **multi-app** mode, automatically merging default values with context values.

```typescript
// packages/core/src/hooks/use-dify-chat.ts
export const useDifyChat = (): IDifyChatContext => { … }

```

### API Client Layer

The `api` package provides a thin, typed wrapper around the Dify HTTP API, exposing request and response models such as `Message` and `ChatResponse`. Internally, it leverages `BaseRequest` from `helpers` and the request generator from `core` (`genDifyRequestByRequestConfig`).

## Frontend Applications

### End-User Chat Interface

The `react-app` package delivers a single-page React application that renders chat conversations, workflow visualizations, and form-based answer collection. It imports the `core` hooks (`useDifyChat`) and the `api` client via [`dify-api.ts`](https://github.com/lexmin0412/dify-chat/blob/main/dify-api.ts). The UI relies on **Tailwind v3** and Ant Design components.

```typescript
// packages/react-app/src/utils/dify-api.ts
export const fetchChat = async (appId: string, payload: any) => { … }

```

### Admin Console and API Proxy

The `platform` package implements the administrative backend using **Next.js 15 (App Router)**, **Ant Design**, **Tailwind v4**, and **Prisma**. It provides a protected backend that stores Dify app configurations in a `dify_apps` table and manages user accounts.

The **API proxy** forwards requests to the real Dify service, injecting the stored `apiKey` so the frontend never leaks credentials. Authentication is handled by **NextAuth.js** with session-based JWT compatibility.

Key directories include:
- `prisma/` – Schema and migrations
- `lib/` – Prisma client and auth helpers
- `repository/` – Data-access layer ([`app.ts`](https://github.com/lexmin0412/dify-chat/blob/main/app.ts), [`user.ts`](https://github.com/lexmin0412/dify-chat/blob/main/user.ts))
- `app/api/` – REST endpoints and proxy routes

```typescript
// packages/platform/app/api/client/dify/[appId]/chat-messages/route.ts
import { getAppItem } from '@/repository/app';
import { BaseRequest } from '@/helpers/base-request';

export async function POST(req, { params }) {
  const { appId } = params;
  const app = await getAppItem(appId);
  const client = new BaseRequest({ baseURL: app.apiBase, headers: { Authorization: `Bearer ${app.apiKey}` } });
  const { messages } = await client.post('/chat-messages', await req.json());
  return new Response(JSON.stringify(messages), { status: 200 });
}

```

## Shared Resources

### Theming System

The `theme` package exposes design tokens—colors, spacing, and font sizes—that both `react-app` and `platform` consume to maintain visual consistency.

**Source**: [`packages/theme/src/constants/index.ts`](https://github.com/lexmin0412/dify-chat/blob/main/packages/theme/src/constants/index.ts)

### Documentation

The `docs` package powers the documentation site using **Rspress**, automatically deployed from the `main` branch.

**Source**: [`packages/docs/rspress.config.ts`](https://github.com/lexmin0412/dify-chat/blob/main/packages/docs/rspress.config.ts)

## Summary

- **Dify Chat** is organized as a **pnpm workspace monorepo** with nine distinct packages, each owning a specific architectural layer.
- The **helpers** package provides the foundational HTTP client (`BaseRequest`), while the **core** package supplies business logic and React hooks (`useDifyChat`).
- Two frontend applications serve different audiences: **react-app** for end-users and **platform** for administrators.
- The **platform** package acts as a secure proxy, storing API keys in Prisma and forwarding authenticated requests to the Dify service.
- Shared **theme** tokens and comprehensive **documentation** ensure consistency and maintainability across the entire system.

## Frequently Asked Questions

### What is the purpose of the core package in Dify Chat?

The **core** package serves as the central business logic layer, exposing type-safe repository interfaces (`DifyAppStore`) and React hooks (`use-dify-chat`, `use-apps`). It abstracts data access patterns and provides shared state management capabilities that both the react-app and platform packages consume.

### How does the platform package protect API keys?

The **platform** package stores Dify API credentials in a PostgreSQL database via Prisma (in the `dify_apps` table). When the frontend requests data, the platform's Next.js API routes retrieve the stored `apiKey`, inject it into the request headers, and forward the call to the actual Dify service. This ensures the frontend never exposes sensitive credentials to the browser.

### What is the difference between the react-app and platform packages?

The **react-app** package is a single-page React application (React 19 + Tailwind v3) designed for end-users to interact with chat conversations and workflows. The **platform** package is a Next.js 15 application (Tailwind v4 + Prisma) that provides an administrative console for managing Dify app configurations and acts as a secure API proxy. They serve distinct user roles but share the core business logic through the **core** package.

### Why does Dify Chat use a monorepo structure?

The monorepo architecture enables **strict separation of concerns** while maintaining type safety and code reuse across the entire system. By organizing code into focused packages (helpers, core, api, react-app, platform), the project ensures that low-level utilities, business logic, and UI components can evolve independently while remaining synchronized through the pnpm workspace catalog. This structure also facilitates consistent versioning of shared dependencies like React 19 and TypeScript 5.