A modern documentation framework that works. One config file, zero boilerplate.
Easily scaffold your docs with the CLI. It auto-detects your framework and scaffolds everything.
Setup beautiful documentation in seconds
Add the core packages to your Next.js project.
pnpm add @farming-labs/docs @farming-labs/theme @farming-labs/nextOne file. Theme, metadata, components, icons — everything.
import { defineDocs } from "@farming-labs/docs";
import { pixelBorder } from "@farming-labs/theme/pixel-border";
export default defineDocs({
entry: "docs",
theme: pixelBorder(),
metadata: {
titleTemplate: "%s – My Docs",
},
});Wrap your config with withDocs(). Handles MDX, routing, and search.
import { withDocs } from "@farming-labs/next/config";
export default withDocs({});Wrap your app with RootProvider for search, theme switching, and AI.
import { RootProvider } from "@farming-labs/theme";
import "./global.css";
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}In app/global.css, import your theme's CSS so docs styling applies (e.g. @import "@farming-labs/theme/default/css"; — use the path that matches your theme).
Create MDX files under app/docs/. Frontmatter for metadata. That's it.
---
title: "Getting Started"
description: "Set up in 5 minutes"
icon: "rocket"
---
# Getting Started
Write your content in **MDX** with
frontmatter for metadata.
```ts title="auth.ts"
export const auth = betterAuth({
database: { provider: "postgresql" },
});
```See the full installation walkthrough for all generated files and options.
Add the core packages to your SvelteKit project.
pnpm add @farming-labs/docs @farming-labs/svelte @farming-labs/svelte-themeOne config file. Theme, metadata, navigation — everything.
import { defineDocs } from "@farming-labs/docs";
import { fumadocs } from "@farming-labs/svelte-theme";
export default defineDocs({
entry: "docs",
contentDir: "docs",
theme: fumadocs(),
metadata: {
titleTemplate: "%s – My Docs",
},
});Create the server helper. Handles loading, search, and AI.
import { createDocsServer } from "@farming-labs/svelte/server";
import config from "./docs.config";
export const { load, GET, POST } = createDocsServer(config);Create Markdown files under docs/. That's it.
---
title: "Getting Started"
description: "Set up in 5 minutes"
icon: "rocket"
---
# Getting Started
Write your content in **Markdown** with
frontmatter for metadata.
```ts title="auth.ts"
export const auth = betterAuth({
database: { provider: "postgresql" },
});
```Three small files for layout, server loader, and page.
<script>
import { DocsLayout } from "@farming-labs/svelte-theme";
import config from "../../lib/docs.config";
let { data, children } = $props();
</script>
<DocsLayout tree={data.tree} {config}>
{@render children()}
</DocsLayout>Add the core packages to your Astro project.
pnpm add @farming-labs/docs @farming-labs/astro @farming-labs/astro-themeOne config file. Theme, metadata, navigation — everything.
import { defineDocs } from "@farming-labs/docs";
import { fumadocs } from "@farming-labs/astro-theme";
export default defineDocs({
entry: "docs",
contentDir: "docs",
theme: fumadocs(),
metadata: {
titleTemplate: "%s – My Docs",
},
});Create the server helper. Handles loading, search, and AI.
import { createDocsServer } from "@farming-labs/astro/server";
import config from "./docs.config";
export const { load, GET, POST } = createDocsServer(config);Create Markdown files under docs/. That's it.
---
title: "Getting Started"
description: "Set up in 5 minutes"
icon: "rocket"
---
# Getting Started
Write your content in **Markdown** with
frontmatter for metadata.
```ts title="auth.ts"
export const auth = betterAuth({
database: { provider: "postgresql" },
});
```Index page, catch-all route, and API endpoint.
---
import DocsLayout from "@farming-labs/astro-theme/src/components/DocsLayout.astro";
import DocsContent from "@farming-labs/astro-theme/src/components/DocsContent.astro";
import config from "../../lib/docs.config";
import { load } from "../../lib/docs.server";
import "@farming-labs/astro-theme/css";
const data = await load(Astro.url.pathname);
---
<html lang="en">
<head><title>{data.title} – Docs</title></head>
<body>
<DocsLayout tree={data.tree} config={config}>
<DocsContent data={data} config={config} />
</DocsLayout>
</body>
</html>Add the core packages to your Nuxt project.
pnpm add @farming-labs/docs @farming-labs/nuxt @farming-labs/nuxt-themeOne config file. Theme, metadata, navigation — everything.
import { defineDocs } from "@farming-labs/docs";
import { fumadocs } from "@farming-labs/nuxt-theme/fumadocs";
export default defineDocs({
entry: "docs",
contentDir: "docs",
theme: fumadocs(),
metadata: {
titleTemplate: "%s – My Docs",
},
});Import the theme CSS and configure Nitro server assets.
export default defineNuxtConfig({
css: ["@farming-labs/nuxt-theme/fumadocs/css"],
nitro: {
serverAssets: [
{ baseName: "docs", dir: "../docs" },
],
},
});One handler for docs loading, search, and AI.
import { defineDocsHandler } from "@farming-labs/nuxt/server";
import config from "../../docs.config";
export default defineDocsHandler(config, useStorage);Create Markdown files under docs/. That's it.
---
title: "Getting Started"
description: "Set up in 5 minutes"
icon: "rocket"
---
# Getting Started
Write your content in **Markdown** with
frontmatter for metadata.
```ts title="auth.ts"
export const auth = betterAuth({
database: { provider: "postgresql" },
});
```A single Vue page that handles all doc routes.
<script setup lang="ts">
import { DocsLayout, DocsContent } from "@farming-labs/nuxt-theme";
import config from "~/docs.config";
const route = useRoute();
const pathname = computed(() => route.path);
const { data } = await useFetch("/api/docs", {
query: { pathname },
watch: [pathname],
});
</script>
<template>
<DocsLayout :tree="data.tree" :config="config">
<DocsContent :data="data" :config="config" />
</DocsLayout>
</template>Pick a preset or build your own with createTheme(). Override any styles from config.
Clean, neutral palette with standard border radius
@import "@farming-labs/theme/default/css";All-black, sharp corners, no rounded edges
@import "@farming-labs/theme/darksharp/css";Inspired by better-auth.com — refined dark UI
@import "@farming-labs/theme/pixel-border/css";Faithful clone of the fumadocs default neutral theme
@import "@farming-labs/theme/colorful/css";Clerk docs-inspired — clean, polished purple accents
@import "@farming-labs/theme/shiny/css";Pure monochrome design — clean, bold, minimal
@import "@farming-labs/theme/darkbold/css";Mintlify-inspired — emerald green, Inter font, modern
@import "@farming-labs/theme/greentree/css";Original hard-edge preset with square corners and strong borders
@import "@farming-labs/theme/hardline/css";Louder brutalist variant with offset shadows and poster-style contrast
@import "@farming-labs/theme/concrete/css";theme: pixelBorder({
ui: {
colors: {
primary: "oklch(0.72 0.19 149)", // green
accent: "hsl(220 80% 60%)", // blue
},
},
}),import { defineDocs } from "@farming-labs/docs";
import { pixelBorder } from "@farming-labs/theme/pixel-border";
import { Rocket, BookOpen, Code } from "lucide-react";
export default defineDocs({
entry: "docs",
theme: pixelBorder({
ui: {
colors: { primary: "oklch(0.72 0.19 149)" },
typography: {
font: {
h1: { size: "2.25rem", weight: 700 },
body: { size: "0.975rem", lineHeight: "1.8" },
},
},
},
}),
nav: {
title: <div style={{ display: "flex", gap: 8 }}>
<Rocket size={14} /> My Docs
</div>,
},
icons: {
rocket: <Rocket size={16} />,
book: <BookOpen size={16} />,
code: <Code size={16} />,
},
sidebar: {
banner: (
<div>
<h2>Welcome to the docs</h2>
<p>This is a banner</p>
</div>
),
flat: false,
collapsible: true,
footer: (
<div>
<p>This is a footer</p>
</div>
),
},
components: { MyCustomCallout },
breadcrumb: { enabled: true },
themeToggle: { enabled: false, default: "dark" },
ai: {
enabled: true,
mode: "floating",
floatingStyle: "full-modal",
apiKey: process.env.OPENAI_API_KEY,
maxResults: 5,
aiLabel: "DocsBot",
suggestedQuestions: [
"How do I get started?",
"What themes are available?",
"How do I create a custom component?",
"How do I configure the sidebar?",
],
model: {
models: [
{ id: "gpt-4o-mini", label: "GPT-4o mini (fast)" },
{ id: "gpt-4o", label: "GPT-4o (quality)" },
],
defaultModel: "gpt-4o-mini",
},
},
pageActions: {
copyMarkdown: { enabled: true },
openDocs: {
enabled: true,
providers: [
{ name: "ChatGPT", urlTemplate: "https://chatgpt.com/?q={url}" },
],
},
},
metadata: {
titleTemplate: "%s – Docs",
description: "My documentation site",
},
});