Skip to content

Documentation that ships with your Laravel app

Write Markdown in resources/docs. Your app serves it at /docs, with search, versions and an API reference.

Terminal
composer require jimmyverburgt/vellum
php artisan vellum:install

Write Markdown

Pages are CommonMark with GitHub Flavored Markdown, including tables and fenced code blocks.

Markdown

md
## Rate limits

Every API key gets **60 requests per minute**. Above that you get a `429`.

```php
RateLimiter::for('api', fn ($request) =>
    Limit::perMinute(60)
);
```

| Plan | Per minute | Burst |
| --- | --- | --- |
| Free | 60 | 10 |
| Team | 600 | 100 |

Rendered

Rate limits

Every API key gets 60 requests per minute. Above that you get a 429.

php
RateLimiter::for('api', fn ($request) =>
    Limit::perMinute(60)
);
Plan Per minute Burst
Free 60 10
Team 600 100

Compose with directives

Callouts, tabs, steps and cards are written as ::: blocks in the Markdown.

Markdown

md
:::tip
Callouts, tabs, steps and cards are `:::` blocks. They need no Blade.
:::

:::tabs
::tab[Composer]
```bash
composer require jimmyverburgt/vellum
```
::tab[Artisan]
```bash
php artisan vellum:install
```
:::

:::steps
## Write a page
Add `resources/docs/billing.md`.

## Link it
Add it to `meta.json` to order the sidebar.
:::

:::cards
::card[Callouts](/docs/components/callouts)
::card[Tabs](/docs/components/tabs)
:::

Rendered

Tip

Callouts, tabs, steps and cards are ::: blocks. They need no Blade.

composer require jimmyverburgt/vellum
php artisan vellum:install

Write a page

Add resources/docs/billing.md.

Add it to meta.json to order the sidebar.

Connect to the app

Pages can print the config, env and route values you allowlist, and can use your own Blade components. Values and components are resolved when the page is served.

Markdown

md
These docs belong to <x-vellum::config key="app.name" />
and are served at <x-vellum::route key="vellum.docs.index" />.
Release notes: <x-vellum::route key="vellum.changelog" />.

<x-plan name="Team" seats="5">
Shared billing, one invoice, every seat sees the same docs.
</x-plan>

Rendered

These docs belong to vellum-site and are served at https://vellum.jimmyverburgt.com/docs . Release notes: https://vellum.jimmyverburgt.com/docs/changelog .

Team plan5 seats

Shared billing, one invoice, every seat sees the same docs.

Gate pages

Require a signed-in reader or a Laravel gate for a page or a whole folder. Readers without access get a 404.

yaml
---
title: Billing
access: auth
---
json
{ "title": "Admin", "access": "manage-team" }

Version folders

The latest version is served without a prefix. Other versions sit under their folder name, and the switcher shows the labels you set.

php
'versions' => [
    'enabled' => true,
    'latest' => 'v1',
    'list' => ['next', 'v1'],
    'labels' => ['v1' => '1.x (LTS)', 'next' => 'Next'],
],

Changelog and feed

A CHANGELOG.md in the Keep a Changelog format is rendered as a page, with an Atom feed.

0.9.2

Added
  • Webhooks: each of the spec's webhooks gets a page in a Webhooks folder, with the headers and payload it arrives with, an example payload beside them, and what to answer with. It has no samples or playground, and the spec's top-level security does not apply to it
  • Callbacks: an operation's page lists the requests the API sends back, with the address, the payload and the statuses to answer with
  • Samples a spec writes itself under x-codeSamples (or x-code-samples) come first among the request samples, and take the place of a generated one in the same language
  • A Python sample, with requests, is generated alongside curl, PHP and JavaScript. openapi.samples lists python by default; a published config keeps its own list
  • Every field in a parameter list or schema has an address made of the names that lead to it, such as #body-captain-name, and its name links to it
Changed
  • The build's link check lets a #fragment land on anything on the page with that id, not only a heading, so links to a field of the reference or to a footnote pass

All releases and the Atom feed

Docs for AI tools

Agents get an llms.txt index, any page as Markdown, and a JSON search endpoint. Readers can copy a page as Markdown or open it in Claude or ChatGPT. Gated pages are left out of all of these.

text
GET /llms.txt
GET /docs/_vellum/raw/billing.md
GET /docs/_vellum/search?q=refunds
text
Open in Claude
Open in ChatGPT
Copy Markdown

API reference

Point Vellum at an OpenAPI spec, or let Scramble write one from your routes, and every operation gets a page with its parameters, request samples and a playground that sends the request. The list below is a live example on this site.

Presets

Three colour presets with light and dark modes, and an accent setting for your brand colour. The swatches below change the preset of this page.

Preset: Neutral

Tip: Three presets, one accent

Every preset meets WCAG AA contrast in light and dark mode. Set accent to your brand colour and it recolours links, buttons and focus rings on any of them.

php
'theme' => [
    'preset' => 'ocean',
    'accent' => '#7c3aed',
    'default' => 'system',
],

Install with two commands

The install command publishes config/vellum.php, copies the compiled CSS and JavaScript to public/vendor/vellum, and adds starter pages to resources/docs. From there you add and edit Markdown files in that folder.

Require the package

Terminal
composer require jimmyverburgt/vellum

Publish config and starter pages

Terminal
php artisan vellum:install

Open the site

Visit /docs. Edit resources/docs/ and reload.

Add docs to your Laravel app

Vellum installs with Composer. Pages can print allowlisted config values, your existing gates decide who can read them, and the docs go out with each deploy. For a host that cannot run PHP, vellum:export writes them as static HTML.

The page What is Vellum explains how it works and what it leaves out. The Comparisons page sets it beside LaRecipe, the closest alternative.

Note: Two commands

Terminal
composer require jimmyverburgt/vellum
php artisan vellum:install

Then open /docs. Requires PHP 8.4 or later and Laravel 11, 12 or 13.

Built on other people's work

The main ones are listed here.

  • Fumadocs The reference for the sidebar and table of contents layout, the ::: directive syntax and code tabs. For a Next.js project, use Fumadocs itself.
  • Phosphor Icons Every icon in the chrome, the callout glyphs and the code-block language marks.
  • league/commonmark Markdown parsing, including GitHub Flavored Markdown. Vellum's directives are extensions to it.
  • Tempest Highlight Syntax highlighting on the server, so no highlighter ships to the browser.
  • Alpine.js Theme toggle, tabs, dialogs, sidebar and scroll spy.
  • MiniSearch Search ranks results with BM25, using MiniSearch's scoring constants. Before 0.7, Vellum used the library itself.

Full credits and licences