The registry version installs project-shaped source files directly into your application:
buddy add tableThis adds resources/components/DataTable.stx and the table functions under resources/functions/table/. The installed STX and TypeScript source remains fully owned and editable by the application.
Typed searching, filtering, sorting, faceting, ranking, and pagination for data tables. The core has no runtime dependencies and works with an in-memory dataset, Meilisearch, Algolia, or Typesense.
bun add @stacksjs/tableThe memory driver provides realistic table behavior without a search service, credentials, Docker, or network access.
import { createTable, MemoryTableDriver } from '@stacksjs/table'
const driver = new MemoryTableDriver({
products: [
{ id: 1, name: 'Mechanical Keyboard', category: 'hardware', price: 149 },
{ id: 2, name: 'TypeScript Handbook', category: 'books', price: 39 },
{ id: 3, name: 'Wireless Keyboard', category: 'hardware', price: 89 },
],
})
const products = createTable({
driver,
index: 'products',
searchFields: ['name'],
ranking: { rules: ['price:asc'] },
})
const result = await products.search({
query: 'keyboard',
filters: { category: 'hardware' },
facets: ['category'],
})Run the included dummy database example with bun run demo:memory.
import { createTable, MeilisearchTableDriver } from '@stacksjs/table'
const products = createTable({
driver: new MeilisearchTableDriver({
host: 'https://search.example.com',
apiKey: process.env.MEILISEARCH_API_KEY,
}),
index: 'products',
ranking: { rules: ['words', 'typo', 'proximity', 'sort', 'exactness'] },
})import { AlgoliaTableDriver, createTable } from '@stacksjs/table'
const products = createTable({
driver: new AlgoliaTableDriver({
appId: process.env.ALGOLIA_APP_ID,
apiKey: process.env.ALGOLIA_API_KEY,
}),
index: 'products',
ranking: { rules: ['desc(popularity)', 'asc(price)'] },
})Algolia searches use its distributed search host. Ranking updates use the write host and finish before the first table search. Use a search-only key when no ranking is configured, and a key with settings permission when it is.
import { createTable, TypesenseTableDriver } from '@stacksjs/table'
const products = createTable({
driver: new TypesenseTableDriver({
host: 'https://typesense.example.com',
apiKey: process.env.TYPESENSE_API_KEY,
queryBy: ['name', 'description'],
}),
index: 'products',
})
const result = await products.search({
query: 'keyboard',
filters: { category: ['hardware', 'accessories'] },
sort: ['price:asc'],
})Typesense ranking is expressed per query through sort, which matches its API model. Remote index-ranking configuration is only exposed by drivers whose engines support that operation.
Custom drivers implement two methods:
interface TableDriver<Row> {
readonly name: string
search(request: TableSearchRequest): Promise<TableSearchResult<Row>>
setRanking?(index: string, ranking: TableRanking): Promise<void>
}Every driver returns the same result shape, so view code does not depend on a vendor SDK response.
bun install
bun test
bun run test:types
bun run lint
bun run buildMIT