Getting Started
piq is a query layer for document collections. It's designed for content-heavy applications where you're reading structured sources (markdown, JSON, S3 etc.) and want explicit control over resolution cost.
Installation
npm install piqit @piqit/resolvers piqit is the core query builder. @piqit/resolvers provides
resolvers for common content sources like markdown files.
Quick Start
Define a resolver for your content:
import { piq } from 'piqit' import { fileMarkdown } from '@piqit/resolvers' import { z } from 'zod' const posts = fileMarkdown({ base: 'content/posts', path: '{year}/{slug}.md', frontmatter: z.object({ title: z.string(), status: z.enum(['draft', 'published']), tags: z.array(z.string()), }), body: { html: true, headings: true } })
Query your content:
const results = await piq.from(posts) .scan({ year: '2024' }) .filter({ status: 'published' }) .select('params.slug', 'frontmatter.title', 'body.html') .exec() // Results are flat: // [{ slug: 'hello-world', title: 'Hello World', html: '<p>...' }]
The Query Pipeline
Every piq query follows the same pattern: scan → filter → select → exec. Each step has a cost, and the API makes that cost visible.
- scan() — Enumerate items by path pattern. Cheapest operation.
- filter() — Narrow by document content. Requires reading frontmatter.
- select() — Declare which fields to return. Controls what gets parsed.
- exec() — Execute and return results as an array.
Read Concepts to understand the cost model, or jump to the API Reference for full details.