Skip to content

bvandreunen/SlowNotes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Slow Notes

A premium iOS app for capturing and organizing handwritten notes. Built with SwiftUI, designed for a calm, mindful note-taking experience.

Features

  • Document Scanning - Capture handwritten notes using your device's camera with VisionKit integration
  • Full-Text Search - Find notes instantly with SQLite FTS5-powered search
  • Notebook Organization - Group entries by notebooks with brand support (Leuchtturm, Nuuna, Moleskine, Hobonichi)
  • Entry Types - Categorize notes with customizable types and colors
  • Tags & People - Link entries with tags and people references using [[PersonName]] syntax
  • Markdown Rendering - Rich text display with custom styling
  • Offline-First - All data stored locally for reliability and privacy
  • Dark Mode - Designed exclusively for dark mode with a liquid glass aesthetic

Architecture

The app follows a feature-based architecture with clean separation of concerns:

  • @Observable Pattern - Modern reactive state management
  • Actor-Based Services - Thread-safe data access with Swift actors
  • Dual Persistence - Local file storage (human-readable markdown) + SQLite search index
  • Type-Safe Navigation - NavigationStack with strongly-typed routing

Key Technologies

  • SwiftUI
  • Swift Concurrency (async/await, actors)
  • SQLite FTS5 (full-text search)
  • VisionKit (document scanning)
  • Keychain Services (secure storage)
  • Textual (markdown rendering)

Project Structure

