comark-content
v0.3.0
Published
Content layer for Comark
Readme
comark-content
Universal content layer for Markdown-driven websites. Comark Content turns Markdown from the filesystem, GitHub, or any storage driver into a queryable, searchable, type-safe API. Framework-agnostic, it runs on a server, at the edge, or fully in the browser. Built on Comark.
Why Comark Content
- Runtime, not build-time: content is read from the source when your app asks. Push Markdown, it's live on the next request — no rebuild, no redeploy.
- Lightweight core: four methods —
get,list,navigation,watch. Everything else is an opt-in plugin. - Pluggable sources: filesystem, GitHub, or any unstorage driver (S3, KV, Redis, HTTP).
- Type-safe: generated types narrow
get(),list(), andquery()by source and by path. - SQL queries & full-text search: opt into a SQLite-backed query builder and BM25 search over frontmatter and content.
- Runs anywhere: Node, edge, or fully in the browser with a hydrated snapshot.
- Framework-agnostic: returns a plain Comark AST, rendered by Vue, React, Svelte, Angular, or plain HTML.
Quick start
pnpm add comark-contentimport { comarkContent } from 'comark-content'
import fs from 'comark-content/sources/fs'
export const content = comarkContent({
source: fs('./content'),
})
const page = await content.get('/getting-started/introduction')
const nav = await content.navigation()Swap the source for GitHub, or any unstorage driver — same API:
import github from 'comark-content/sources/github'
const content = comarkContent({
source: github({ repo: 'nuxt/nuxt', branch: 'main', path: 'docs' }),
})Type-safe by generation
Run the CLI (or the Vite plugin) to generate types from your actual content. It infers a schema per source and augments comark-content, so reads narrow to the real shape of your files:
npx comark-content prepare # writes comark-content.d.ts// `/about` is a known path — it autocompletes, and `data` is typed from its frontmatter
const about = await content.get('/about')
about?.data.title // string
// passing source names narrows each item's `data`
const posts = await content.list(['blog']) // data: BlogData
No casts, no manual interfaces — edit a file, re-run `prepare`, and the types follow.
## CLI
The package ships a small `comark-content` binary. Today it has a single focused command, `prepare`, which locates your `comarkContent()` instance and generates source types — the same generation the Vite plugin runs automatically. Reach for it when you're not using Vite, or want to (re)generate types in a script or CI step.
```sh
npx comark-content prepare # find content.{ts,mts,js,mjs}, write ./comark-content.d.ts
npx comark-content prepare --config server/content.ts -o types/comark-content.d.ts
npx comark-content --helpSee the CLI reference for all flags.
Documentation
Full guides, concepts, and API reference at content.comark.dev.
License
Made with ❤️
Published under MIT License.
