Fibel|

Hosting Fibel

Run Fibel as a documentation server or mount the documentation under a route in an existing app.

3 min read Updated 2026-06-09 #hosting#fetch#routing

Fibel exposes a fetch handler. The documentation can run as its own server or be mounted under a route in an existing web app.

Develop locally

Use the development command while editing content and configuration.

sh
bunx --bun @k2b/fibel dev --port 5173

The command loads fibel.config.ts, builds the theme CSS, creates the documentation app, and starts a local server.

The development server watches the config file, docs folder, and assets folder. When a change is detected, Fibel rebuilds the app in memory and reloads connected browser tabs after the rebuild succeeds.

sh
bunx --bun @k2b/fibel dev --no-watch
bunx --bun @k2b/fibel dev --no-reload

If a rebuild fails, the server keeps serving the last working app and prints the error in the terminal.

The watcher covers content, assets, and the config file only. Editing a project plugin or any other TypeScript file does not trigger a rebuild, so restart the server after changing plugin code.

Build for deployment

sh
bunx --bun @k2b/fibel build

The build creates a runtime entry and generated documentation files. Requests still pass through Fibel. This keeps the theme cookie, search, Markdown routes, and mounted paths consistent.

If the host owns its server bundle and output directory, generate only Fibel's runtime stylesheet:

ts
import { buildFibelStyles } from "@k2b/fibel/build";

await buildFibelStyles(process.cwd(), true);

The stylesheet is written to .fibel/public/styles.css. The second argument enables minification. The host remains responsible for its other assets and for replacing its build output.

Deploy behind Traefik

The recommended deployment is the container image behind Traefik.

yaml
services:
  docs:
    image: ghcr.io/k2b-dev/fibel:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.docs.rule=Host(`docs.example.com`)
      - traefik.http.routers.docs.tls.certresolver=letsencrypt
      - traefik.http.services.docs.loadbalancer.server.port=3000

The server listens on PORT, which defaults to 3000. Set siteUrl in fibel.config.ts to the same host so canonical URLs and the sitemap match the deployment.

For a project's own documentation, build an image from the project instead of using the Fibel image and keep the same labels.

Run the default docs image

The Fibel repository includes a Docker image for hosting the default documentation.

sh
docker build -t fibel-docs .
docker run --rm -p 3000:3000 fibel-docs

The image uses a Bun multi-stage build. It installs development dependencies only in the build stage, runs typecheck, tests, and build, then runs the generated server as the non-root bun user with production dependencies.

Tagged releases publish the image to GitHub Container Registry:

sh
docker run --rm -p 3000:3000 ghcr.io/k2b-dev/fibel:latest
docker run --rm -p 3000:3000 ghcr.io/k2b-dev/fibel:v0.7.2

Mount in Hono

ts
import { Hono } from "hono";
import config from "./fibel.config";
import { createFibelApp } from "@k2b/fibel";

const docs = await createFibelApp(config);
const app = new Hono();

app.mount("/docs", docs.fetch);

Set routing.basePath to the same path:

ts
export default defineFibel({
  title: "My Docs",
  routing: {
    basePath: "/docs",
  },
});

Fibel then generates links, internal routes, and assets relative to /docs.

If this instance enables agentSkillsPlugin(), also forward its origin-scoped well-known route:

ts
app.all("/.well-known/agent-skills/*", (c) =>
  docs.fetch(c.req.raw),
);

The host must do this explicitly because a /docs subrouter never receives requests for the origin root. See Agent Skills discovery.

Mount several instances

Several Fibel instances can run in one server and one deployment. Separate base paths keep their navigation, search indexes, assistant context, chat sessions, MCP endpoints, and path-scoped discovery routes independent:

ts
const docs = await createFibelApp(docsConfig); // basePath: "/docs"
const ui = await createFibelApp(uiConfig);     // basePath: "/ui"

export default new Hono()
  .mount("/docs", docs.fetch)
  .mount("/ui", ui.fetch);

The instances can share the same header configuration, theme cookie, assistant provider, and process-wide rate limiters. Only one instance can own origin-level Agent Skills discovery; route /.well-known/agent-skills/* to that explicit owner. The custom pages guide shows the complete header and Solid SSR setup.

Mount in other servers

Any environment that can pass a Web-standard Request to a fetch handler can serve Fibel.

ts
const docs = await createFibelApp(config);

export default {
  fetch(request: Request) {
    return docs.fetch(request);
  },
};

The host remains responsible for outer routing, authentication, or middleware. Fibel handles only requests forwarded to the documentation app.

Routes

A Fibel app handles:

  • Page routes such as /en/configuration.
  • Markdown source routes such as /en/configuration.md.
  • Internal files under routing.internalPath.
  • Assets under routing.assetsPath.
  • Plugin routes, including the SEO and llms.txt files.
  • Origin-scoped plugin routes when the outer server forwards them.
  • A redirect from the mount root to the default locale, so / lands on /en.

When a project runs under a base path, external links and reverse proxies should preserve that path.

Connect a coding agent

The Fibel skill provides compact working instructions. MCP supplies exact current documentation when details matter.

CLI command
bunx skills add https://docs.example.com

This command installs the working instructions published by this website in the selected coding agent.

For exact, current details, also connect the MCP server through one of the agent tabs.

Installation uses the open-source Vercel Skills CLI.

The skill and MCP complement each other: the skill describes workflows, while MCP supplies current documentation.