Files
homarr/apps/docs/README.md
T
Thomas 229bd4b3ed chore: use Bun package management and Turbo remote caching (#6978)
* feat: migrate tooling and runtimes to bun

* fix: serialize act installs and adapt backup checks

* fix: finish bun scripts and rootless act setup

* fix: support bun images in runtime benchmarks

* fix: keep a single bun toolchain configuration

* fix: include docs mascot sources in workshop build

* docs: use bun in remaining tool commands

* fix: complete bun sqlite development tooling

* docs: explain sqlite development adapter

* fix: align remaining commands and local ci validation

* fix: use renovate regex fallback with bun

* fix: finalize bun sqlite connections during cleanup

* fix: preserve sqlite foreign key enforcement

* fix: align docker build frontends

* fix: prepare release versions with bun

* Add Bun benchmarks and preserve SQLite connection defaults

* Benchmark Bun installs, conflicts and production workloads

* Force Bun workspace tools and HTTP/1.1 upstream streaming

* Exclude benchmark evidence from Docker contexts

* Expose branch benchmarks through CI

* Verify hydrated widget data in production benchmarks

* Measure image archives and document benchmark protocol

* Audit dependency sharing across every workspace

* Pin pnpm for nested baseline benchmark scripts

* Preserve nested manager pinning on benchmark resume

* Include application and runtime image footprints

* Fail benchmark gates on candidate command errors

* Report complete build overhead and sampled memory bounds

* Validate migration comparisons across pinned revisions

* Record configurable runtime memory budgets

* Retain out-of-memory kills in runtime budget probes

* Reject OOM events consistently across runtime metrics

* Record complete Bun migration benchmarks

* Record memory diagnosis and correct Turbo caching

* Use Bun package management while preserving Node runtimes

* Keep native build fallbacks and exclude development artifacts

* Fix Node ESM metadata and isolate local CI configuration

* Measure development performance and isolate act environment

* Support isolated environment files in rootless act

* Validate the full migration range with act

* Preserve native SQLite binding for bundled migrations

* Use documented dev defaults and report benchmark scope

* Validate dev defaults and isolate restart measurements

* Record package-manager and development benchmarks

* Keep benchmark measurements and link full command artifacts

* Clean up temporary act environment files

* Validate Node runtimes in package-manager comparisons

* Validate every workspace in manual CI runs

* Retain patched nested brace expansion versions

* Complete package-manager and Node performance report

* Normalize archived benchmark logs

* Record final hosted validation

* Cache both Next builds with platform isolation

* Prime cache with write-only mode

* Split Next artifacts below Cloudflare upload limit

* Assemble coherent standalone cache outputs

* Preserve traced middleware entrypoints

* Assemble traced directory links before files

* Separate cached dependencies from assembled output

* Record signed Turbo cache benchmarks

* Remove archived benchmark captures

Full benchmark evidence is preserved at 8f7d3bcd14109bfb13fa664d31710b88d820ad66.

* Remove migration benchmark harness

* fix: correct migration launch and local Act prerequisites

* Consolidate Turbo caches and production artifacts

* Exclude generated files from Docker cache inputs

* fix: address Bun migration review findings

* fix: check restored compiler bundle manifests
2026-10-07 16:38:14 +02:00

11 KiB

Homarr documentation (@homarr/docs)

The source for homarr.dev, built with Next.js and Fumadocs UI inside the Homarr monorepo.

Develop

From the repository root:

bun run dev:docs

The site runs on http://127.0.0.1:3003. To use a local Workshop API:

WORKSHOP_API_URL=http://127.0.0.1:8090 bun run dev:docs

Validate

bun run --filter @homarr/docs typecheck
bun run --filter @homarr/docs build
bun run --filter @homarr/docs validate:links
bun run --filter @homarr/docs verify:search
bun run --filter @homarr/docs verify:seo

The static export is written to out/. The build validates docs pages and typed metadata for integrations and widgets that declare a documentation slug. Set the slug to null when a page would add no useful information for advanced users. CI enforces coverage alongside schema drift and export validation. The link check validates internal Markdown and MDX links and rendered anchors against the export. The search check exercises the exported index with title, heading, and body queries and verifies result destinations. The SEO check validates canonical URLs, descriptions, social metadata, heading structure, and sitemap coverage in the exported HTML. These tags are generated at build time; set HOMARR_WEBSITE_URL before building for a different origin.

Preview the static export with PocketBase

After building the docs, run from the repository root:

sh apps/workshop/preview-docs.sh

Open http://127.0.0.1:8093/docs/. This starts an isolated PocketBase container with temporary local data and serves the export directly, including search, Markdown, and the custom 404 page. Workshop browser requests use the configured backend; a trailing /api/ is removed because the PocketBase SDK appends its API paths. The preview does not copy or migrate another database. Set WORKSHOP_API_URL to a remote PocketBase origin when testing against one; WORKSHOP_REMOTE_API_URL can override the server-side metadata source independently. Direct item links then use that source for titles and social metadata. Missing remote items return 404; an unavailable backend returns 503.

Verify public item pages without changing the remote database:

REMOTE_WORKSHOP_URL=https://workshop.example.com
WORKSHOP_TEST_URL=http://127.0.0.1:8093 WORKSHOP_REMOTE_API_URL="$REMOTE_WORKSHOP_URL" \
  bun apps/workshop/tests/remote-workshop.integration.mjs

Stop it with docker stop homarr-docs-static-preview. Rebuild and restart the preview after changing source files; startup recreates the runtime configuration. DOCS_PREVIEW_PORT, DOCS_PREVIEW_HOST, and DOCS_PREVIEW_NAME override the defaults. Set the host to this machine's Tailscale address to access it from your other devices.

Write content

Documentation lives in docs/; project posts live in blog/. Navigation is controlled by the nearest meta.json. Integration and widget folders pair typed index.ts metadata with index.mdx content.

Use standard Markdown and MDX. Shared components live in src/components/. Mermaid fences, tabs, callouts, zoomable images, and syntax-highlighted code are supported by the Fumadocs pipeline.

Update docs in the same pull request only when a smart, advanced user cannot infer the changed behavior from the UI or generated API schema. Routine or self-explanatory changes need no docs update. See the documentation-sync skill for target paths.

Published formats

  • /docs — searchable documentation with typed navigation
  • /api-reference — interactive reference generated from the OpenAPI schema
  • /llms.txt — compact documentation and blog index for agents
  • /llms-full.txt — complete processed Markdown corpus
  • /llms.mdx/docs/.../content.md — raw Markdown for each docs page
  • /llms.mdx/blog/.../content.md — raw Markdown for each blog post
  • /llms.mdx/api-reference/.../content.md — operation parameters, bodies, responses, and authentication
  • /blog/rss.xml — RSS feed for project posts
  • /search?q=... — opens documentation search with the supplied query, including existing Homarr search-engine links

Every docs page and blog post includes copy-Markdown and view-source actions. Search is generated at build time and runs locally in the browser; it does not depend on an external crawler. Markdown exports and search resolve integration credentials and widget defaults from the same typed metadata used by the pages. The search dialog and its client-side engine load when search is first opened. Fumadocs caches the downloaded index for subsequent queries. The docs index, individual Markdown pages, and full corpus share the llms() renderer. API operations are indexed alongside docs and exported as Markdown from the same OpenAPI schema. The reference uses Fumadocs with Scalar: select an instance URL and API key, then explicitly send a request. Authentication is not persisted in local storage. Browser access requires the documented REST CORS configuration.

The Custom JSX guide includes a lazily loaded, editable example using the application renderer and real component registry. Its bindings work locally; configured widget queries and actions do not run.

The getting-started overview and complete Custom JSX component catalog are also included, with property types, binding contracts, and blocked capabilities taken from the published catalog JSON.

Published Docusaurus /docs/category/... addresses remain available as static compatibility pages. They forward to the corresponding overview or developer setup guide, preserving query strings and anchors, and provide a direct link when JavaScript is disabled. Their canonical metadata points to the destination; compatibility pages are excluded from search and the sitemap.

Fumadocs upgrade notes

The September 2026 update moves Core/UI from 16.15.4 to 16.15.12, MDX from 15.4.0 to 15.4.3, and OpenAPI from 11.3.5 to 12.0.1. Review the upstream Core, UI, MDX, and OpenAPI changelogs when upgrading.

  • Core/UI and MDX now declare side effects for better tree shaking. UI also fixes tabs reverting to the URL hash.
  • Core's llms({ renderPage }) API provides the shared index(), page(), and full() exports.
  • OpenAPI 12 replaces several custom renderer options and hooks. This site uses createOpenAPIPage() and getOpenAPIPageProps() without those removed overrides; the built-in renderer retains all request languages. The Scalar adapter receives an equivalent nonrecursive union for unconstrained JSON values to avoid recursive schema expansion during rendering. The generated public OpenAPI document remains unchanged.
  • MDX 15.4.3 fixes duplicate compilation output when its experimental build cache is enabled. We leave that cache disabled: its current key checks source content without accounting for all compiler configuration changes.
  • The existing macro collections, processed-Markdown component adapters, and static search remain supported. Typed version roots and server-side MCP tools are available upstream but are not needed by this static site.

Kapa AI

The compact Homarr mascot in the bottom-right opens Ask AI. It slowly spins when idle and gives a subtle claw movement and wink on hover. Animation respects reduced motion.

The launcher uses Homarr's existing public Kapa Website ID. The root layout loads the widget once across client-side navigation and follows the docs light or dark theme. Search and Ctrl+K / Cmd+K always use Fumadocs search, including when Kapa is unavailable.

Set KAPA_WEBSITE_ID at build time to use a different Kapa Website Widget integration. An explicitly empty value disables the widget, for example KAPA_WEBSITE_ID= bun run --filter @homarr/docs build. This is a public integration ID included in exported pages, not a Kapa API key. Rebuild the static export after changing it.

In the Kapa dashboard, confirm the integration is live and enable the production and preview domains. Restoring the script does not verify that the historical integration is still active. Follow the Kapa widget setup for domain restrictions and CSP settings.

After changing the documentation structure, review the Website Crawl source in Kapa: use the deployed /docs URL as the start URL and preview main as the content selector. Replace any old Docusaurus-specific selector and check that titles, headings, code samples, and integration details appear in the extracted Markdown. Docs are exported as HTML; the site also publishes /sitemap.xml and permits crawling in /robots.txt. The /llms.txt exports do not configure Kapa ingestion automatically. See Kapa source setup.

Before publishing, check that Ask AI opens after navigating between pages, ask a documentation question, and verify its citations point to the current docs. In a separate check, block widget.kapa.ai and confirm search still works.

Release verification

The production image compiles the docs itself; it does not depend on a host out/ directory. Build-time HOMARR_WEBSITE_URL controls canonical metadata. Runtime URL overrides configure Workshop connections but do not rewrite already-exported canonical URLs.

PostHog records SPA pageviews, installation clicks, searches with no results (including the search query), and Workshop content downloads and submission starts/completions through hog.homarr.dev. Downloads include JSON files and successful JSON/CSS clipboard copies. All events carry site and source_path. Autocapture, page-leave events, and session replay are disabled; tracked URL query strings and fragments are removed. Localhost and ?analytics_test traffic carries verification=true; exclude it from production reports.

Carbon loads one visible placement after the desktop TOC, below API examples, or below content on other layouts. The homepage is excluded at every viewport size. Navigation reloads the ad script; resizing changes placement only when crossing its breakpoint. Ad blockers or no-fill responses must not prevent content, navigation, or search from working.

To preview Carbon locally, start docs with NEXT_PUBLIC_ENABLE_CARBON_ADS=true bun run dev:docs. Production builds enable ads automatically. When the TOC collapses into a toggle, the ad appears below the content before “Edit this page”.