Notes List
Compact mode
Show notes in a denser layout without preview
{ compactNotes = !compactNotes; saveGeneralSettings(); }}>
Show dates
Show the date next to each note in the list
{ showNoteDates = !showNoteDates; saveGeneralSettings(); }}>
Notebooks
Sort order
Alphabetical (default) or manual. Drag notebooks above/below each other to reorder.
{ $notebookSortMode = 'alphabetical'; }}>Alphabetical
{ $notebookSortMode = 'manual'; }}>Manual
Time Format
{ timeFormat = 'relative'; saveGeneralSettings(); }}>Relative
{ timeFormat = '12h'; saveGeneralSettings(); }}>12-hour
{ timeFormat = '24h'; saveGeneralSettings(); }}>24-hour
{#if isMobile}
Vault
Current: {$appConfig?.active_vault?.split('/').pop() ?? 'Unknown'}
{ $showSettings = false; $vaultReady = false; }}>
Switch Vault
{/if}
{#if !isMobile}
Performance
GPU Acceleration
Use hardware acceleration for rendering (requires restart)
{ gpuAcceleration = !gpuAcceleration; saveGeneralSettings(); }}>
System
Start at system startup
Launch HelixNotes when your computer starts
{ autostart = !autostart; saveGeneralSettings(); }}>
Show in system tray
Show an icon in the notification area (requires restart)
{ showTrayIcon = !showTrayIcon; if (!showTrayIcon) closeToTray = false; saveGeneralSettings(); }}>
{#if showTrayIcon}
Close to tray
Minimize to tray instead of quitting when closing the window (requires restart)
{ closeToTray = !closeToTray; saveGeneralSettings(); }}>
{/if}
{/if}
Title
Hide title in note body
Hide the first heading when it matches the note title
{ hideTitleInBody = !hideTitleInBody; saveGeneralSettings(); }}>
{#if !isMobile}
Show line numbers
Display line numbers in the markdown source editor
{ showLineNumbers = !showLineNumbers; saveGeneralSettings(); }}>
{/if}
Open notes in View Mode
Notes open as read-only by default. Click the eye icon to switch to editing.
{ defaultViewMode = !defaultViewMode; saveGeneralSettings(); }}>
Restore last session on launch
Reopen the note and folder you were last using, instead of All Notes.
{ restoreLastSession = !restoreLastSession; saveGeneralSettings(); }}>
Wiki Links & Graph
Enable wiki links
Link notes with [[Note Title]] syntax and visualize connections in a graph view
{ enableWikiLinks = !enableWikiLinks; saveGeneralSettings(); }}>
{#if !isMobile}
PDF Preview
Inline PDF preview
Render embedded PDF files as inline previews inside notes
{ pdfPreview = !pdfPreview; saveGeneralSettings(); }}>
{#if pdfPreview}
PDF Height
{#each pdfHeightPresets as preset}
{ pdfHeight = preset.value; saveGeneralSettings(); }}
>
{preset.label}
{preset.value}px
{/each}
Default height for PDF previews in notes
{/if}
{/if}
Theme
{#each themePresets as preset}
{ $theme = preset.id; setTheme(preset.id); }}
title={preset.label}
>
{preset.label}
{/each}
Accent Color
{#each accentPresets as preset}
selectAccent(preset)}
title={preset.name}
>
{preset.name}
{/each}
Font Size
{#each fontSizePresets as preset}
selectFontSize(preset.size)}
>
{preset.label}
{preset.size}px
{/each}
{#if !isMobile}
Interface Scale
{#each uiScalePresets as preset}
selectUiScale(preset.value)}
>
{preset.label}
{/each}
Zooms the whole app: every panel, menu, and the editor. Use Default (100%) to reset.
{/if}
Line Height
{#each lineHeightPresets as preset}
selectLineHeight(preset.value)}
>
{preset.label}
{preset.value}
{/each}
Font
{#each fontFamilyPresets as preset}
selectFontFamily(preset)}
>
Aa
{preset.name}
{/each}
Automatic Backup
Enable automatic backup
{ if ($appConfig) { $appConfig = { ...$appConfig, backup_enabled: !$appConfig.backup_enabled }; saveBackupSettings(); } }}>
Backup frequency
{#each [{ value: '1h', label: '1 hour' }, { value: '6h', label: '6 hours' }, { value: '12h', label: '12 hours' }, { value: '24h', label: '24 hours' }] as opt}
{ if ($appConfig) { $appConfig = { ...$appConfig, backup_frequency: opt.value }; saveBackupSettings(); } }}>{opt.label}
{/each}
Maximum backups
{#each [5, 10, 20, 50] as count}
{ if ($appConfig) { $appConfig = { ...$appConfig, backup_max_count: count }; saveBackupSettings(); } }}>{count}
{/each}
Include attachments
Include images and files in backups (increases size significantly)
{ if ($appConfig) { $appConfig = { ...$appConfig, backup_include_attachments: !$appConfig.backup_include_attachments }; saveBackupSettings(); } }}>
{#if !isMobile}
{$appConfig?.backup_location ? 'Change backup folder' : 'Select backup folder'}
{#if $appConfig?.backup_location}
{$appConfig.backup_location}
{/if}
{/if}
{#if backupLoading}
Backing up...
{:else}
Backup now
{/if}
{#if $appConfig?.last_backup_time}
Last backup: {formatBackupDate($appConfig.last_backup_time)}
{:else}
No backups yet
{/if}
{#if backupMessage}
{#if backupMessage.type === 'success'}
{:else}
{/if}
{backupMessage.text}
{/if}
Restore Backup
{#if backups.length === 0}
No backups found
{:else}
{#each backups as entry}
{formatBackupDate(entry.created)}
{formatBackupSize(entry.size)}
restoreConfirm = entry}>
handleDeleteBackup(entry)}>
{/each}
{/if}
{#if restoreConfirm}
restoreConfirm = null}>
e.stopPropagation()}>
Restore Backup?
This will replace all notes in your vault with the backup from {formatBackupDate(restoreConfirm.created)} . This action cannot be undone.
restoreConfirm = null}>Cancel
handleRestore(restoreConfirm!)}>Restore
{/if}
Import from Obsidian
Convert Obsidian wiki-links (![[image.png]], [[note]]) to standard markdown links across all notes in the current vault. This expects that you have opened an Obsidian vault directory directly as your HelixNotes vault.
This modifies files in place. Make a backup before running!
{#if importLoading}
Importing...
{:else}
Import Obsidian Vault
{/if}
{#if importResult}
Converted {importResult.links_converted} links across {importResult.files_converted} files
{/if}
{#if importError}
{importError}
{/if}
Provider
{ if (!aiProvider) return; aiProvider = null; aiTestMessage = null; saveAiSettings(); }}>Disabled
{ if (aiProvider === 'ollama') return; aiProvider = 'ollama'; aiModel = 'gemma3:4b'; aiTestMessage = null; saveAiSettings(); }}>Ollama
{ if (aiProvider === 'anthropic') return; aiProvider = 'anthropic'; aiModel = 'claude-sonnet-4-6'; aiTestMessage = null; saveAiSettings(); }}>Anthropic
{ if (aiProvider === 'openai') return; aiProvider = 'openai'; aiModel = 'gpt-5.5'; aiTestMessage = null; saveAiSettings(); }}>OpenAI
{ if (aiProvider === 'openai_compatible') return; aiProvider = 'openai_compatible'; aiModel = ''; aiTestMessage = null; saveAiSettings(); }}>Compatible
{#if aiProvider}
{#if aiProvider === 'ollama' || aiProvider === 'openai_compatible'}
Your data stays on your device. No text is sent to any external server.
{:else}
Your selected text and note content will be sent to {aiProvider === 'openai' ? 'OpenAI' : 'Anthropic'} servers for processing.
{/if}
{#if aiProvider === 'ollama'}
{:else if aiProvider === 'openai_compatible'}
{:else}
{/if}
Model
{#if aiProvider === 'ollama' || aiProvider === 'openai_compatible'}
{ aiModel = (e.target as HTMLInputElement).value; }}
onblur={saveAiSettings}
/>
{aiProvider === 'ollama' ? 'Enter the model name as shown by ollama list' : 'Enter the model name as required by your server'}
{:else}
{#each aiModels as m}
{ aiModel = m.value; saveAiSettings(); }}
>
{m.label}
{m.desc}
{/each}
{/if}
Writing Style
Describe your preferred tone, style, or personality. This will be applied to all AI actions.
Connection
{#if aiTestLoading}
Testing...
{:else}
Test Connection
{/if}
{#if aiTestMessage}
{#if aiTestMessage.type === 'success'}
{:else}
{/if}
{aiTestMessage.text}
{/if}
Usage
{#if isMobile}
Use the AI button in the toolbar or header to access AI writing tools: improve, fix grammar, rewrite, summarize, translate, and more.
{:else}
Select text in the editor and right-click to access AI writing tools: improve, fix grammar, rewrite, summarize, translate, and more.
{/if}
{/if}
Provider
{ syncProvider = null; syncMessage = null; syncTestMessage = null; saveSyncSettings(); }}>Disabled
{ syncProvider = 'webdav'; syncMessage = null; syncTestMessage = null; saveSyncSettings(); }}>WebDAV
Sync your vault to your own WebDAV server (Nextcloud, ownCloud, a NAS).
{#if syncProvider === 'webdav'}
Password
Use an app password, not your main one. Stored locally on this device.
Connection
{#if syncTestLoading}
Testing...
{:else}
Test Connection
{/if}
{#if syncTestMessage}
{#if syncTestMessage.type === 'success'}
{:else}
{/if}
{syncTestMessage.text}
{/if}
Sync
{#if syncRunning}
Syncing...
{:else}
Sync Now
{/if}
{#if syncMessage}
{#if syncMessage.type === 'success'}
{:else}
{/if}
{syncMessage.text}
{/if}
{#if $appConfig?.last_sync_time}
Last sync: {new Date($appConfig.last_sync_time).toLocaleString()}
{/if}
If a note is edited on two devices, both are kept (one as a "(conflict)" copy).
Automatic Sync
{#each [{ v: 0, l: 'Off' }, { v: 5, l: '5 min' }, { v: 15, l: '15 min' }, { v: 30, l: '30 min' }, { v: 60, l: '60 min' }] as opt}
{ syncIntervalMinutes = opt.v; saveSyncSettings(); }}>{opt.l}
{/each}
How often to sync in the background.
Sync when a note changes
Sync shortly after you edit a note.
{ syncOnChange = !syncOnChange; saveSyncSettings(); }}>
Sync when the vault opens
Sync once when the app starts.
{ syncOnOpen = !syncOnOpen; saveSyncSettings(); }}>
{/if}
Current Version
HelixNotes v{appVersion}
Check for Updates
{#if updateChecking}
Checking...
{:else}
Check for Updates
{/if}
{#if updateAvailable}
Update Available
Version {updateAvailable.version}
{#if updateAvailable.date}
{new Date(updateAvailable.date).toLocaleDateString()}
{/if}
{#if updateAvailable.body}
{updateAvailable.body}
{/if}
{#if $installType === 'appimage' || $installType === 'windows' || $installType === 'macos'}
{#if updateDownloading}
{updateProgress > 0 ? `Downloading ${updateProgress}%` : 'Downloading...'}
{:else}
Download & Install
{/if}
{#if updateDownloading && updateProgress > 0}
{/if}
{:else if $installType === 'deb'}
Update via your package manager:
sudo apt update && sudo apt upgrade helix-notes
{:else if $installType === 'aur'}
Update via your AUR helper:
yay -Syu helixnotes
{:else if $installType === 'android'}
{ openUrl('https://helixnotes.com/#download').catch(() => {}); }}>
Download from Website
{:else}
Download from Codeberg
{/if}
{/if}
{#if updateMessage}
{#if updateMessage.type === 'success'}
{:else if updateMessage.type === 'error'}
{:else}
{/if}
{updateMessage.text}
{/if}