# Core vs Hybrid vs Legacy Search in Wigolo: Backend Architecture Explained

> Understand Wigolo's core hybrid and legacy search backends. Explore the differences in ranking sophistication content processing and failover for your technical needs.

- Repository: [Towhid Khan/wigolo](https://github.com/KnockOutEZ/wigolo)
- Tags: architecture
- Published: 2026-07-19

---

**Wigolo provides three distinct search backends—Core (native full-stack orchestration), Legacy (SearxNG pass-through), and Hybrid (Core with SearxNG fallback)—each offering different levels of ranking sophistication, content processing, and failover capabilities.**

The open-source Wigolo project (KnockOutEZ/wigolo) implements a flexible search architecture that allows developers to choose between three distinct backends depending on their needs for ranking complexity, external service dependencies, and fallback reliability. Understanding the difference between wigolo's core search backend and its hybrid/legacy search modes is essential for optimizing query performance and result quality.

## Architectural Differences Between Search Modes

Wigolo's search implementation separates concerns across three provider classes, each defined in specific source files under the `src/search/` directory. The system resolves which provider to use based on the `WIGOLO_SEARCH` environment variable or persisted configuration, with the selection logic centralized in [`src/providers/search-provider.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/providers/search-provider.ts).

### Core Search Backend

The **Core** mode represents Wigolo's native, full-stack search implementation. Located in [`src/search/core/core-provider.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/core/core-provider.ts), the `CoreSearchProvider` class executes the `runV1Search` orchestrator, which performs:

- **Intent routing** and per-vertical engine selection
- **RRF (Reciprocal Rank Fusion)** for merging results
- **Query expansion** and brand-collision rewrites
- **Reranking**, score-flooring, and recency-boosting
- **Content fetching** and evidence synthesis

This mode activates by default when `WIGOLO_SEARCH` is unset, set to `core`, or when the persisted `searchBackend` configuration is empty. It provides the richest feature set but requires no external SearxNG dependencies.

### Legacy SearxNG Mode

The **Legacy** mode acts as a thin wrapper around an external SearxNG instance. Implemented in [`src/search/legacy/searxng-provider.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/legacy/searxng-provider.ts), the `LegacySearxngProvider` forwards requests to the SearxNG side-car via `runSearxngSearch` (defined in [`src/search/legacy/searxng-orchestrator.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/legacy/searxng-orchestrator.ts)).

In this mode, Wigolo bypasses its internal ranking pipeline entirely. The system does not perform query expansion, reranking, content fetching, or evidence synthesis—instead returning raw results from the external SearxNG service. Select this mode by setting `WIGOLO_SEARCH=searxng`.

### Hybrid Search Mode

The **Hybrid** mode combines Core's sophistication with Legacy's breadth. Implemented in [`src/search/hybrid/router.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/hybrid/router.ts), the `HybridSearchProvider` executes the Core provider first, then evaluates **fallback signals** (defined in [`src/search/hybrid/signals.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/hybrid/signals.ts)) such as low recall or temporal intent.

If these signals trigger, the system optionally invokes the `LegacySearxngProvider` as a fallback and merges both result sets using the `mergeResults` function. If the SearxNG side-car is unavailable, the fallback is skipped and a warning is appended to the response. Enable this mode with `WIGOLO_SEARCH=hybrid`.

## Provider Selection Logic

The entry point [`src/tools/search.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/tools/search.ts) delegates all search requests to a resolved provider instance. The resolution occurs in [`src/providers/search-provider.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/providers/search-provider.ts), which reads the environment configuration and lazily imports the appropriate module (`CoreSearchProvider`, `LegacySearxngProvider`, or `HybridSearchProvider`).

```typescript
// Conceptual flow based on src/providers/search-provider.ts
const provider = getSearchProvider(); // Reads WIGOLO_SEARCH env var
const result = await provider.search(input, engines, router);

```

