MDX.org.ai
Structured Data

mdxdb

Create, Manage, & Publish MDX & URL-centric File System & Database

mdxdb

mdxdb provides a unified interface for storing and querying MDXLD documents across multiple storage backends.

Installation

npm install mdxdb

Features

  • Unified API - Same interface across all storage backends
  • URL-centric - Documents are addressed by URLs/paths
  • Full-text Search - Search across document content
  • Type-safe - Full TypeScript support
  • Pluggable - Easy to add custom adapters

Storage Adapters

PackageBackendUse Case
@mdxdb/fsFile SystemLocal development, static sites
@mdxdb/sqliteSQLiteEmbedded database, edge computing
@mdxdb/clickhouseClickHouseAnalytics, time-series
@mdxdb/apiHTTP APIRemote mdxdb server

Quick Start

File System Adapter

import { createDatabase } from '@mdxdb/fs'
 
const db = createDatabase({
  path: './content',
})
 
// Store a document
await db.set('posts/hello-world', {
  data: {
    $type: 'BlogPost',
    title: 'Hello World',
    author: 'Jane Doe',
  },
  content: '# Hello World\n\nWelcome to my blog!',
})
 
// Retrieve a document
const doc = await db.get('posts/hello-world')
console.log(doc.data.title) // 'Hello World'
 
// List all documents
const posts = await db.list('posts/')
console.log(posts.length) // 1

SQLite Adapter

import { createDatabase } from '@mdxdb/sqlite'
 
const db = createDatabase({
  filename: './content.db',
})
 
// Same API as file system
await db.set('docs/getting-started', doc)
const result = await db.get('docs/getting-started')

Core API

Database Interface

interface Database {
  /** Get a document by path */
  get(path: string, options?: GetOptions): Promise<MDXLDDocument | null>
 
  /** Store a document */
  set(path: string, doc: MDXLDDocument, options?: SetOptions): Promise<SetResult>
 
  /** Delete a document */
  delete(path: string, options?: DeleteOptions): Promise<DeleteResult>
 
  /** List documents */
  list(prefix?: string, options?: ListOptions): Promise<ListResult>
 
  /** Search documents */
  search(query: string, options?: SearchOptions): Promise<SearchResult>
}

Get Options

interface GetOptions {
  /** Include content in response */
  includeContent?: boolean
}

Set Options

interface SetOptions {
  /** Overwrite existing document */
  overwrite?: boolean
  /** Create parent directories/collections */
  createParents?: boolean
}

List Options

interface ListOptions {
  /** Maximum results to return */
  limit?: number
  /** Pagination offset */
  offset?: number
  /** Sort order */
  orderBy?: 'path' | 'createdAt' | 'updatedAt'
  /** Sort direction */
  order?: 'asc' | 'desc'
  /** Filter by type */
  type?: string
}

Search Options

interface SearchOptions {
  /** Fields to search */
  fields?: ('title' | 'content' | 'data')[]
  /** Maximum results */
  limit?: number
  /** Filter by type */
  type?: string
}

Working with Documents

Creating Documents

import { parse } from 'mdxld'
 
// From MDX string
const doc = parse(`---
$type: Article
title: My Article
---
 
# My Article
 
Content here...
`)
 
await db.set('articles/my-article', doc)
 
// From object
await db.set('articles/another', {
  data: {
    $type: 'Article',
    title: 'Another Article',
  },
  content: '# Another Article\n\nMore content...',
})

Querying Documents

// List all articles
const articles = await db.list('articles/', {
  type: 'Article',
  orderBy: 'createdAt',
  order: 'desc',
  limit: 10,
})
 
// Search content
const results = await db.search('typescript tutorial', {
  fields: ['title', 'content'],
  limit: 20,
})

Updating Documents

const doc = await db.get('articles/my-article')
 
// Modify the document
doc.data.title = 'Updated Title'
doc.data.updatedAt = new Date().toISOString()
 
// Save changes
await db.set('articles/my-article', doc, { overwrite: true })

Deleting Documents

await db.delete('articles/old-article')
 
// Delete with confirmation
const result = await db.delete('articles/important')
if (result.success) {
  console.log('Document deleted')
}

API Client

Connect to a remote mdxdb server:

import { createApiClient } from 'mdxdb/client'
 
const client = createApiClient({
  baseUrl: 'https://api.example.com/mdxdb',
  apiKey: process.env.MDXDB_API_KEY,
})
 
// Same interface as local database
const doc = await client.get('posts/hello-world')

Fumadocs Integration

Use mdxdb as a content source for Fumadocs:

import { createSource } from '@mdxdb/fumadocs'
import { loader } from 'fumadocs-core/source'
 
const db = createDatabase({ path: './content' })
const docs = await db.list('docs/')
 
const source = createSource(
  docs.map(doc => [doc.path, doc]),
  { basePath: 'docs' }
)
 
export const docsSource = loader({
  source,
  baseUrl: '/docs',
})

See @mdxdb/fumadocs for more details.

Next Steps