Skip to main content
Inkdown is a modern, cross-platform markdown note-taking application built with Tauri v2, React 19, and TypeScript. It follows a modular monorepo architecture with a platform-agnostic core and platform-specific adapters, enabling true cross-platform compatibility across Desktop, Web, and potentially Mobile platforms.

Monorepo Structure

Inkdown is organized as a Bun monorepo with clear separation between application layers, core business logic, and platform-specific implementations.
inkdown/
├── apps/                    # Platform-specific applications
   ├── desktop/            # Tauri desktop app
   └── mobile/             # React Native mobile app (future)
├── packages/               # Core packages
   ├── core/              # Platform-agnostic business logic
   ├── ui/                # Shared React components
   ├── plugins/           # Built-in plugins
   ├── plugin-api/        # Public plugin API
   ├── editor-webview/    # CodeMirror editor adapter
   ├── native-tauri/      # Tauri platform adapter
   ├── native-expo/       # Expo/React Native adapter
   ├── storage-tauri/     # Tauri storage implementation
   └── storage-mobile/    # Mobile storage implementation

Architecture Layers

The architecture consists of three primary layers:

1. Application Layer

Platform-specific entry points that bootstrap the application:
  • Desktop App (apps/desktop): Built with Tauri + React
  • Mobile App (apps/mobile): React Native with Expo (in development)
  • Web App (future): Browser-based version

2. Core Layer

Platform-agnostic packages that contain business logic:

@inkdown/core

Central business logic, managers, and Plugin API. The foundation of Inkdown.

@inkdown/ui

Shared React component library for design consistency across platforms.

@inkdown/plugins

Built-in plugins providing core functionality like live preview and word count.

@inkdown/plugin-api

Public API for community plugin developers.

3. Platform Adapter Layer

Platform-specific implementations that bridge core functionality to native capabilities:
  • @inkdown/editor-webview: CodeMirror 6 implementation (Desktop, Web)
  • Future: React Native editor adapters
  • @inkdown/native-tauri: File system, dialogs, clipboard via Tauri IPC
  • @inkdown/native-expo: React Native native modules
  • Future: Web browser APIs adapter
  • @inkdown/storage-tauri: File system-based storage for desktop
  • @inkdown/storage-mobile: AsyncStorage for mobile

Core System (@inkdown/core)

The Core package is the foundation of Inkdown, exposing the main App class and various specialized managers.

The App Class

App.ts
import { App } from '@inkdown/core';

// Create app instance with built-in plugins
const app = new App(builtInPlugins);

// Initialize all managers
await app.init();

// Access managers
const files = await app.workspace.getMarkdownFiles();
const activeEditor = app.editorRegistry.getActive();

Key Managers

The App class coordinates multiple specialized managers:
workspace
Workspace
Manages file operations (CRUD) and file events. Acts as the central file management system.
workspaceUI
WorkspaceUI
Manages UI state including tabs, views, and active file display.
pluginManager
PluginManager
Handles built-in plugin loading, enabling, and disabling.
communityPluginManager
CommunityPluginManager
Manages community plugin discovery, installation, and updates from GitHub.
configManager
ConfigManager
Persistent configuration storage (JSON files in app config directory).
themeManager
ThemeManager
Theme loading, switching, and CSS injection for built-in themes.
tabManager
TabManager
Handles tab management, restoration, and persistence.
commandManager
CommandManager
Central registry for all commands (plugin and built-in).
editorRegistry
EditorRegistry
Manages CodeMirror editor instances and provides access to active editor.
editorStateManager
EditorStateManager
Manages content of open files, dirty states, and auto-saving.
metadataCache
MetadataCache
Caches file metadata and frontmatter for quick access.
bookmarkManager
BookmarkManager
Manages bookmarked files and bookmark groups.
fontManager
FontManager
System font discovery and management.
syncManager
SyncManager
Handles workspace synchronization.

Initialization Flow

The application follows a specific initialization sequence to ensure all dependencies are loaded in the correct order:
App.ts (simplified)
async init(): Promise<void> {
    // 1. Initialize config manager (needed by other managers)
    await this.configManager.init();
    
    // 2. Load system fonts
    await this.fontManager.loadSystemFonts();
    
    // 3. Load and apply theme
    await this.loadTheme();
    
    // 4. Initialize community theme manager
    await this.communityThemeManager.init();
    
    // 5. Initialize sync manager
    await this.syncManager.init();
    
    // 6. Initialize bookmark manager
    await this.bookmarkManager.init();
    
    // 7. Initialize community plugin manager
    await this.communityPluginManager.init();
    await this.communityPluginManager.loadAllInstalledPlugins();
    
    // 8. Load all plugins (built-in + community)
    await this.loadPlugins();
    
    // 9. Initialize tab manager and restore tabs
    await this.tabManager.init();
}
The initialization order is critical. For example, configManager must be initialized before other managers that depend on configuration, and plugins must be loaded before tabs are restored.

Technology Stack

Desktop Framework

Tauri v2 - Rust backend with web frontend

Frontend

React 19 + TypeScript

Editor

CodeMirror 6 - Extensible code editor

Styling

CSS Variables - No Tailwind, theme-first approach

Package Manager

Bun - Fast JavaScript runtime and package manager

Build Tool

Vite - Next-generation frontend tooling

Linting

Biome - Fast formatter and linter

Mobile

React Native + Expo - Cross-platform mobile

Data Flow

Here’s how a typical file operation flows through the architecture:
The NativeBridge pattern allows the same core code to work across different platforms by swapping out the native implementation at runtime.

Benefits of This Architecture

Platform Agnostic

Write business logic once, run on Desktop, Web, and Mobile

Type Safe

Full TypeScript coverage ensures compile-time checking

Testable

Easy to mock platform implementations for unit testing

Extensible

Plugin system allows community extensions

Maintainable

Clear separation of concerns and single responsibility

Performance

No runtime overhead - abstractions are compile-time only

Plugin System

Learn about Inkdown’s plugin architecture and API

Workspace

Understand workspace management and file operations

Cross-Platform

Deep dive into the bridge pattern and platform adapters

Build a Plugin

Start building your first Inkdown plugin