Platform & Infrastructure
Complete guide to NkapBooks Platform & Infrastructure — offline-first architecture, cross-platform support, auto-updates, dark mode with ripple transitions, multi-language (i18n), and keyboard shortcuts.
14. Platform & Infrastructure
NkapBooks is built as a native desktop application using modern web technologies wrapped in a Rust-powered shell. This section covers the platform architecture, cross-platform support, automatic updates, theming, internationalization, and keyboard shortcuts that make NkapBooks a professional-grade desktop accounting tool.
| Component | Implementation | Description |
|---|---|---|
| Offline-First Architecture | SQLite / PostgreSQL + Tauri | All data stored locally with no internet dependency for core features |
| Cross-Platform Support | Tauri 2 (Rust) + Vue.js 3 | Native builds for Windows, macOS (Intel & Apple Silicon), and Linux |
| Auto-Updates | @tauri-apps/plugin-updater | Signed update bundles with download progress and user-controlled install |
| Dark Mode | View Transitions API + CSS | Full dark mode with animated circular ripple transition effect |
| Multi-Language (i18n) | Translation maps + reactive refs | Real-time language switching without page reload |
| Keyboard Shortcuts | Context-based Shortcuts class | Contextual keyboard shortcuts with modifier key support |
14.0 Technology Stack Overview
NkapBooks combines a modern frontend framework with a lightweight, secure native shell:
┌─────────────────────────────────────────────────────────────┐
│ NkapBooks Desktop App │
├─────────────────────────────────────────────────────────────┤
│ Frontend (Renderer Process) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Vue.js 3 + TypeScript + Tailwind CSS │ │
│ │ • Reactive UI with Composition API │ │
│ │ • Vue Router for SPA navigation │ │
│ │ • Pesa library for currency arithmetic │ │
│ │ • Luxon for date/time handling │ │
│ │ • CodeMirror for template editing │ │
│ │ • Feather Icons for iconography │ │
│ └───────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Backend (Tauri Rust Core) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Tauri 2 + Rust │ │
│ │ • SQLite / PostgreSQL database drivers │ │
│ │ • License verification & anti-tampering │ │
│ │ • PDF generation & printing │ │
│ │ • File system access & backup management │ │
│ │ • Auto-update download & installation │ │
│ │ • Stronghold for secure credential storage │ │
│ └───────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Tauri Plugins │
│ • plugin-dialog — Native file/folder dialogs │
│ • plugin-fs — File system read/write │
│ • plugin-os — OS detection & platform info │
│ • plugin-process — App relaunch & exit │
│ • plugin-shell — Open external URLs │
│ • plugin-stronghold — Encrypted key-value storage │
│ • plugin-updater — Signed auto-update system │
└─────────────────────────────────────────────────────────────┘
Why Tauri Instead of Electron?
| Aspect | Tauri 2 (NkapBooks) | Electron |
|---|---|---|
| Binary Size | ~10–15 MB | ~150+ MB |
| RAM Usage | ~50–100 MB | ~200–500 MB |
| Backend Language | Rust (memory-safe, fast) | Node.js |
| WebView | OS-native (WebView2/WebKit) | Bundled Chromium |
| Security | CSP enforced, Rust sandbox | Less constrained |
| Startup Time | Fast (native webview) | Slower (Chromium init) |
14.1 Offline-First Architecture
NkapBooks is designed to work entirely offline. No internet connection is required for any core accounting functionality.
Local Data Storage
All data is stored locally on your device:
| Storage | Technology | Description |
|---|---|---|
| Primary Database | SQLite | Default. Single .db file stored in the app data directory |
| Alternative Database | PostgreSQL | Optional. Local or network PostgreSQL server for multi-user setups |
| Configuration | Tauri Stronghold | Encrypted key-value store for app settings, credentials, and license data |
| Templates | Bundled files | Print templates and translation files shipped with the app binary |
What Works Offline
| Feature | Offline | Notes |
|---|---|---|
| All accounting operations | ✓ | Create, edit, submit, cancel documents |
| Sales & purchase workflows | ✓ | Invoices, quotes, payments |
| Inventory management | ✓ | Stock movements, adjustments, tracking |
| Point of Sale (POS) | ✓ | Full POS operation including payments |
| Reports & analytics | ✓ | All reports generated from local data |
| Print & PDF export | ✓ | Templates rendered locally |
| Import & export | ✓ | CSV/JSON import and export |
| User management | ✓ | Users, roles, permissions |
| Dark mode & language | ✓ | All UI preferences stored locally |
What Requires Internet
| Feature | Why Internet Is Needed |
|---|---|
| Auto-updates | Download new versions from the update server |
| Database backup | Upload backups to the NkapBooks server |
| Exchange rates | Fetch current currency exchange rates |
| License activation | Initial license key validation with the server |
| License validation | Periodic server-side license verification (for blocked licenses) |
Database Architecture
NkapBooks uses a schema-driven architecture where every document type is defined by a JSON schema. The database tables are automatically created and migrated based on these schemas.
SQLite (Default):
- Single file database — easy to backup, move, and restore
- No server process required
- Supports multiple databases (switch between companies)
- File stored in the OS-specific app data directory
PostgreSQL (Optional):
- Full ACID compliance with advanced query capabilities
- Suitable for multi-user network installations
- Configured during setup or from the Database Selector screen
Multi-Database Support
NkapBooks supports managing multiple companies through separate database files:
- Each company has its own database file (SQLite) or database instance (PostgreSQL)
- Switch between databases from the Database Selector screen
- Each database maintains its own:
- Chart of accounts
- Users and permissions
- Settings and preferences
- Transaction history
- Print templates
14.2 Cross-Platform Support
NkapBooks runs natively on all major desktop operating systems.
Supported Platforms
| Platform | Format | Minimum Version | Architecture |
|---|---|---|---|
| Windows | .msi installer, .exe (NSIS) | Windows 10 (64-bit) | x86_64 |
| macOS Intel | .dmg disk image | macOS 10.15 (Catalina) | x86_64 |
| macOS Apple Silicon | .dmg disk image | macOS 11 (Big Sur) | aarch64 (ARM) |
| Linux | .AppImage | Most modern distros | x86_64 |
| Linux | .deb package | Debian/Ubuntu based | x86_64 |
| Linux | .rpm package | Fedora/RHEL based | x86_64 |
Installation
Windows
- Download the
.msior.exeinstaller from the NkapBooks website - Run the installer — it will install to
Program Filesby default - Launch NkapBooks from the Start Menu or desktop shortcut
- Updates are installed passively (Windows NSIS
passiveinstall mode)
macOS
- Download the
.dmgfile for your architecture (Intel or Apple Silicon) - Open the
.dmgand drag NkapBooks to your Applications folder - On first launch, you may need to right-click → Open to bypass Gatekeeper
- The app runs natively — no Rosetta translation needed on Apple Silicon
Linux
- Download the package for your distribution:
- AppImage: Make executable (
chmod +x) and run directly — no installation needed .deb: Install withsudo dpkg -i nkapbooks_*.debor via your package manager.rpm: Install withsudo rpm -i nkapbooks_*.rpmor via DNF/Yum
- AppImage: Make executable (
- Launch from your application menu or command line
Platform-Specific Features
| Feature | Windows | macOS | Linux |
|---|---|---|---|
| Native window controls | Custom (frameless) | Custom (frameless) | Custom (frameless) |
| Auto-update install | Passive (NSIS) | Binary replace + relaunch | Binary replace + relaunch |
| System tray | ✓ | ✓ | ✓ |
| File dialogs | Native Win32 | Native Cocoa | Native GTK/Qt |
| PDF printing | ✓ | ✓ | ✓ |
| Keyboard shortcuts | Ctrl-based | Cmd-based | Ctrl-based |
Window Configuration
NkapBooks uses a frameless window with custom title bar controls:
| Property | Value |
|---|---|
| Default size | 1200 × 800 pixels |
| Minimum size | 800 × 600 pixels |
| Decorations | Custom (frameless) |
| Resizable | Yes |
| Center on launch | Yes |
Content Security Policy
The application enforces a strict CSP for security:
| Directive | Policy |
|---|---|
default-src | 'self' |
img-src | 'self' data: asset: blob: |
style-src | 'self' 'unsafe-inline' |
script-src | 'self' 'unsafe-eval' |
connect-src | 'self' ipc: https://nkapbooks.ddns.net |
14.3 Auto-Updates
NkapBooks includes an automatic update system powered by the Tauri Updater plugin. Updates are signed, downloaded in the background, and installed when the user chooses to restart.
Update Flow
The update system follows a state machine pattern:
┌──────┐ ┌──────────┐ ┌─────────────┐ ┌───────┐
│ idle │───▶│ checking │───▶│ downloading │───▶│ ready │
└──────┘ └──────────┘ └─────────────┘ └───────┘
│ │
▼ ▼
┌───────┐ ┌───────┐
│ error │ │ error │
└───────┘ └───────┘
How It Works
- Check: On app startup (and on database connection), NkapBooks checks the update endpoint for a newer version
- Download: If an update is available, it's automatically downloaded in the background
- The update notification widget appears at the bottom-right of the screen
- A progress bar shows the download percentage and bytes transferred
- Ready: When the download completes, the user is notified and can choose:
- Restart Now — Install the update and relaunch the app immediately
- Later — Dismiss the notification; the update will be installed when the app is closed
- Install: The update is applied:
- Windows: NSIS installer runs in passive mode (no user interaction needed)
- macOS/Linux: Binary is replaced on disk; the app relaunches
Update Notification UI
When an update is available and downloading, a notification widget appears:
| Stage | Title | Message |
|---|---|---|
| Checking | Checking for updates… | Looking for a newer version… |
| Downloading | Updating to vX.Y.Z… | 5.2 MB of 12.8 MB (40%) |
| Ready | Update ready! | vX.Y.Z has been downloaded. Restart to apply the update. |
| Error | Update failed | Something went wrong during the update. |
The notification includes a progress bar with four stages:
- ✓ Checking for updates
- ✓ Downloading update
- ✓ Installing update
- ○ Ready to restart
Update Stages
| Stage | Visual | Description |
|---|---|---|
| Completed | ✓ Green checkmark | Stage finished successfully |
| Current | ◌ Spinning indicator | Stage currently in progress |
| Error | ✗ Red X | Stage failed |
| Pending | ● Gray dot | Stage not yet started |
Deduplication
The update system tracks the last downloaded version to prevent re-downloading the same update when the check runs again (e.g., on database reconnection after the initial startup check already completed).
Signed Updates
All update bundles are signed with a public key embedded in the application. The update endpoint provides signed manifests that the Tauri updater verifies before applying:
| Configuration | Value |
|---|---|
| Update endpoint | https://nkapbooks.ddns.net/api/updates/{target}/{arch}/{current_version} |
| Signature algorithm | Ed25519 (minisign) |
| Windows install mode | Passive (no user prompts) |
Close-Time Install
If the user dismisses the update notification ("Later"), the downloaded update is still applied when the app window is closed. This ensures updates are eventually installed even if the user never clicks "Restart Now":
- User clicks Later → notification is dismissed
- User continues working normally
- When the user closes the app, the pending install callback runs
- The update is installed silently before the process exits
Update Availability
| Tier | Auto-Updates |
|---|---|
| Community (Free Trial) | ✗ |
| Pro | ✓ |
| Enterprise | ✓ |
14.4 Dark Mode
NkapBooks includes a complete dark mode implementation that covers every surface in the application — pages, sidebar, forms, charts, POS interface, and dialogs.
Toggling Dark Mode
Dark mode can be toggled from:
- Sidebar toggle — Click the moon/sun icon at the bottom of the sidebar
- System Settings — The
darkModefield in SystemSettings stores the preference
Ripple Transition Effect
NkapBooks features a visually polished circular ripple animation when switching between light and dark mode:
┌───────────────────────────────────────┐
│ │
│ ●──────────▶ Ripple expands │
│ / from click │
│ / radius │
│ / │
│ Click │
│ Point │
│ │
└───────────────────────────────────────┘
How the animation works:
- The toggle captures the click position (x, y coordinates)
- It calculates the maximum radius needed to cover the entire screen from that point
- If the browser supports the View Transitions API:
- A
::view-transition-new(root)pseudo-element animates aclip-path: circle()from 0px to the max radius - Duration: 800ms with
ease-outeasing
- A
- Fallback (if View Transitions API is unavailable):
- A CSS overlay div is created with
position: fixedcovering the viewport - The overlay animates its
clip-pathfrom 0 to the max radius - The actual theme change is applied at the midpoint (350ms) of the animation
- The overlay is removed after the animation completes (800ms)
- A CSS overlay div is created with
- The preference is persisted to
SystemSettings.darkModein the database
Dark Mode Coverage
| Area | Support | Implementation |
|---|---|---|
| All pages | ✓ | Tailwind dark: variant classes |
| Sidebar & navigation | ✓ | Dark background, light text |
| Forms & inputs | ✓ | Dark backgrounds, bordered inputs |
| List views | ✓ | Alternating dark row colors |
| Dashboard charts | ✓ | Chart colors adapt to theme |
| POS interface | ✓ | Full dark POS checkout screen |
| Dialogs & modals | ✓ | Dark overlays and content |
| Print preview | Screen only | Prints always use template colors |
| Custom scrollbars | ✓ | Dark scrollbar thumb and track |
Persistence
Dark mode preference is stored in two places for reliability:
- SystemSettings.darkMode — Stored in the database (primary, when DB is connected)
- darkModeRef — A reactive Vue ref used as fallback when the database is not available (e.g., on the Database Selector screen)
When the app starts, it reads the stored preference and applies it before the first render to prevent a flash of the wrong theme.
14.5 Multi-Language (i18n)
NkapBooks supports multiple languages with real-time language switching — no page reload required.
Desktop App Languages
The desktop application currently supports:
| Language | Code | Direction |
|---|---|---|
| English | en | LTR |
| French | fr | LTR |
translations/ directory. The desktop app bundles translation files as Tauri resources. The architecture supports RTL languages (like Arabic) through the languageDirectionKey injection.How Language Switching Works
Language switching in NkapBooks is instantaneous — no page reload needed:
┌──────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ User selects │───▶│ Fetch translation │───▶│ Update reactive │
│ new language │ │ map from file │ │ refs & UI │
└──────────────┘ └──────────────────┘ └──────────────────┘
- User selects a language in Settings (or during Setup Wizard)
- The app fetches the translation map for that language code
- The translation map is applied to the translation string system (
ttagged template literal) - Schema labels are re-translated in memory via
translateSchemaMap() - The reactive language ref (
systemLanguageRef) updates, triggering UI re-renders - The preference is saved to the config store
Translation System
NkapBooks uses a tagged template literal system for translations:
// In Vue components and TypeScript code:
const message = t`Hello, welcome to NkapBooks`;
const greeting = t`${count} invoices created`;
The t function:
- Looks up the string in the current language map
- Returns the translated string if found
- Falls back to the original English string if no translation exists
- Supports interpolation with
${variable}placeholders
Translation Files
Translation files are CSV files stored in the translations/ directory:
| File | Language |
|---|---|
translations/fr.csv | French |
Each CSV file contains two columns:
- Column 1: English source string
- Column 2: Translated string
These files are bundled as Tauri resources and deployed with the application binary.
Schema Translation
In addition to UI strings, NkapBooks translates schema labels (field names, document type names, option labels):
- When a non-English language is selected, the schema map is translated in memory
- All form labels, list column headers, and dropdown options show translated text
- When switching back to English, translations are cleared and original labels are restored
Website/Server Internationalization
The NkapBooks documentation website supports:
| Language | Code |
|---|---|
| English | en |
| French | fr |
The website uses Nuxt i18n with JSON locale files for full page translation support. The i18n framework allows easy addition of new languages by creating additional locale files.
Language Direction (RTL/LTR)
NkapBooks includes infrastructure for right-to-left (RTL) language support:
- A Vue
InjectionKey(languageDirectionKey) provides reactive direction state - The Tailwind CSS configuration includes
tailwindcss-rtlfor RTL utility classes - When an RTL language is activated, the entire UI mirrors automatically
14.6 Keyboard Shortcuts
NkapBooks includes a context-based keyboard shortcut system that enables efficient, keyboard-driven workflows throughout the application.
Shortcut System Architecture
The shortcut system is built on a context-based architecture:
┌─────────────────────────────────────────────────────────────┐
│ Shortcuts Class │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Context A │ │ Context B │ │ Context C │ │
│ │ (Sidebar) │ │ (Form) │ │ (Modal) │ │
│ │ │ │ │ │ │ │
│ │ Ctrl+S │ │ Ctrl+S │ │ Escape │ │
│ │ Ctrl+N │ │ Ctrl+Enter │ │ Enter │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Evaluation: Most recent context wins (stack-based) │
└─────────────────────────────────────────────────────────────┘
Key concepts:
- Context: Each UI component registers its shortcuts with a unique context (typically the component instance itself)
- Stacking: When multiple contexts define the same shortcut, the most recently registered context wins
- Propagation: A shortcut can optionally propagate to earlier contexts if
propagate: trueis set - Cleanup: When a component is destroyed, its context is removed and shortcuts are unregistered
Modifier Keys
The shortcut system supports the following modifier keys:
| Modifier | Windows/Linux | macOS |
|---|---|---|
ctrl | Ctrl | Ctrl |
meta | Win | Cmd (⌘) |
alt | Alt | Option (⌥) |
shift | Shift | Shift |
pmod | Ctrl | Cmd (⌘) |
The pmod (platform modifier) automatically resolves to Ctrl on Windows/Linux and Cmd on macOS, ensuring consistent behavior across platforms.
Global Shortcuts
These shortcuts work from anywhere in the application:
| Shortcut | Action | Description |
|---|---|---|
Ctrl+K / Cmd+K | Quick Search | Open the command palette / quick search |
Ctrl+N / Cmd+N | New Document | Create a new document (context-dependent) |
Navigation Shortcuts
| Shortcut | Action |
|---|---|
| Sidebar items | Click sidebar items for quick module navigation |
| Quick Search | Type to search documents, pages, and actions |
Document Form Shortcuts
When editing a document (invoice, payment, journal entry, etc.):
| Shortcut | Action |
|---|---|
Ctrl+S / Cmd+S | Save the current document |
Ctrl+Enter / Cmd+Enter | Submit the document |
Escape | Close the current form or modal |
POS Shortcuts
The Point of Sale module supports full keyboard-driven checkout:
| Shortcut | Action |
|---|---|
| Barcode scan | Add item by barcode |
| Number keys | Enter quantities |
Enter | Confirm payment |
Escape | Cancel / go back |
Shortcut Registration API
Components register shortcuts using the Shortcuts class:
// Register a shortcut
shortcuts.pmod.set(context, ['KeyS'], () => saveDocument());
// Register with Shift modifier
shortcuts.pmod.shift.set(context, ['KeyS'], () => saveAsNew());
// Register Escape (no modifiers)
shortcuts.set(context, ['Escape'], () => closeForm());
// Clean up when component unmounts
shortcuts.delete(context);
Developer Tools Restrictions
In production builds, certain keyboard shortcuts are disabled for security:
| Blocked Shortcut | Reason |
|---|---|
F12 | Prevent DevTools access |
Ctrl+Shift+I / Cmd+Option+I | Prevent DevTools access |
Ctrl+Shift+J / Cmd+Option+J | Prevent console access |
Ctrl+U / Cmd+U | Prevent view-source access |
| Right-click context menu | Disabled in production |
14.7 Application Lifecycle
NkapBooks follows a defined lifecycle from launch to database connection:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ App Launch │───▶│ Config Init │───▶│ Database │───▶│ Desk Mode │
│ │ │ │ │ Selector │ │ │
│ • Load Tauri│ │ • Language │ │ │ │ • Dashboard │
│ • Init Vue │ │ • Dark Mode │ │ OR │ │ • Sidebar │
│ • License │ │ • Config │ │ │ │ • All │
│ Service │ │ from Store│ │ Setup │ │ Features │
│ │ │ │ │ Wizard │ │ │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
Startup Sequence
- Tauri Initialization: The Rust backend starts, creates the native window (1200×800, frameless, centered)
- Config Loading: The app reads configuration from the Tauri Stronghold store (language, dark mode preference)
- Language Setup: If a non-English language is configured, the translation map is loaded
- License Initialization: The license service initializes (non-blocking, runs in background)
- Screen Routing:
- If no database exists → Setup Wizard
- If databases exist → Database Selector (or auto-connect to last used database)
- After database connection → Login (if authentication is enabled) → Desk Mode
- Post-Connection Setup:
- License entity tracking starts
- Backup manager starts (checks every hour)
- Update check is scheduled
- Schema translations are applied
Security Features
| Feature | Implementation |
|---|---|
| Custom window | Frameless window with custom title bar (no native chrome manipulation) |
| CSP enforcement | Strict Content Security Policy prevents XSS and injection |
| Frozen prototype | Option to freeze Object.prototype to prevent prototype pollution (configurable) |
| Global Tauri | withGlobalTauri: true enables IPC communication between frontend and backend |
| DevTools blocked | F12, Ctrl+Shift+I, right-click disabled in production builds |
| Stronghold storage | Encrypted storage for sensitive configuration (credentials, license data) |
14.8 Bundled Resources
NkapBooks ships with bundled resources that are deployed alongside the application binary:
| Resource | Directory | Description |
|---|---|---|
| Print Templates | templates/ | Built-in print templates for all document types |
| Translation Files | translations/ | Language CSV files (currently French) |
| App Icons | icons/ | Application icons in multiple sizes and formats |
These resources are configured in the Tauri bundle settings and are available to both the Rust backend and the frontend renderer through the asset protocol.
Summary
| Feature | Status | Notes |
|---|---|---|
| Offline-first | ✓ | All core features work without internet |
| Windows support | ✓ | Windows 10+ (64-bit), .msi / .exe |
| macOS support | ✓ | macOS 10.15+, Intel & Apple Silicon |
| Linux support | ✓ | AppImage, .deb, .rpm |
| Auto-updates | ✓ | Pro/Enterprise only, signed bundles |
| Dark mode | ✓ | Full coverage with ripple transition |
| Multi-language | ✓ | English + French, extensible framework |
| Keyboard shortcuts | ✓ | Context-based, cross-platform modifiers |
| RTL support | ◐ | Infrastructure ready, pending full implementation |
| Additional languages | ◐ | Framework supports it, community contributions welcome |
NkapBooks delivers a native desktop experience that's fast, secure, and works reliably with or without an internet connection. The Tauri 2 + Vue.js 3 architecture ensures small binary sizes, low resource usage, and strong security — all while providing a modern, polished user interface with dark mode, keyboard shortcuts, and multi-language support.