Introduction
OwnDocs turns Markdown files into a documentation site with search, sidebar navigation, and password protection. It runs on Next.js 16, React 19, TypeScript 6, and Tailwind CSS 4.
Use it for an external API reference, an internal knowledge base, or customer-facing product guides. The page structure, components, and hosting setup come ready-made, so you're not building a docs site from scratch.
Why OwnDocs
Most documentation tools make you choose between control and setup time. Static site generators give you control but ask for hours of plugin configuration. Hosted platforms run the infrastructure for you but charge per seat and limit what you can change. OwnDocs ships as source code you own. It works without extra setup, and you can change any part of it.
Pages from files, no configuration. Create an .mdx file and write. OwnDocs
builds the sidebar, search index, breadcrumbs, table of contents, sitemap,
OpenGraph metadata, and static pages for you. There's no routing config or build
plugin to set up.
29 ready-made documentation components. They cover the patterns that keep coming up in technical writing: API endpoint docs, structured parameter fields, tabbed code groups, feature comparisons, step-by-step guides, release notes, and diagrams.
Two access modes, one codebase. One ACCESS_MODE environment variable
switches between private (password-protected) and public (open) access. One
deployment can serve internal team docs, client portals, and public product
docs.
You own the source. OwnDocs is a one-time purchase with an MIT license. No per-seat fees, no monthly subscriptions, no vendor lock-in. Deploy on Vercel, AWS, DigitalOcean, or your own server.
Technology Stack
OwnDocs is built on these libraries:
- Next.js v16 — App Router with Turbopack for sub-second hot reload, server and static rendering, and proxy middleware for authentication
- React v19 — Server Components and concurrent rendering for fast first paint and responsive pages
- MDX v3 — Markdown with embedded React components via
next-mdx-remote - Tailwind CSS v4 — Utility-first styling with OKLCH color space for consistent color themes across all 26 palettes
- Prism.js v1.30 — Client-side syntax highlighting for 65+ programming languages with hydration-safe rendering
- Mermaid v11 — Diagram rendering for 15+ diagram types with DOMPurify SVG sanitization for security
- Jose v6 — JWT-based authentication with HS256 signing for sessions
- DOMPurify v3 — SVG sanitization for all diagram output, which blocks XSS attacks
- Lucide React v1.0 — Icon library used across 29 components
- TypeScript v6 — Type safety across every source file in the project
Core Capabilities
Content Authoring
OwnDocs supports the content formats you'll need in a docs site:
- File-based routing — Every
.mdxfile inapp/becomes a page. The file path is the URL. No routing configuration needed. - MDX support — Write Markdown with embedded React components. 29 custom components are available on every page without imports.
- GitHub Flavored Markdown — Tables, strikethrough, task lists, and
autolinks via
remark-gfm - GitHub-style alerts — Six alert types (note, tip, important, warning, caution, danger) for flagging important information
- Frontmatter support — YAML metadata parsed via
gray-matterfor page descriptions used in SEO and search results - Internal link normalization —
.mdxextensions are stripped from links, so[Features](./features.mdx)and[Features](./features)both work - Copy page as Markdown — A dropdown button next to every page title copies the whole page as Markdown or plain text, ready to paste into ChatGPT, Claude, or Cursor
Code and Diagrams
Technical docs lean on readable code examples and diagrams. OwnDocs covers both:
- Syntax highlighting — 65+ programming languages with Prism.js client-side highlighting and dependency ordering handled for you
- 45 language aliases — Common shortcuts like
js,ts,py,sh,kt,rs,rb,tf,sol, and more - Line numbers — Line numbering with a configurable start offset
- Line highlighting — Highlight specific lines with
{1,3-5}syntax to point out key code - Diff markers — Inline
// [!code ++]and// [!code --]annotations for showing code changes without switching to diff format - Word highlighting — Highlight specific patterns with
/pattern/syntax to call out variables or functions - File titles — Show file path headers with
title="filename"metastring so readers know where code belongs - Collapsible code — Long blocks collapse with
expandableandmaxLines=Nto keep pages scannable while keeping full examples - Code groups — Tabbed code blocks for showing the same concept in multiple languages or package managers (npm/yarn/pnpm)
- Copy to clipboard — One-click code copying with visual feedback on every code block
- Mermaid diagrams — 15+ diagram types including flowchart, sequence, class, state, gantt, pie, ER, gitGraph, journey, mindmap, timeline, quadrant, sankey, and more
- Diagram detection — Mermaid diagrams render without the
mermaidlanguage tag when the content starts with a recognized diagram keyword
Navigation and Search
Readers find what they need from the sidebar, search, and breadcrumbs. OwnDocs builds each one from your file structure:
- Auto-generated sidebar — Built from the file system, with 3-level depth and active page highlighting
- Acronym-aware name formatting — 140+ technical acronyms keep their capitalization (API, REST, GraphQL, MongoDB, JWT, SSO, RBAC, and more)
- Full-text search — Client-side search across all pages with scored ranking and context snippets showing where the match was found
- Keyboard shortcut —
Cmd+KorCtrl+Kopens the search modal from any page, following the ARIA combobox pattern for screen readers - Heading anchors — Auto-generated slug IDs with clickable links via
rehype-slugandrehype-autolink-headingsfor deep-linking - Table of contents — Scroll-spy TOC on desktop that highlights the current section, with a collapsible panel on mobile
- Breadcrumb navigation — Auto-formatted path breadcrumbs on every page for orientation within the site hierarchy
- Previous/next navigation — Sequential page links at the bottom of every article for linear reading
- Auto-generated index —
<DynamicIndexContent />builds a site map with page counts for landing pages - Category index — Directories without an
index.mdxgenerate a landing page that lists all child pages
Documentation Components
OwnDocs ships 29 custom components. Each one is responsive, keyboard-accessible, and styled to match your theme:
- ApiBlock — REST API endpoint documentation with 5 HTTP method badges, color-coded headers, request/response bodies, multi-response tabs, auth indicators, deprecation notices, rate limiting, base URLs, and generated cURL examples
- ParamField — Structured parameter documentation with type, location (path, query, body, header), required/optional markers, default values, and deprecation labels
- ResponseField — Structured response field documentation for API endpoints
- CodeGroup — Tabbed code blocks with keyboard navigation for multi-language examples
- Tabs / TabItem — General-purpose tabbed content panels with ARIA tablist pattern and localStorage sync
- Steps — Numbered step-by-step guides with visual connectors for tutorials
- Card / CardGrid — Feature showcase cards with configurable grid columns and optional icons
- Accordion — Collapsible sections with smooth animation and URL hash deep-linking
- Badge — Inline status indicators in five variants (default, info, success, warning, danger)
- ComparisonTable — Side-by-side feature comparison with 10 visual indicator types and column highlighting
- FileTree — Visual directory structure from indented text
- ChangelogEntry / ChangelogLabel — Technical changelog timeline with 7 label types for developer audiences
- ReleaseNote / ReleaseHighlight — User-facing release announcements with 8 highlight types for public "What's New" pages
- ImageZoom — Click-to-zoom lightbox with keyboard and ARIA support
- Embed — Responsive iframe embeds with URL allowlist (YouTube, GitHub) and sandbox security
Theming
OwnDocs ships 26 color themes. Each theme is a coordinated palette that generates light mode, dark mode, and component-level CSS custom properties:
- 26 built-in palettes — violet (default), amber, blue, cyan, emerald, fuchsia, gray, green, indigo, lime, mauve, mist, neutral, olive, orange, pink, purple, red, rose, sky, slate, stone, taupe, teal, yellow, zinc
- Dark mode toggle — Light, dark, and system modes with
prefers-color-schemedetection and localStorage persistence - CSS custom properties — All colors defined as semantic variables
(
--color-accent,--color-bg-primary, and more) that switch between light and dark - Semantic aliases — Tailwind theme aliases (
surface-*,content-*,edge-*,brand-*) switch with dark mode withoutdark:variant classes - Custom typography — Maven Pro for body text, JetBrains Mono for code with ligatures and slashed zeros
Security
OwnDocs protects private docs in these ways:
- Password protection — JWT sessions with 24-hour expiry via
joselibrary - Browser fingerprinting — Sessions are invalidated if the User-Agent or Accept-Language header changes, which stops session hijacking
- Secure cookies —
__Host-prefix,httpOnly,secure,sameSite: lax - Cookie name obfuscation — Cookie name derived from SHA-256 of
COOKIE_SALT, making it unpredictable - Rate limiting — 5 login attempts per IP with a 15-minute lockout, plus a global cap of 50 failed attempts per 15 minutes, and timing-safe password comparison to stop brute-force attempts
- Origin validation — CSRF protection on all state-changing auth endpoints
- 9 security headers — HSTS (2-year with preload), CSP, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection (disabled, superseded by CSP), Referrer-Policy, Permissions-Policy, X-Robots-Tag
- 4-layer crawler blocking —
robots.txt, HTML meta robots,X-Robots-Tagheader, and password-gated access (private mode) - Path traversal checks — Slug validation rejects
..and leading/ - DOMPurify — SVG sanitization on all Mermaid diagram output to block XSS
SEO and AI Readiness
In public mode, OwnDocs prepares every page for search engines and AI agents:
- Dynamic sitemap —
sitemap.xmlgenerated from the navigation tree - OpenGraph and Twitter Cards — Per-page
og:title,og:description, andtwitter:cardmeta tags with descriptions pulled from MDX content - Canonical URLs —
<link rel="canonical">on every page to avoid duplicate content - JSON-LD structured data —
TechArticleandBreadcrumbListschema.org markup on every documentation page for rich search results - Dynamic robots.txt — 28+ named bots blocked in private mode, full crawling permitted in public mode
- llms.txt — AI agent index at
/llms.txtlisting all pages with URLs - llms-full.txt — Full documentation content at
/llms-full.txtfor bulk AI context loading - Copy page as Markdown — Dropdown button next to every H1 title with Markdown and plain text copy options for AI tools
Accessibility
OwnDocs follows WCAG guidelines for keyboard and screen reader support:
- Skip to content — Keyboard-accessible skip link visible on focus
- Focus management — H1 focused on route change so screen readers announce it
- Focus-visible indicators — Visible keyboard focus rings on all interactive elements (WCAG 2.4.7)
- ARIA patterns — Combobox on search, tablist on tabs/code groups, dialog on modals, region on code blocks
- Keyboard navigation — Arrow keys, Home/End, Enter/Space across search, tabs, code groups, and accordions
- Focus trapping — Search modal and image zoom trap focus within the dialog
- Body scroll lock — Background scroll disabled when modals are open
- Reduced motion — Respects
prefers-reduced-motionsystem preference - Print stylesheet — Code rendering adjusted for print, interactive elements hidden
- Content-visibility —
content-visibility: autoon prose content to cut rendering work
Public/Private Access Mode
OwnDocs has two access modes set by one environment variable, so the same codebase can serve internal and public docs:
- Private mode (default) — Password-protected access, all search engine and AI crawlers blocked, login required for every page
- Public mode — Open access for all visitors, search engines allowed to index content, login page redirects to home, logout button hidden
Set via the ACCESS_MODE environment variable. The default is private.
Project Structure
Architecture
The diagrams below show how content moves through the build pipeline, how the layout organizes navigation components, and how the security and SEO layers fit in:
Configuration by Environment
Configuration stays outside the code. A handful of environment variables decide the access mode, the password and signing secrets, the color palette, and the canonical site URL, so the same build serves a private team wiki or a public product site depending on what you pass it. The Configuration reference lists every variable, its default, and the command that generates it.
Adding Content
Create any .mdx file under app/ and it becomes a documentation page:
app/guides/deployment.mdx → /guides/deployment
app/api-docs/endpoints.mdx → /api-docs/endpointsDirectories become sidebar categories, and a numeric prefix like 01-basics/
controls the ordering. OwnDocs picks up each new file and wires it into the
sidebar, the search index, the sitemap, and the previous/next links. Nothing to
register, nothing to configure.
Linting and Formatting
OwnDocs ships a linting and formatting pipeline to keep content and code consistent:
npm run format # Format all files
npm run format:check # Check without modifying
npm run lint # ESLint for TS/JS
npm run lint:mdx # ESLint for MDX
npm run mdx:check # Remark lint for MDX/MarkdownThe pipeline runs ESLint with TypeScript rules, eslint-plugin-mdx for MDX
files, and remark-lint with the recommended and consistent presets. It also
checks heading style, validates links, and runs remark-preset-prettier so
remark rules don't fight Prettier formatting.
See also
- Installation — clone the repository and install dependencies with npm, Bun, or pnpm.
- Configuration — every environment variable and config file, with defaults and generation commands.
- Deployment — one-click deploys and manual builds on your own infrastructure.
- Feature Catalog — each feature on its own page with default, mixed, and advanced examples.