SlowNotes/
├── App/
│   ├── SlowNotesApp.swift              # App entry point
│   └── ContentView.swift               # Root view (enforces dark mode)
│
├── Features/
│   ├── AddEntry/
│   │   ├── AddEntryView.swift          # Entry creation UI
│   │   ├── AddEntryViewModel.swift     # Entry creation state
│   │   └── DocumentScannerView.swift   # VisionKit scanner wrapper
│   │
│   ├── Auth/
│   │   ├── AuthenticationView.swift    # Auth flow coordinator
│   │   ├── LoginView.swift             # Login form
│   │   └── SignupView.swift            # Signup form
│   │
│   ├── EntryDetail/
│   │   ├── EntryDetailView.swift       # Note detail & markdown display
│   │   └── EntryDetailViewModel.swift  # Detail state & editing
│   │
│   ├── FilteredEntries/
│   │   ├── FilteredEntriesView.swift   # Filtered list UI
│   │   └── FilteredEntriesViewModel.swift
│   │
│   ├── Home/
│   │   ├── HomeView.swift              # Main library view
│   │   └── HomeViewModel.swift         # Library state & sections
│   │
│   ├── Notebooks/
│   │   ├── ManageNotebooksView.swift   # Notebook CRUD UI
│   │   └── NotebooksViewModel.swift
│   │
│   ├── Onboarding/
│   │   ├── OnboardingView.swift        # First-launch experience
│   │   └── OnboardingViewModel.swift
│   │
│   ├── Search/
│   │   ├── SearchView.swift            # Full-text search UI
│   │   └── SearchViewModel.swift       # Search state & results
│   │
│   ├── Settings/
│   │   ├── SettingsView.swift          # App settings UI
│   │   └── SettingsViewModel.swift
│   │
│   └── Types/
│       ├── ManageTypesView.swift       # Entry type management
│       └── TypesViewModel.swift
│
├── Models/
│   ├── Models.swift                    # Core types (NoteEntrySummary, EntryType, Notebook, etc.)
│   ├── EntryDetail.swift               # Full entry model
│   ├── Person.swift                    # Person reference model
│   └── Tag.swift                       # Tag model
│
├── Networking/
│   ├── APIClient.swift                 # Generic HTTP client
│   ├── APIError.swift                  # Error types
│   ├── APIModels.swift                 # Request/response DTOs
│   ├── AuthService.swift               # Authentication service
│   ├── EntryService.swift              # Entry API & OCR jobs
│   ├── KeychainService.swift           # Secure token storage
│   └── UserService.swift               # User profile API
│
├── Persistence/
│   ├── LocalStorage/
│   │   ├── LocalEntryService.swift     # Main entry service (coordinates file + index)
│   │   ├── FileStorageService.swift    # Markdown file I/O
│   │   └── SearchIndexService.swift    # SQLite FTS5 search index
│   │
│   ├── AppDataService.swift            # App-wide data coordination
│   ├── ExportService.swift             # PDF/Markdown export
│   ├── ImageStorageService.swift       # Image file management
│   ├── NotebookStorageService.swift    # Notebook persistence
│   ├── PersonStorageService.swift      # People persistence
│   ├── TagStorageService.swift         # Tag persistence
│   ├── PersistenceController.swift     # Storage coordination
│   ├── Repositories.swift              # Repository pattern implementations
│   └── SwiftDataModels.swift           # SwiftData model definitions
│
├── Preview/
│   └── PreviewData.swift               # Mock data for Xcode previews
│
├── Services/
│   ├── MockServices.swift              # Mock implementations for development
│   ├── ProcessingJobsService.swift     # OCR job tracking & polling
│   ├── OnboardingStateService.swift    # First-launch state
│   └── Logger.swift                    # Unified logging with levels
│
└── UI/
    ├── Components/
    │   ├── Buttons/
    │   │   ├── GlassButton.swift       # Glass-effect button
    │   │   ├── IconButton.swift        # Square icon button
    │   │   └── TextButton.swift        # Plain text button
    │   │
    │   ├── Cards/
    │   │   ├── GlassCard.swift         # Base card with glass effect
    │   │   ├── NoteCard.swift          # Entry summary card
    │   │   └── NotebookIconView.swift  # Notebook brand icon
    │   │
    │   ├── Feedback/
    │   │   ├── EmptyStateView.swift    # No-data state
    │   │   └── ToastView.swift         # Temporary notifications
    │   │
    │   ├── Inputs/
    │   │   └── GlassTextField.swift    # Styled text input
    │   │
    │   ├── Lists/
    │   │   ├── ListRowButton.swift     # Interactive list row
    │   │   ├── ListRowNavigation.swift # Navigation list row
    │   │   ├── ListRowToggle.swift     # Toggle list row
    │   │   └── ListSection.swift       # Grouped list section
    │   │
    │   ├── Navigation/
    │   │   ├── FloatingActionBar.swift # Bottom action buttons
    │   │   └── SectionHeader.swift     # Time period headers
    │   │
    │   ├── Rows/
    │   │   └── NotebookRow.swift       # Notebook list item
    │   │
    │   ├── ModalOverlayContainer.swift # Liquid glass modal backdrop
    │   ├── NotebookPickerModal.swift   # Notebook selection
    │   ├── TypePickerModal.swift       # Entry type selection
    │   ├── TagsPickerModal.swift       # Multi-select tags
    │   └── PeoplePickerModal.swift     # People picker
    │
    └── Theme/
        ├── Colors.swift                # Color palette & semantic colors
        ├── Typography.swift            # Font styles & text hierarchy
        └── ViewStyles.swift            # Reusable view modifiers

76 Swift files organized across 11 feature modules.

Getting Started

Requirements

  • iOS 17.0+
  • Xcode 15.0+
  • Swift 5.9+

Building

# Clone the repository
git clone https://github.com/your-org/SlowNotes.git
cd SlowNotes

# Build the project
xcodebuild -project SlowNotes.xcodeproj -scheme SlowNotes build

# Or open in Xcode
open SlowNotes.xcodeproj

Data Storage

Entries are stored in two complementary formats:

  1. Markdown Files - Human-readable files organized by notebook, year, and month

    Documents/
    └── <notebook>/
        └── <year>/
            └── <month>/
                └── <slug>.md  
    
  2. Search Index - SQLite database with FTS5 for fast full-text search

Design System

The app uses a consistent dark-mode design language:

  • Glass Effects - Ultra-thin material overlays for cards and modals
  • Entry Type Colors - Slate, Amber, Emerald, Cobalt, Violet
  • Notebook Brands - Visual identification by physical notebook brand
  • Typography - Clean hierarchy with system fonts

Development

Preview States

Most views include multiple preview states for development:

  • Empty state
  • Loading state
  • Populated state
  • Edge cases

Guidelines

See CLAUDE.md for detailed development guidelines and coding conventions.

License

Copyright 2026. All rights reserved.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages