ScribekitDocs

Installation

Install the Scribekit package, wire up its stylesheet, and link the Claude Code skills.

3 min readUpdated 11 August 2026
Installation

This page gets the package and the Claude Code skills installed in an existing Next.js App Router project. It stops there: to build your first page, follow Quickstart; for what the pieces are, read Getting started.

Install the package

Install Scribekit together with next-mdx-remote, which renders the MDX bodies:

npm install @daanvandenbergh/scribekit next-mdx-remote

Scribekit declares four peer dependencies. Your project supplies them:

Peer dependencyRangeNotes
next>=14Optional peer. Required in practice: the components target the App Router
react>=18Required peer
react-dom>=18Optional peer
next-mdx-remote^5 || ^6Optional peer. Required to render any post or docs page body

The optional markings keep npm quiet for consumers who only import the Blog or Docs class in a script. If you render pages, install next-mdx-remote.

Everything else the package needs at runtime - @daanvandenbergh/i18nkit, fuse.js, gray-matter, remark-gfm, and server-only - is a real dependency and arrives with the install.

Import the stylesheet once

Import the stylesheet in your root layout, not in each page. It is a global sheet, and importing it more than once is wasted work:

// app/layout.tsx
import "@daanvandenbergh/scribekit/styles.css";

export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <html lang="en">
            <body>{children}</body>
        </html>
    );
}

The package sets sideEffects: ["**/*.css"], so bundlers will not tree-shake the import away.

Set metadataBase

Docs.docMetadata and Blog.postMetadata already emit their own metadataBase from the siteUrl you pass the instance. Set one in the root layout as well, so relative URLs elsewhere in your app resolve against the same origin:

// app/layout.tsx
export const metadata = {
    metadataBase: new URL("https://example.com"),
};

Use the same origin you give the instance. A mismatch produces canonical URLs that disagree with your other pages.

The skills ship inside the npm tarball. Symlink each one into .claude/skills/ so Claude Code picks it up:

mkdir -p .claude/skills
ln -s ../../node_modules/@daanvandenbergh/scribekit/skills/scribekit-blog .claude/skills/scribekit-blog
ln -s ../../node_modules/@daanvandenbergh/scribekit/skills/scribekit-docs .claude/skills/scribekit-docs
ln -s ../../node_modules/@daanvandenbergh/scribekit/skills/scribekit-hero .claude/skills/scribekit-hero
ln -s ../../node_modules/@daanvandenbergh/scribekit/skills/scribekit-docs-github-pages .claude/skills/scribekit-docs-github-pages

Check the links resolve:

ls -la .claude/skills/

Each entry should point at its target under node_modules/@daanvandenbergh/scribekit/skills/. A broken arrow means the package is not installed, or the relative path does not climb far enough out of .claude/skills/.

Link only what you need. scribekit-hero and scribekit-docs-github-pages each stand alone, so you can skip either. The two content skills are the exception, and the next section says why. See Skills for what each skill does.

Install scribekit-docs and scribekit-blog together

scribekit-docs depends on scribekit-blog. It reads two files from it, house-style.md for voice and MDX rules and research-protocol.md for how it sources facts, and it stops when it cannot resolve them at any of three locations, in order: a sibling scribekit-blog link, .claude/skills/scribekit-blog/ from the project root or $HOME, or node_modules/@daanvandenbergh/scribekit/skills/scribekit-blog/.

That last fallback means the package you installed in step 1 already satisfies the dependency, so linking scribekit-docs alone still runs. Link both anyway - the sibling link is what keeps working if the skills are ever copied out of a project that has no scribekit install. The same three-location fallback applies to scribekit-hero, which scribekit-blog and scribekit-docs hand off to for hero images.

Add the CLAUDE.md rule

The package also ships one CLAUDE.md rule snippet, rules/docs_parity.md: docs and README.md are updated in the same change as the code, never deferred. Claude Code inlines any @path reference in CLAUDE.md at load time, so point it straight at the file in node_modules and the text auto-updates with the package:

@node_modules/@daanvandenbergh/scribekit/rules/docs_parity.md

The path is relative to CLAUDE.md, so keep CLAUDE.md at the project root, next to node_modules. Unlike the skills, a rule needs no symlink.

Create the content directory

Each surface reads one directory, with one subfolder per page:

mkdir -p docs

A missing content directory is not an error: the reader returns no pages until the folder exists. contentDir resolves against process.cwd(), the directory holding the package.json you run Next from, so "./docs" means <project-root>/docs/.

Was this page helpful?