- Notion-style document editor — block-based rich text with headings, callouts, tables, code blocks, embeds, slash commands, and drag-and-drop reordering via BlockNote
- File manager — upload, organize, preview, and download files; ZIP extraction; breadcrumb navigation; card and list view
- Document versioning — full revision history with author attribution and restore
- Rich previews — PDF, images, Markdown, plain text; Office documents converted via LibreOffice/Gotenberg headless pipeline
- AI search and Q&A — semantic search powered by pgvector; conversational Q&A over your document corpus via Claude or OpenAI (auto-selected); offline fallback via Ollama
- Workspaces with RBAC — multi-tenant; per-workspace roles: owner, admin, member, viewer
- Auth — email + password (argon2) and Google OAuth; JWT access + rotating refresh tokens; super-admin seeded from environment on first boot
- Sharing — share documents and files with users inside or outside your workspace via public links or direct invite
- Offline-first PWA — full local-first operation via Dexie (IndexedDB); all writes are queued through an outbox and synced when back online; installable via browser
- Dark mode out of the box
- Docker Compose deployment — single port exposed via nginx; everything else is internal
| Layer | Technology |
|---|---|
| Backend | Python 3.12 + FastAPI |
| ORM / Migrations | SQLAlchemy 2.x + Alembic |
| Frontend | Vite + React (JSX, no TypeScript) + shadcn/ui + Tailwind CSS |
| Editor | BlockNote |
| Database | PostgreSQL 16 + pgvector |
| Auth | argon2-cffi, JWT (access + refresh), Google OAuth |
| AI (cloud) | Anthropic Claude (LLM) + OpenAI text-embedding-3-small |
| AI (offline) | Ollama (llama3.1 + nomic-embed-text) |
| Job Queue | Arq (Redis-backed) |
| Cache | Redis 7 |
| File Storage | Pluggable — bundled MinIO, AWS S3, Cloudflare R2, Backblaze B2, or Azure Blob Storage (presigned URLs everywhere) |
| Offline Sync | Dexie (IndexedDB) + outbox pattern |
| PWA | vite-plugin-pwa |
| Reverse Proxy | Nginx (single host-exposed port) |
| Office Conversion | Gotenberg (LibreOffice headless) |
- Docker and Docker Compose v2+
- Git
git clone https://github.com/YavLabs/docx.git
cd docxcp .env.example .envOpen .env and fill in the required values. At minimum, set:
APP_BASE_URL— the public URL users open in their browser (e.g.http://localhost:8080,http://10.6.30.16:8080, orhttps://docx.example.com). Every emitted URL (emails, OAuth callback, presigned downloads) derives from this.POSTGRES_PASSWORD— database passwordJWT_SECRET— generate withopenssl rand -hex 32MINIO_ROOT_PASSWORD— MinIO root credentials (only required when using the bundled MinIO)SUPERADMIN_EMAILandSUPERADMIN_PASSWORD— initial super-admin account
When you run docx behind NGINX Proxy Manager, Caddy, Cloudflare, or any other TLS-terminating front-end, just point that proxy at the docker host on ${APP_PORT} and set APP_BASE_URL to the public address. The backend rebuilds all outbound links — verification emails, password resets, share links, OAuth redirects, and presigned download URLs — using that value.
STORAGE_BACKEND selects the driver:
| Backend | Use when | Required env |
|---|---|---|
s3 (default) |
Bundled MinIO, AWS S3, Cloudflare R2, Backblaze B2, etc. | STORAGE_BUCKET, STORAGE_ACCESS_KEY, STORAGE_SECRET_KEY, STORAGE_ENDPOINT_URL (blank → fall back to the bundled MinIO), STORAGE_REGION, STORAGE_SECURE |
azure |
Azure Blob Storage | STORAGE_BUCKET (= container), STORAGE_AZURE_ACCOUNT_NAME, STORAGE_AZURE_ACCOUNT_KEY, optional STORAGE_AZURE_ENDPOINT |
Same call sites everywhere — the rest of the codebase goes through one ObjectStore interface so the bucket name, credentials, and endpoint are all you need to switch.
STORAGE_PRESIGN_REWRITE_TO_PUBLIC controls whether presigned URLs are made same-origin (true, the right choice for MinIO behind nginx) or kept absolute (false, for AWS / R2 / Azure). The default auto picks the right behavior based on the endpoint hostname.
docker compose up -d --buildThis starts: PostgreSQL, Redis, MinIO, the FastAPI backend, an Arq worker, the Vite frontend, Gotenberg, and an Nginx reverse proxy.
docker compose exec api uv run alembic upgrade headThe super-admin account is seeded automatically on first boot using SUPERADMIN_EMAIL / SUPERADMIN_PASSWORD.
docker compose --profile ai-local up -d ollamaWhen OLLAMA_BASE_URL is reachable the AI provider falls back to local models automatically — no cloud credentials required.
Open http://localhost:8080 in your browser (or your configured APP_PORT).
Log in with the super-admin credentials from your .env file.
For pointing the app at a real domain, swapping object storage, publishing
Docker images, and using the prebuilt docker-compose.prod.yml, see
DEPLOY.md. Highlights:
- Single
APP_BASE_URLchange → emails, CORS, OAuth, presigned URLs all switch. STORAGE_BACKEND+STORAGE_*→ external MinIO, AWS S3, R2, B2, or Azure Blob.scripts/reset.sh→ nukes volumes, brings the stack back up looking like first boot.scripts/publish-images.sh+.github/workflows/publish-images.yml→ publishyavadmin/docx-*to Docker Hub.docker-compose.prod.yml→ deploy with prebuilt images.
cd apps/api
cp ../../.env.example ../../.env # if not already done
uv sync
uv run alembic upgrade head
uv run uvicorn app.main:app --reload --port 8000cd apps/web
npm install
npm run devThe Vite dev server runs on port 5173. In development the full stack is
accessible through nginx on APP_PORT (default 8080), which proxies HMR
WebSocket connections automatically.
# Backend
cd apps/api && uv run pytest
# Frontend
cd apps/web && npm testAll variables are documented in .env.example. The file is organized into sections:
- App —
APP_PORT(nginx host port, default8080) andAPP_BASE_URL(the single public origin every emitted URL derives from) - CORS —
EXTRA_CORS_ORIGINSfor extra allowed origins;APP_BASE_URLis allowed automatically - PostgreSQL — database connection
- Object storage —
STORAGE_BACKEND(s3orazure),STORAGE_BUCKET, plus the backend-specific credentials - MinIO — legacy block kept as a default fallback for the
s3backend - Redis — Arq job queue and cache
- Gotenberg — Office-to-PDF conversion service
- Encryption —
SETTINGS_ENC_KEYfor app settings stored in the database - JWT —
JWT_SECRET, access / refresh token lifetimes - Super Admin —
SUPERADMIN_EMAIL/SUPERADMIN_PASSWORDseeded on first boot - Google OAuth — optional;
GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET(the redirect URI auto-derives fromAPP_BASE_URL) - AI providers —
ANTHROPIC_API_KEY,OPENAI_API_KEY,OLLAMA_BASE_URL; the provider is auto-selected; all three are optional but at least one is needed for AI features
+-------------+
| Nginx | port APP_PORT (public via APP_BASE_URL)
+------+------+
/ | \ \
+------+ +--+--+ +-------+-------+
| Web | | API | | Object Store |
| :5173 | |:8000| | (MinIO / S3 / |
+-------+ +--+--+ | R2 / Azure) |
| +---------------+
+--------+--------+
| |
+------+------+ +------+------+
| PostgreSQL | | Redis |
| + pgvector | | (queue/cache|
+-------------+ +------+------+
|
+------+------+
| Worker |
| (Arq) |
+------+------+
|
+------------------+------------------+
| |
+------+------+ +-------+------+
| Gotenberg | | Ollama |
| (Office PDF)| | (local AI, |
+-------------+ | optional) |
+--------------+
Key design principles:
- Offline-first — every write is queued via an outbox; every read has a Dexie fallback; the app is fully functional with no network
- One public origin —
APP_BASE_URLis the single canonical URL; CORS, OAuth callbacks, email links, and presigned download URLs all derive from it - Pluggable object storage — a single
ObjectStoreinterface backs MinIO, AWS S3, R2/B2 (any S3-compatible service), and Azure Blob — picked by env, no code changes - Provider abstraction for AI — Claude, OpenAI, and Ollama all satisfy a single
AIProviderprotocol; the app picks the best available at runtime - Single ingress — only nginx is exposed to the host; all other services communicate on the internal Docker network
- RBAC-first — every API endpoint enforces role permissions before executing
docx/
apps/
api/
app/
auth/ # JWT, OAuth, password hashing
workspaces/ # Workspace RBAC + membership
documents/ # BlockNote doc storage + versioning
files/ # MinIO upload/download/preview
ai/ # AIProvider protocol + Claude/OpenAI/Ollama impls
search/ # pgvector semantic search
sync/ # Outbox + sync API for offline clients
core/ # DB session, settings, middleware
alembic/ # Database migrations
tests/
web/
src/
components/ # Reusable UI (shadcn/ui + Radix primitives)
pages/ # Route-level page components
hooks/ # Custom React hooks
db/ # Dexie schema + offline storage
outbox/ # Offline write queue + sync engine
services/ # API client functions
lib/ # Utilities and formatters
public/
packages/
ui/ # Shared shadcn/Radix primitives (JSX)
nginx/
nginx.conf
docker-compose.yml
.env.example
| Phase | Status | Description |
|---|---|---|
| 0 | Done | Scaffold — monorepo, Docker Compose, nginx routing |
| 1 | Done | Auth + workspaces + RBAC + super-admin seed |
| 2 | Done | Files — object-storage upload/download + file manager UI |
| 3 | Done | Documents — BlockNote editor + versioning |
| 4 | Done | Preview pipeline — PDF, images, Office, text/MD |
| 5 | Done | AI search and Q&A (cloud) |
| 6 | Done | Sharing, exports, permissions UI |
| 7 | In progress | Offline — PWA + Dexie + outbox + sync API |
| 8 | Planned | Ollama fallback (local AI) |
| 9 | Planned | Full AI provider compatibility — first-class adapters for Anthropic, OpenAI, Azure OpenAI, Google Gemini, Mistral, Groq, Together, OpenRouter, Cohere, vLLM, and any OpenAI-compatible endpoint; per-workspace provider selection; cost/usage telemetry |
| 10 | Planned | MCP (Model Context Protocol) — expose docx as an MCP server (documents, files, search, Q&A as tools/resources) so external agents and IDEs can read/write the corpus, plus inbound MCP-client support so docx's AI can call external MCP tools |
Contributions are welcome. Please see CONTRIBUTING.md for guidelines on how to get started.
If you discover a security vulnerability, do not open a public issue. Please refer to SECURITY.md for responsible disclosure instructions.
docx is licensed under the GNU Affero General Public License v3.0.
Copyright 2026 YavLabs / Yash.
Coming soon.