Contentlayer is abandoned. MDX is setup-heavy. Velite turns your Markdown, YAML, and JSON files into type-safe, validated collections — with zero runtime overhead.
What Is Velite?
Velite is a content build tool that transforms local files (Markdown, MDX, YAML, JSON) into type-safe data collections. Think of it as a "content compiler" for your static site.
Quick Start
npm install velite
// velite.config.ts
import { defineConfig, s } from 'velite';
export default defineConfig({
collections: {
posts: {
name: 'Post',
pattern: 'posts/**/*.md',
schema: s.object({
title: s.string().max(120),
slug: s.slug('posts'),
date: s.isodate(),
description: s.string().max(300),
tags: s.array(s.string()),
draft: s.boolean().default(false),
body: s.markdown(),
}),
},
},
});
Usage
// Access typed content in your app
import { posts } from '#content';
// posts is fully typed as Post[]
const publishedPosts = posts
.filter(post => !post.draft)
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
// TypeScript knows the exact shape
publishedPosts.forEach(post => {
console.log(post.title); // string
console.log(post.slug); // string
console.log(post.date); // string (ISO date)
console.log(post.tags); // string[]
console.log(post.body); // string (rendered HTML)
});
Schema Validation
Velite validates your content at build time:
const schema = s.object({
title: s.string().min(10).max(120),
date: s.isodate(),
cover: s.image(), // Validates image exists, returns dimensions
category: s.enum(['tech', 'life']), // Only allowed values
author: s.object({
name: s.string(),
avatar: s.image(),
}),
related: s.array(s.slug('posts')), // Validates references exist
});
If your frontmatter doesn't match the schema, the build fails with a clear error.
Supported Content Types
// Markdown → HTML
body: s.markdown(),
// MDX → Component code
body: s.mdx(),
// Rich text excerpt
excerpt: s.excerpt(),
// Computed fields
readingTime: s.string().transform((_, { meta }) =>
`${Math.ceil(meta.content.split(' ').length / 200)} min read`
),
// Image processing
cover: s.image(), // Returns { src, width, height, blurDataURL }
Framework Integration
Works with any framework:
-
Next.js — import from
#content -
Astro — import from
#content - Remix — import at build time
-
SvelteKit — import from
#content
Why Velite
| Feature | Velite | Contentlayer | Gray-matter |
|---|---|---|---|
| Status | Active | Abandoned | Active |
| Type safety | Full | Full | None |
| Validation | Built-in (Zod-like) | Contentlayer schema | None |
| MDX support | Yes | Yes | No |
| Image processing | Built-in | No | No |
| Framework | Any | Next.js focused | Any |
Get Started
- Documentation
- GitHub — 1K+ stars
- Examples
Processing content from the web? My Apify scrapers extract structured content from any site. Custom solutions: spinov001@gmail.com
Top comments (0)