Why a content layer
What is a content layer?
A content layer is the piece of your stack between your content and your application code. It loads files (usually Markdown), parses them, and exposes them through a typed API — so your app asks for get('/blog/hello') or list() instead of reading files and parsing frontmatter by hand.
It is not a Content backend: there is no hosted database, no admin panel, no API service. The content stays where it is; the layer indexes and serves it.
import { comarkContent } from 'comark-content'
import fs from 'comark-content/sources/fs'
const content = comarkContent({
source: fs('./content'),
})
const page = await content.get('/blog/hello')
page.data.title // typed frontmatter
page.nodes // parsed body, ready to renderThe problem it solves
Every content-driven site rebuilds the same plumbing:
- Reading: walk a directory, filter by extension, map file paths to routes.
- Parsing: split frontmatter from body, parse Markdown, highlight code.
- Typing: cast
dataasanyand hope the frontmatter matches. - Listing: sort posts by date, filter drafts, build navigation trees.
- Search: bolt on a client-side index or a search service.
A content layer replaces that with one dependency. Comark Content covers each point: sources for reading, Comark for parsing, generated types for frontmatter, list() and navigation() for listings, and opt-in SQL queries and full-text search.
When you need one
Use a content layer when:
- Content is Markdown (or JSON/YAML) written by developers or technical writers.
- You want content changes live without hand-rolled parsing code in every route.
- You need listings, navigation, queries, or search over a collection of files.
- The same content should render in more than one place: a site, an RSS feed, an API, an LLM context.
You don't need one when:
- Your site has a handful of static pages — hardcode them.
- Non-technical editors need a browser editing UI and publishing workflows — use a headless CMS.
Build time vs runtime
Most content layers (Contentlayer, Astro Content Collections, Velite) run at build time: they compile your files into typed data during build, so every content change requires a rebuild and redeploy.
Comark Content runs at runtime. Content is read from the source when your app asks, so a Markdown push is live on the next request — from a GitHub repo your app never rebuilds for. If you want build-time semantics, parse once and ship a snapshot; the API stays the same.
| Build-time layer | Comark Content | |
|---|---|---|
| Content change | Rebuild + redeploy | Live on next request |
| Content location | Local files in the app repo | Filesystem, GitHub, S3, KV, custom |
| Framework coupling | Bundler or framework plugin | Plain TypeScript, runs anywhere |
| Cost of a page read | Free (precompiled) | First read parses, then cached |
Content layer vs headless CMS
Both give your app an API over content. The difference is ownership: a headless CMS moves content into a vendor's database behind a metered API; a content layer reads content you already own. Full comparison: Comark Content vs headless CMS.
Next steps
- Install Comark Content — a source and a
get()in a few lines. - How it works — the pipeline from source to API.
- Compare — against Contentlayer, Astro Content Collections, and headless CMS.