# How NextChat Supports Multiple AI Models: Claude, Gemini, and GPT-4 Integration

> NextChat enables seamless integration of Claude, Gemini, and GPT-4 via its provider-agnostic architecture and dynamic adapter system. Discover how NextChat supports multiple AI models easily.

- Repository: [NextChat/NextChat](https://github.com/ChatGPTNextWeb/NextChat)
- Tags: deep-dive
- Published: 2026-02-28

---

**NextChat uses a provider-agnostic architecture where the `ClientApi` class dynamically instantiates provider-specific adapters—such as `ClaudeApi`, `GeminiProApi`, or `ChatGPTApi`—based on the `ModelProvider` enum, enabling seamless integration of diverse LLMs through a unified `LLMApi` interface.**

The ChatGPTNextWeb/NextChat repository demonstrates a robust pattern for supporting multiple AI providers within a single chat interface. By abstracting vendor-specific protocols behind a common interface, NextChat treats Claude, Gemini, and GPT-4 as first-class citizens while maintaining type safety and extensibility. This architecture allows users to switch between models without changing the underlying application logic.

## Provider-Agnostic Architecture

NextChat's multi-model capability relies on a strict separation between the UI layer and backend-specific implementations. The system uses TypeScript enums and abstract classes to standardize interactions across heterogeneous AI services.

### ModelProvider Enum and Type Safety

The foundation of multi-model support is the `ModelProvider` enum defined in [`app/constant.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/constant.ts). This enumeration serves as the single source of truth for every supported backend, mapping human-readable identifiers to internal constants used throughout the routing layer.

```typescript
// app/constant.ts
export enum ModelProvider {
  Stability = "Stability",
  GPT = "GPT",
  GeminiPro = "GeminiPro",
  Claude = "Claude",
  // ...
}

```

Each chat configuration stores a `providerName` property corresponding to these enum values, enabling the system to route requests correctly without hardcoding provider logic in React components.

### ClientApi as the Central Router

The `ClientApi` class in [`app/client/api.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/api.ts) functions as a factory that instantiates the appropriate provider implementation at runtime. Its constructor accepts a `ModelProvider` value and uses a switch statement to bind the correct adapter to the `this.llm` property.

```typescript
// app/client/api.ts
constructor(provider: ModelProvider = ModelProvider.GPT) {
  switch (provider) {
    case ModelProvider.GeminiPro: 
      this.llm = new GeminiProApi(); 
      break;
    case ModelProvider.Claude:   
      this.llm = new ClaudeApi();   
      break;
    // ...
    default:                     
      this.llm = new ChatGPTApi(); 
      break;
  }
}

```

This pattern ensures that the rest of the application interacts with a uniform `llm` object implementing the `LLMApi` interface, regardless of whether the underlying model is Claude, Gemini, or GPT-4.

## Provider-Specific Adapters

Each supported AI model implements the abstract `LLMApi` interface, which standardizes methods for `chat`, `speech`, `usage`, and `models` queries. These adapters handle protocol translation, authentication headers, streaming logic, and response parsing.

### Claude (Anthropic) Integration

The `ClaudeApi` class in [`app/client/platforms/anthropic.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/anthropic.ts) builds Anthropic-specific request payloads, mapping NextChat's internal message roles to Anthropic's format. It handles tool calling through the `stream` and `streamWithThink` methods, managing unique requirements such as system prompt placement and stop sequence handling specific to the Anthropic API.

### Gemini (Google) Integration

Located in [`app/client/platforms/google.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/google.ts), the `GeminiProApi` adapter converts NextChat message arrays into Gemini's `contents` schema. It injects Google-specific safety settings and implements streaming via Server-Sent Events (SSE), translating Gemini's chunked response format into the standard callback interface (`onUpdate`, `onFinish`, `onError`) consumed by the UI.

### GPT-4 (OpenAI) Integration

The `ChatGPTApi` class in [`app/client/platforms/openai.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/openai.ts) supports OpenAI and Azure OpenAI endpoints. This adapter handles GPT-4, GPT-4o, O1, and vision capabilities, formatting requests to accommodate DALL·E image generation and function calling while maintaining compatibility with standard chat completion streams.

## Runtime Provider Selection

Developers interact with multiple models through the `getClientApi` helper function, which abstracts the instantiation logic and returns a pre-configured `ClientApi` instance.

### Selecting a Provider at Runtime

```typescript
import { getClientApi } from "@/app/client/api";
import { ServiceProvider } from "@/app/constant";

// Initialize Google (Gemini) client
const geminiClient = getClientApi(ServiceProvider.Google);

// Initialize Anthropic (Claude) client  
const claudeClient = getClientApi(ServiceProvider.Anthropic);

// Initialize OpenAI (GPT-4) client
const gptClient = getClientApi(ServiceProvider.OpenAI);

```

The `getClientApi` function implements the same switching logic as the `ClientApi` constructor, ensuring consistent provider resolution across the application.

### Unified Chat Interface

Regardless of the underlying provider, chat requests follow an identical structure defined by the `ChatOptions` interface:

```typescript
const chatOpts = {
  messages: [
    { role: "user", content: "Explain quantum entanglement in plain language." },
  ],
  config: {
    model: "claude-3.5-sonnet",  // or "gemini-1.5-pro", "gpt-4o"
    providerName: "Anthropic",   // determines routing
    stream: true,
    temperature: 0.7,
    max_tokens: 2048,
  },
  onUpdate: (msg, chunk) => console.log("Δ", chunk),
  onFinish: (msg, _) => console.log("✅", msg),
  onError: err => console.error(err),
};

await claudeClient.llm.chat(chatOpts);

```

The same code pattern works for any supported model; only the `model` string and `providerName` values change, allowing dynamic model switching without refactoring business logic.

## Extending Support for New Providers

Adding a new AI provider requires implementing three specific integration points without modifying the UI layer.

1. **Extend the enum** in [`app/constant.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/constant.ts):
   ```typescript
   export enum ModelProvider { 
     // ... existing providers
     MyNewAI = "MyNewAI" 
   }
   ```

2. **Create the adapter** in [`app/client/platforms/mynewai.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/mynewai.ts):
   ```typescript
   export class MyNewAIApi implements LLMApi {
     async chat(options: ChatOptions) {
       // Provider-specific implementation
     }
     async speech() { /* ... */ }
     async usage() { /* ... */ }
     async models() { /* ... */ }
   }
   ```

3. **Register the switch case** in [`app/client/api.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/api.ts):
   ```typescript
   case ModelProvider.MyNewAI:
     this.llm = new MyNewAIApi();
     break;
   ```

The settings UI automatically populates the new provider in dropdown menus because it reads directly from the `ModelProvider` enum.

## Summary

- **Provider abstraction**: NextChat uses the `ModelProvider` enum and `ClientApi` class to route requests to the correct backend implementation based on the `providerName` configuration.
- **Unified interface**: All providers implement the `LLMApi` interface, exposing standardized methods for `chat`, `speech`, and `usage` queries across Claude, Gemini, and GPT-4.
- **Adapter pattern**: Platform-specific logic lives in dedicated files like [`app/client/platforms/anthropic.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/anthropic.ts), handling protocol translation, authentication, and streaming quirks.
- **Dynamic routing**: The `getClientApi` function instantiates providers at runtime, allowing the same chat logic to power conversations with any supported model.
- **Extensible design**: New models require only enum extension and adapter implementation, with zero changes to React components or chat state management.

## Frequently Asked Questions

### How does NextChat determine which AI provider to use for a chat request?

NextChat extracts the `providerName` property from the chat configuration object, which corresponds to a value in the `ModelProvider` enum defined in [`app/constant.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/constant.ts). The `ClientApi` constructor or `getClientApi` factory function uses this value in a switch statement to instantiate the appropriate adapter class, such as `ClaudeApi` for Anthropic or `GeminiProApi` for Google.

### Can I switch between GPT-4 and Claude in the same conversation thread?

While NextChat supports configuring different models per chat session, switching providers mid-conversation requires re-instantiating the client with a new configuration. The `ClientApi` initializes the provider adapter once per instance, so dynamic switching within a single request stream necessitates creating a new chat session or changing the model settings before the next message.

### What interface must new provider adapters implement?

All provider adapters must implement the `LLMApi` interface exported from the client API layer. This interface requires four main methods: `chat()` for text generation with streaming support, `speech()` for text-to-speech conversion, `usage()` for quota checking, and `models()` for fetching available model lists. The `chat()` method must specifically handle the `onUpdate`, `onFinish`, and `onError` callbacks to integrate with NextChat's streaming UI.

### Where does NextChat handle provider-specific authentication?

Each platform adapter manages its own authentication logic within its implementation file in `app/client/platforms/`. For example, [`app/client/platforms/anthropic.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/anthropic.ts) injects `x-api-key` headers for Claude, while [`app/client/platforms/google.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/platforms/google.ts) handles Google API key parameters and safety settings. This encapsulation ensures that credential formatting and provider-specific headers remain isolated from the core chat logic in [`app/client/api.ts`](https://github.com/ChatGPTNextWeb/NextChat/blob/main/app/client/api.ts).