# Stacks Search Engine

> Use when implementing search in Stacks - full-text search with Meilisearch or Algolia backends, document indexing, search settings management, the useSearch model trait for automatic indexing, or search driver configuration. Covers @stacksjs/search-engine and config/search-engine.ts.

- Skill: `stacksjs/stacks-search-engine` (Agent Skill)
- Install (CLI): `npx skillmds@latest add stacksjs/stacks-search-engine`
- Raw SKILL.md: https://api.skillmd.com/api/skills/stacksjs/stacks-search-engine/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: stacksjs (https://skillmd.com/u/stacksjs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/stacksjs/stacks-search-engine

---


# Stacks Search Engine

Full-text search integration with Meilisearch, Algolia, Typesense, and
OpenSearch drivers.

## Key Paths
- Core package: `storage/framework/core/search-engine/src/`
- Configuration: `config/search-engine.ts`

## Search Driver Factory

```typescript
import {
  flushModelDocuments,
  useAlgolia,
  useMeilisearch,
  useOpensearch,
  useSearchEngine,
  useTypesense,
} from '@stacksjs/search-engine'

const search = useSearchEngine()       // default driver
const algolia = useAlgolia()            // Algolia client
const meili = useMeilisearch()          // Meilisearch client
const openSearch = useOpensearch()       // OpenSearch driver
const typesense = useTypesense()         // Typesense driver
```

## Document Operations

```typescript
// Index documents
await search.addDocuments('products', [
  { id: 1, name: 'Widget', description: 'A useful widget', price: 29.99 },
  { id: 2, name: 'Gadget', description: 'A cool gadget', price: 49.99 }
])

// Search
const results = await search.search('products', 'widget')

// List indexes
const indexes = await search.listAllIndexes()

// Get/update settings
const settings = await search.getSettings('products')
await search.updateSettings('products', {
  searchableAttributes: ['name', 'description'],
  filterableAttributes: ['price', 'category'],
  sortableAttributes: ['price', 'created_at']
})

// Flush all documents
await flushModelDocuments('Product')
```

## Model Integration (useSearch Trait)

Models with `useSearch` trait are automatically indexed:

```typescript
defineModel({
  name: 'Product',
  traits: {
    useSearch: {
      displayable: ['name', 'description', 'price'],
      searchable: ['name', 'description'],
      sortable: ['name', 'price', 'created_at'],
      filterable: ['category', 'status', 'price']
    }
  }
})
```

## CLI Commands

```bash
buddy search-engine:update                    # index all searchable models
buddy search-engine:update --model Product    # index specific model
buddy search-engine:update --flush            # flush before re-indexing
buddy search-engine:update --settings         # update search settings only
buddy search-engine:settings                  # list current settings
buddy search-engine:settings --model Product  # settings for specific model
```

## Driver Comparison

| Feature | Meilisearch | Algolia | Typesense | OpenSearch |
|---------|-------------|---------|-----------|------------|
| Self-hosted | Yes | No | Yes | Yes |
| Managed option | Yes | Yes | Yes | Yes |
| Model lifecycle indexing | Yes | Yes | Yes | Driver must implement the full contract |

## config/search-engine.ts

```typescript
{ driver: 'opensearch' }  // 'meilisearch' | 'algolia' | 'opensearch' | 'typesense'
```

Environment variables: `MEILISEARCH_HOST`, `MEILISEARCH_KEY`, `SEARCH_ENGINE_DRIVER`

## Gotchas
- Default driver is `opensearch` — configure in config or env
- A selected driver must implement the complete `SearchEngineDriver` surface; never satisfy the type with an empty cast
- `useSearch` trait determines which model fields are indexed
- `displayable` controls which fields appear in search results
- `searchable` controls which fields are queried during search
- `filterable` enables faceted filtering on those fields
- `sortable` enables sorting by those fields
- Use `buddy search-engine:update --flush` for full re-index
- Meilisearch requires a running Meilisearch server
- Algolia requires API keys from your Algolia dashboard
- Settings updates don't re-index — run `search-engine:update` after changes