The `handleSearch` function in [`src/tools/search.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/tools/search.ts) remains agnostic to the backend implementation, ensuring consistent tooling interfaces regardless of which mode is active.

## Practical Implementation Examples

### Using the Default Core Backend

When `WIGOLO_SEARCH` is undefined, Wigolo automatically selects the Core provider:

```typescript
import { handleSearch } from './src/tools/search.js';
import { getConfig } from './src/config.js';

const input = {
  query: 'how to set up a Next.js project',
  category: 'code',
  max_results: 10,
};

const result = await handleSearch(
  input,
  getConfig().searchEngines,
  smartRouter,
);

```

This executes the full core pipeline including intent routing and RRF fusion.

### Configuring Legacy SearxNG Mode

Set the environment variable before starting the service:

```bash
export WIGOLO_SEARCH=searxng
export WIGOLO_SEARXNG_URL=https://searxng.example.com
wigolo serve

```

All subsequent `handleSearch` calls route to `LegacySearxngProvider`, which forwards queries to the configured SearxNG instance without applying Wigolo's ranking algorithms.

### Enabling Hybrid Fallback Protection

```bash
export WIGOLO_SEARCH=hybrid
wigolo serve

```

In this configuration, Core search runs first. If signals indicate insufficient results, the system attempts a SearxNG fallback and merges the result sets. If the side-car is unreachable, the response includes a warning but still returns Core results.

### Debugging Backend Selection

Inspect which provider processed the query:

```typescript
const response = await handleSearch(...);
console.log('Provider used:', response.data.fallback_signal ?? 'core');

```

The `fallback_signal` field appears only in hybrid mode when SearxNG fallback occurs; otherwise, the response shape indicates the primary provider.

## Summary

- **Core** provides the native Wigolo orchestration with full ranking, query expansion, content extraction, and evidence synthesis via `CoreSearchProvider`.
- **Legacy** acts as a pass-through to an external SearxNG instance via `LegacySearxngProvider`, bypassing Wigolo's advanced processing steps.
- **Hybrid** prioritizes Core results while using `HybridSearchProvider` to optionally fetch and merge SearxNG results when fallback signals (low recall, temporal intent) indicate insufficient coverage.
- **Selection** occurs in [`src/providers/search-provider.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/providers/search-provider.ts) based on the `WIGOLO_SEARCH` environment variable, with [`src/tools/search.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/tools/search.ts) serving as the thin entry point for all modes.

## Frequently Asked Questions

### Which backend provides the best result quality?

The **Core** backend generally provides superior result quality because it executes the full `runV1Search` orchestration with RRF fusion, reranking, query expansion, and content fetching. The **Legacy** mode relies entirely on external SearxNG ranking without Wigolo's post-processing, while **Hybrid** maintains Core quality unless fallback signals trigger SearxNG augmentation.

### When should I use hybrid mode instead of core?

Use **Hybrid** mode when your queries frequently involve temporal content (recent news, current events) or when you suspect the Core backend may return low-recall results for specific verticals. The hybrid router in [`src/search/hybrid/router.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/hybrid/router.ts) detects these conditions via signals in [`src/search/hybrid/signals.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/hybrid/signals.ts) and automatically supplements Core results with SearxNG data when beneficial.

### What happens if the SearxNG side-car is unavailable in hybrid mode?

If the SearxNG side-car cannot be reached during a hybrid search, the system skips the fallback invocation and adds a warning message to the response, returning only the Core results. This ensures graceful degradation rather than search failure, as implemented in the error handling logic of [`src/search/hybrid/router.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/search/hybrid/router.ts).

### How do I configure which backend Wigolo uses?

Set the `WIGOLO_SEARCH` environment variable to `core`, `searxng`, or `hybrid` before starting the service. The provider resolution logic in [`src/providers/search-provider.ts`](https://github.com/KnockOutEZ/wigolo/blob/main/src/providers/search-provider.ts) reads this value to determine whether to instantiate `CoreSearchProvider`, `LegacySearxngProvider`, or `HybridSearchProvider`. If the variable is unset, the system defaults to Core mode.