Quickstart
Create a Brief app, run it locally, and start writing your documentation.
Setup#
The quickest way to set up a Brief app is using create brief, which gives you a ready-to-use Next app.
Then, open localhost:3000
Project Structure#
Brief's configuration is contained in /brief. All configuration is split across files in /brief/config while content is written in a Next-inspired folder structure in /brief/case (pun intended).
---
name: brief
description: Read and navigate this documentation site.
---
# Documentation
Start with `/llms.txt` to find documentation pages. Read the linked Markdown files for the task at hand. Use the site's MCP endpoint at `/mcp` when available.
---
title: Welcome to your documentation
description: Write your first pages, organize your navigation, and publish a
documentation site with Brief.
updatedAt: 2026-10-23T03:12:39.006Z
contentHash: sha256-ast-v1:3c7a4dce7daf503d63f8410904b89e3e7bd899afaf246238d10a370fe44e4e9b
---
Welcome to your documentation site. Replace this page with an introduction to your project
and help readers take their first step.
## Edit this page
Open `brief/case/docs/v1/welcome/en.md` and write your content using Markdown.
Use the development command in your project's `README.md` to preview your changes.
## Add a page
Use your package manager to run
`brief page add docs/v1/getting-started --title "Getting started"`.
Pages live in `brief/case/`. The `*.meta.toml` files define your site's tabs, versions,
and navigation.
Keep each page focused on one task or topic. Use headings to divide longer explanations,
and link related pages so readers can find their next step.
## Publish your documentation
Run `brief check` to validate your content and links, then use your project's build command.
See the project's `README.md` for configuration and deployment options.
routeKey = "page_0a07caa339ae4da6af1e127ea8b1e2cc"
label = "v1"
title = "Documentation"
defaultVersion = "v1"
{
"checkpoint": {
"pages": [
{
"key": "page_0a07caa339ae4da6af1e127ea8b1e2cc",
"id": "docs/v1/welcome",
"urls": {
"en": "/welcome"
},
"title": "Welcome to your documentation"
}
]
},
"renames": [],
"redirects": [],
"pendingPageRemovals": []
}
title = "Brief"
defaultTab = "docs"
[locales]
default = "en"
[locales.localeLabels]
en = "English"
import { defineBuild } from '@brief/build/config'
import { comarkFormat } from '@brief/format-comark'
import { miniSearchSearchBuilder } from '@brief/search-minisearch/build'
import components from './components.ts'
import metadata from './metadata.ts'
import search from './search'
export default defineBuild({
customMetadataSchemas: metadata,
formats: [comarkFormat({ components })],
search: { builder: miniSearchSearchBuilder, definition: search },
})
import { ComponentRegistry } from '@brief/ui/components'
export default new ComponentRegistry()
import 'server-only'
import { comarkContent } from '@brief/format-comark'
import { defineContent } from '@brief/ui/config/content'
import components from './components.ts'
export default defineContent({
components,
renderers: [comarkContent],
})
import { createMetadataSchemas } from '@brief/ui/custom-metadata'
export default createMetadataSchemas()
import { defineMiniSearch } from '@brief/search-minisearch'
export default defineMiniSearch()
/** Attribution applied to eligible external links. */
import { defineUtm } from '@brief/ui/config/utm'
export default defineUtm({ source: 'brief', medium: 'referral' })
import { defineVisuals } from '@brief/ui/config/visuals'
import { OUTLINE_DUO_ICONS } from '@brief/ui/icons/interface-icons/outline-duo'
export default defineVisuals({ interfaceIcons: OUTLINE_DUO_ICONS })
/** Shares the filesystem search client between MCP queries after its first import. */
import 'server-only'
import { createServerClient } from '@brief/search-minisearch/node'
import search from './config/search'
export const mcpSearch = createServerClient(search)
import 'server-only'
import { briefRoute } from '@brief/ui-next/route'
import type compiler from './config/compiler'
import publication from './publication'
const brief = briefRoute<typeof compiler>(publication)
export const { Page, generateStaticParams } = brief
export async function generateMetadata(props: Parameters<typeof brief.generateMetadata>[0]) {
const metadata = await brief.generateMetadata(props)
if (metadata.openGraph === undefined) return metadata
return {
...metadata,
openGraph: {
...metadata.openGraph,
images: [{ url: '/opengraph-image', width: 1200, height: 630, alt: `Brief documentation` }],
},
twitter: { ...metadata.twitter, images: ['/opengraph-image'] },
}
}
export const { TocPage } = brief
export const { shellViews, locale } = brief
export const { markdown } = brief
export const { llmsTxt, llmsFullTxt, llmsIndex } = brief
export const { sitemap } = brief
export const { mcp } = brief
export const { robotsTxt } = brief
export const { skills } = brief
import { mcpServerName } from '@brief/adapters-utils/publication'
import { resolveSiteOrigin } from '@brief/next'
import type { UiBriefRouteOptions } from '@brief/ui-next/route'
import type compiler from './config/compiler'
const publication: UiBriefRouteOptions<typeof compiler> = {
mcp: {
server: { name: mcpServerName(resolveSiteOrigin()) },
search: {
provider: {
search: async (request) => (await import('./mcpSearch')).mcpSearch.search(request),
},
},
},
skills: { defaultSkill: 'brief' },
contentSignals: { search: true, aiInput: true, aiTrain: true },
}
export default publication
Content#
Node | Description | Configuration file |
|---|---|---|
Page | Individual page. Represented by a folder with one [locale].md file per locale. | page.meta.toml |
Group | Ordered group of pages. Represented by a folder with one folder per contained unit (which can be pages or nested groups). | group.meta.toml |
Tab | Top-level group. Tabs are versioned independently. | tab.meta.toml |
Version | Tab version, which can evolve and be versioned independently. | version.meta.toml |
Page, group, tab, and version structure is dictated by folder organization.
Configuration#
File | Description |
|---|---|
compiler.ts | Configures Brief's compiler so it knows how to lint and edit pages. |
components.ts | Registers components available in all pages. |
content.ts | Configures the Markdown format and wires components.ts through. |
metadata.ts | Defines the metadata accepted on pages and folders. |
search.ts | Configures client-side and MCP search. |
utm.ts | Sets UTM attribution parameters for all external links. |
visuals.ts | Configures the site's logos, appearance, colors, and icons. |
Out of all of these, you'll likely only need to edit utm.ts and visuals.ts.
For more on visual customization, visit the Visual Customization page.
Next & MCP Config#
Some additional Next and MCP adapter files exist in brief/ to bridge these settings to Next.js and MCP:
File | Description |
|---|---|
next.ts | Connects Brief's pages, metadata, and endpoints to Next.js. |
publication.ts | Defines MCP behavior, published agent skills, and crawler content signals. |
mcpSearch.ts | Creates the server-side search client used by MCP. Included when search is enabled. |