Self-hosted collaborative writing platform for novelists & worldbuilders
Your words, your server, your control.
Quick Start β’ Features β’ Status β’ Architecture β’ Development β’ Contributing
# Pull and run with Docker
docker run -d \
--name inkweld \
-p 8333:8333 \
-e HOST=0.0.0.0 \
-e SESSION_SECRET=$(openssl rand -hex 32) \
-e WEBAUTHN_RP_ID=your-domain.com \
-e ALLOWED_ORIGINS=https://your-domain.com \
-v inkweld_data:/data \
ghcr.io/bobbyquantum/inkweld:latestThen open http://localhost:8333 in your browser.
π Full deployment guide β
Write together, or alone. Work entirely in your browser with no server, keep writing across your devices through your own cloud storage, or connect to an Inkweld server for real-time collaboration.
Build your world as you write. Create characters, locations, factions β whatever your story needs. Link them together with relationships, and reference them directly in your prose with @mentions.
Own your data. Many hosting options are supported. Native sync server binaries (thanks to Bun), self contained Docker images, and support for Cloudflare free tier deployment.
Export when you're ready. PDF, EPUB, Markdown, HTML. Configurable publish plans let you publish multiple asset variants from a single project.
| Browser | Cloud Sync | Realtime Sync | |
|---|---|---|---|
| Where your writing lives | This browser only | Your own Dropbox or Nextcloud | An Inkweld server |
| Account needed | None | Your cloud provider account | Inkweld account on that server |
| Works offline | β | β (syncs when back online) | β (syncs when back online) |
| Use on several devices | β¬ | β | β |
| Real-time co-editing, presence, cursors | β¬ | β¬ | β |
| Share projects with collaborators | β¬ | β¬ | β |
| Version history & snapshots | β local | β synced | β synced |
| Media library & covers | β | β | β |
| Publishing (PDF, EPUB, HTMLβ¦) | β | β | β |
| AI features, MCP API keys | β¬ | β¬ | β (if the server enables them) |
| Backup | Export archive | Continuous mirror + export archive | Server + export archive |
| Move to another mode later | β | β | β |
| Cost to run | Free | Free (your storage quota) | Self-host, or a hosted server |
- Can be deployed and used now, however, until numbered releases are started, there are no guarantees that data migration paths will be available.
- Not recommended for production use. If you do use it in this way, always back up your work before upgrading, and be aware, manual fixing of exports might be needed to move to newer versions.
- At some point closer to the first numbered release, the drizzle migrations will be squashed into a single V1 migration, meaning existing databases will need to be reset or manually fixed.
Status: β
Done | π¨ In Progress | β¬ Planned
Priority: π₯ High | π‘ Medium | π’ Nice to have
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Home screen with project cards | Browse and manage all projects |
| β | π₯ | Drag-and-drop project tree | Organize documents, folders, elements |
| β | π₯ | Folder hierarchy | Unlimited nesting depth |
| β | π₯ | Project archives (import/export) | Backup and restore entire projects |
| β | π‘ | Project renaming | |
| β | π‘ | Context menus | Right-click actions on tree items |
| β | π‘ | Home screen search | Filter projects by name |
| β | π‘ | Project templates | Start new projects from templates |
| β | π’ | Project duplication | Export & re-import with new name |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Quick file open (Ctrl/Cmd + P) | |
| β | π₯ | Find in document (Ctrl/Cmd + F) | |
| β | π₯ | Mobile-responsive design | |
| β | π₯ | Project-wide search (Ctrl/Cmd + Shift + F) | Full-text search across all documents |
| β | π₯ | Find and replace in document | |
| β | π‘ | Tag filtering in search | Filter search results by tags, element types, relationships, and worldbuilding schemas |
| β | π‘ | Browse elements by tag | Project search browse mode filters by tag; open from the Tags settings tab or the search dialog |
| β | π‘ | Breadcrumbs | Folder path shown above each editor (document, folder, worldbuilding, canvas, relationship chart, timeline); toggle in user settings |
| β | π‘ | Pinning | Pin elements to Home tab and sidebar for quick access |
| β | π’ | Recent files list | Tracks last 10 files per project |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Full keyboard shortcut support | |
| β | π₯ | Image insertion | |
| β | π‘ | Zen mode (distraction-free) | |
| β | π‘ | Document snapshots | Version history for documents |
| β | π‘ | Comments/Annotations | Inline feedback with threaded replies and resolution |
| β | π’ | Writing statistics | Daily word counts and session stats across projects, shown on your profile |
| β | π₯ | Scenes & notes | Prose documents are created as Scenes (manuscript, with synopsis/status/word target/story date) or Notes (research, front matter); POV and location as relationships |
| β | π₯ | Corkboard & outline | Open a folder to see its scenes as index cards (drag to reorder, edit synopsis and status in place) or as an outline table with word counts and totals |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Custom element templates | |
| β | π₯ | Relationships with backlinks | Bidirectional connections |
| β | π₯ | Element references (@mentions) | |
| β | π‘ | Tags on documents & elements | Categorize and organize content |
| β | π‘ | Tags on images | Extend tagging to media library |
| β | π‘ | Custom calendar systems | Fantasy calendars with custom months/years |
| β | π‘ | Random generators | Names, places and writing prompts; the worldbuilding templates ship five, bound to Character, Settlement, Building and Geographic Feature for a dice by the name field |
| β¬ | π’ | Language/Conlang tools | Vocabulary lists, alphabets |
| β¬ | π’ | Secrets/GM notes | Per-element spoiler hiding from some collaborators |
| β¬ | π’ | Reference images panel | Side-by-side images while writing |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Local-first image storage | Saved to IndexedDB, syncs to server |
| β | π₯ | Inline image embedding | Paste/drop images into documents |
| β | π‘ | Cover images | Project and element covers |
| β | π‘ | Category filtering | Filter by generated, inline, published, etc. |
| β | π‘ | Server sync | Bi-directional sync when connected |
| β | π‘ | Image search/filtering | Search within media library |
| β¬ | π’ | Bulk image operations | Multi-select, batch delete |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Real-time co-editing | Multiple users editing same document |
| β | π₯ | CRDT conflict resolution | Yjs-based, no manual merge needed |
| β | π₯ | Presence indicators | See who's viewing/editing |
| β | π₯ | Collaborative cursors | See other users' cursor positions |
| β | π‘ | Project sharing | Invite collaborators with role-based access |
| β | π‘ | Local-first architecture | Works offline, syncs when connected |
| β | π‘ | Migrate local to server | Start offline, add sync server later |
| β | π’ | Activity feed | Per-project feed of recent changes by collaborators |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Relationship chart element | New element type for visualizing connections |
| β | π₯ | Graph layout | Force-directed network visualization |
| β | π‘ | Hierarchy layout | Tree-style parent/child visualization |
| β | π‘ | Relationship type filtering | Choose which relationship types to include |
| β | π‘ | Element type filtering | Choose which element types to include |
| β | π’ | Export chart as image | PNG/SVG export |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Canvas element type | Infinite freeform canvas with layers |
| β | π₯ | Drawing tools | Freehand draw, line, shapes (rect, ellipse, arrow), text, pin |
| β | π₯ | Image placement | Add and position images on the canvas |
| β | π‘ | Layers | Add, rename, duplicate, delete; visibility & lock toggles |
| β | π‘ | Pan and zoom | Navigate large canvases smoothly |
| β | π‘ | Export as PNG | Standard and high-resolution export |
| β | π‘ | Shape fills & stroke palette | Per-object color editing with the full color picker; gradient fills for shapes |
| β | π’ | Pin-to-element linking | Connect canvas pins to worldbuilding elements |
| β | π‘ | Canvas size & crop frames | Page bounds plus named crop frames; per-frame PNG/SVG export and set-as-project-cover |
| β | π‘ | Region pen tool | Click-to-place vertices, close the loop into a polygon β trace map regions |
| β | π’ | Collapsible sidebar sections | Layers, Objects, Pins and Frames each collapse independently; state remembered |
| β | π’ | Unified colour chooser | Canvas uses the worldbuilding appearance picker: swatches, full picker, gradient mode |
| β | π’ | Canvas guided tour | Auto-offered on first open; replay from the sidebar help button |
| β | π‘ | Phone layout & touch | Sidebar drawer on narrow screens, long-press context menu, tap-to-name linked regions, finger-sized handles |
| β¬ | π’ | SVG import | Place an SVG as an image; later, import Inkscape files as editable objects |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Map background images | Flag any canvas image as a non-editable backdrop; multiple per layer for tiling large maps |
| β | π₯ | Location pins | Double-click (or double-tap) a linked pin to open its element |
| β | π₯ | Pin-to-element linking | canvas-pin relationship type; links cleaned up when elements are deleted |
| β | π‘ | Multiple map layers | Per-layer backgrounds blended with layer visibility/opacity; "Map" preset in the new-element dialog |
| β | π‘ | Linked regions | Shapes linked to elements: click-to-open areas; discontinuous regions via shared links |
| β | π‘ | Pins as annotations | Pins live on an always-on overlay, independent of drawing layers |
| β¬ | π’ | AI map restyling | Rough-colour a layer, restyle it via AI image generation (political, terrain, parchmentβ¦) |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Timeline element type | New element for chronological visualization |
| β | π₯ | Time systems | Define custom calendars and date formats (see Custom calendar systems) |
| β | π₯ | Timeline fields on elements | Add dates to worldbuilding elements |
| β | π₯ | Auto-build from elements | Generate timeline from element date fields |
| β | π‘ | Events system | Add events directly to timeline with element references |
| β | π‘ | Multiple timelines | Parallel timelines for different storylines/regions |
| β | π’ | Era/period grouping | Visual spans for ages, reigns, wars |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | EPUB export | Industry-standard e-book format |
| β | π₯ | PDF export (via Typst) | Print-ready documents |
| β | π₯ | Markdown export | Plain text with formatting |
| β | π₯ | HTML export | Single-file web output |
| β | π‘ | Publish plans | Save export configurations for reuse; a folder in a plan publishes its contents in tree order, so reordering scenes needs no plan changes |
| β | π‘ | Typography customization | Per-plan style editor with 6 presets and full per-section overrides (font, size, weight, alignment, color, indent, page breaks) |
| β¬ | π’ | Presentation mode | Read-only, docs-site-like rendering of a whole project |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Password auth | Strong client-side requirements. Disabled by default in v0.2+ (passwordless-first per NIST SP 800-63B Rev. 4) β set PASSWORD_LOGIN_ENABLED=true to opt in |
| β | π₯ | Passkeys (WebAuthn) | Passwordless sign-in with device biometrics or hardware security keys |
| β | π₯ | Magic-link passkey recovery | Email-based recovery to enrol a new passkey if the original device is lost (requires EMAIL_RECOVERY_ENABLED=true + SMTP) |
| β | π₯ | CSRF protection | |
| β | π‘ | User approval system | |
| β | π₯ | Password reset via email | Forgot/reset flow with emailed token links (only when password login is enabled) |
| β | π‘ | GitHub OAuth | Optional GitHub sign-in |
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π₯ | Docker with multi-stage builds | |
| β | π₯ | Docker Compose | |
| β | π₯ | CI/CD with automated testing | |
| β | π‘ | Auto-publish to GHCR | |
| β | π‘ | Admin dashboard | User management, AI settings, announcements |
| β | π‘ | Production logging | |
| β¬ | π’ | Monitoring setup |
| Status | Priority | Item | Notes |
|---|---|---|---|
| β | π‘ | Features marketing page | /features landing page for website |
| β | π‘ | Import/archive docs | User guide for exporting, importing, and backing up projects |
| β | π’ | Desktop app docs | Electron app installation guide |
All AI features require admin configuration and are disabled by default. See AI Stance.
| Status | Priority | Feature | Notes |
|---|---|---|---|
| β | π‘ | AI image generation | OpenAI, OpenRouter, Fal.ai, Stable Diffusion |
| β | π‘ | Image model profiles | Admin-configured presets per provider/model |
| β | π‘ | Worldbuilding context for images | Include element data in generation prompts |
| β | π‘ | Reference images | Use existing images as style/composition reference |
| β | π‘ | Prompt optimization | AI-powered prompt rewriting for better results |
| β | π‘ | AI grammar/lint suggestions | Per-paragraph grammar/style suggestions with accept/reject (OpenAI) |
| β¬ | π’ | AI writing assistance | Suggestions, continuations, rephrasing |
Inkweld has two parts that can run together or separately, plus an optional Cloud Sync mode that needs neither an Inkweld server nor an account:
The client is where you write. It's a full web app that works offline.
The server enables real-time collaboration and sharing. Run it on your own hardware or a VPS. Without it, you can still use Inkweld locally β documents save to your browser.
Cloud Sync mirrors your projects to your own Dropbox or Nextcloud straight from the browser, so you can move between devices without running a server.
git clone https://github.com/bobbyquantum/inkweld.git
cd inkweld
bun install
cp .env.example .env
npm run devFrontend runs on :4200, backend on :8333.
| Task | Command |
|---|---|
| Dev servers | npm run dev |
| Run tests | npm test |
| Build | npm run build |
| Docker (local) | npm run docker:prod |
π Developer docs β
Inkweld is self-hosted β the content on your server doesn't leave your server and any browsers you connect with.
The exception to this are if you use external AI services. There's an AI Kill Switch that disables all AI features, and AI is disabled by default.
If you choose to enable AI features, you can configure both self hosted services and external services, and uses include image generation based on content, and grammar suggestions.
You should be aware when using external AI services that content could be used to train, and in the case of some providers, even be published or sold as training data sets.
Always check the provider policies when configuring AI features.
Disclosure: GitHub Copilot and Claude Code is used in development (a lot). The desktop background image in the main app is currently AI-generated. Some of the examples in the docs use generative AI for images and text.
The main logo is not AI, this was hand-drawn in Inkscape as SVG.
Check out the Status and Feature Roadmap for areas that need work.
- π Report bugs
- π‘ Request features
- π§ Submit PRs
MIT β see LICENSE.
