Skip to main content
Ora Browser is built with privacy as a core principle. From private browsing mode to per-space data isolation, Ora gives you complete control over your browsing data and privacy.

Private Browsing Mode

Private browsing in Ora uses in-memory storage that is never persisted to disk. When you close a private window, all data is immediately discarded.

Opening a Private Window

Use ⌘⇧N to open a new private browsing window.
// Private tabs use non-persistent data stores
let config = TabScriptHandler()
self.webView = WKWebView(
    frame: .zero,
    configuration: config.customWKConfig(
        containerId: container.id,
        temporaryStorage: isPrivate  // Uses in-memory storage when true
    )
)

What’s Protected in Private Mode

No History

Browsing history is not recorded and won’t appear in your history or Quick Launcher suggestions

In-Memory Cookies

Cookies and site data are stored in memory only and deleted when the window closes

No Downloads History

Downloaded files aren’t tracked in your downloads history

Temporary Storage

All website data uses WebKit’s non-persistent data store
if temporaryStorage {
    configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
} else {
    configuration.websiteDataStore = WKWebsiteDataStore(forIdentifier: containerId)
}
Private browsing mode in Ora uses WebKit’s nonPersistent() data store, ensuring all data is kept in memory and never written to disk.

Space-Based Data Isolation

Each Space maintains completely isolated browsing data, including cookies, cache, and website storage.

How It Works

Ora uses WebKit’s data store isolation feature to create separate data containers for each Space:
@Model
class TabContainer: ObservableObject, Identifiable {
    var id: UUID
    var name: String
    var emoji: String
    
    @Relationship(deleteRule: .cascade) var tabs: [Tab] = []
    @Relationship(deleteRule: .cascade) var folders: [Folder] = []
    @Relationship() var history: [History] = []
}
Each Space’s tabs use a data store identified by the container’s unique ID:
configuration.websiteDataStore = WKWebsiteDataStore(forIdentifier: containerId)

Benefits of Data Isolation

1

Separate Login Sessions

Log into the same service with different accounts in different Spaces—perfect for managing multiple work accounts
2

Context-Specific Cookies

Cookies set in one Space don’t affect other Spaces, preventing cross-context tracking
3

Independent Storage

LocalStorage, IndexedDB, and other web storage APIs are isolated per Space

Privacy Service

Ora provides a powerful PrivacyService for managing browsing data at both the Space and site level.

Clear All Data for a Space

class PrivacyService {
    static func clearCache(_ container: TabContainer, completion: (() -> Void)? = nil) {
        let types: Set<String> = WKWebsiteDataStore.allWebsiteDataTypes()
        self.clearData(container, types, completion)
    }
    
    static func clearCookies(_ container: TabContainer, completion: (() -> Void)? = nil) {
        let types: Set<String> = [WKWebsiteDataTypeCookies]
        self.clearData(container, types, completion)
    }
    
    private static func clearData(_ container: TabContainer, _ types: Set<String>, _ completion: (() -> Void)?) {
        let dataStore = WKWebsiteDataStore(forIdentifier: container.id)
        dataStore.removeData(
            ofTypes: types,
            modifiedSince: .distantPast
        ) {
            completion?()
        }
    }
}

Clear Data for Specific Sites

Target individual websites for data removal:
static func clearCookiesForHost(for host: String, container: TabContainer, completion: (() -> Void)? = nil) {
    let dataStore = WKWebsiteDataStore(forIdentifier: container.id)
    let types: Set<String> = [WKWebsiteDataTypeCookies]
    
    dataStore.fetchDataRecords(ofTypes: types) { records in
        let targetRecords = records.filter { $0.displayName.contains(host) }
        guard !targetRecords.isEmpty else {
            completion?()
            return
        }
        
        dataStore.removeData(ofTypes: types, for: targetRecords) {
            completion?()
        }
    }
}

Clear Cache for Specific Sites

static func clearCacheForHost(for host: String, container: TabContainer, completion: (() -> Void)? = nil) {
    let dataStore = WKWebsiteDataStore(forIdentifier: container.id)
    let types: Set<String> = WKWebsiteDataStore.allWebsiteDataTypes()
    
    dataStore.fetchDataRecords(ofTypes: types) { records in
        let targetRecords = records.filter { $0.displayName.contains(host) }
        guard !targetRecords.isEmpty else {
            completion?()
            return
        }
        
        dataStore.removeData(ofTypes: types, for: targetRecords) {
            completion?()
        }
    }
}
Control how Ora handles cookies with flexible cookie policies.
enum CookiesPolicy: String, CaseIterable, Identifiable, Codable {
    case allowAll = "Allow all"
    case blockThirdParty = "Block third-party"
    case blockAll = "Block all"
    
    var id: String { rawValue }
}
@Published var cookiesPolicy: CookiesPolicy {
    didSet { defaults.set(cookiesPolicy.rawValue, forKey: cookiesPolicyKey) }
}

Quick Actions for Privacy

Keyboard Shortcuts

Ora provides convenient keyboard shortcuts for common privacy actions:
ActionShortcut
New Private Window⌘⇧N
Clear Cache & Reload⌘⇧R
Clear Cookies & Reload⌘⌥⇧R
Access privacy features from the Navigation menu:
CommandMenu("Navigation") {
    Button("Clear Cache & Reload") {
        NotificationCenter.default.post(name: .clearCacheAndReload, object: NSApp.keyWindow)
    }
    .keyboardShortcut("r", modifiers: [.command, .shift])
    
    Button("Clear Cookies & Reload") {
        NotificationCenter.default.post(name: .clearCookiesAndReload, object: NSApp.keyWindow)
    }
    .keyboardShortcut("r", modifiers: [.command, .option, .shift])
}

Developer Tools

Web Inspector

Ora enables WebKit’s developer tools for debugging and inspection:
configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
Developer extras are enabled by default in Ora, allowing you to inspect any page by right-clicking and selecting “Inspect Element”.

Inspectable WebViews

All WebViews are marked as inspectable for external debugging tools:
webView.isInspectable = true

Content Security

JavaScript Security

Ora enables modern JavaScript features while maintaining security:
configuration.preferences.setValue(true, forKey: "javaScriptEnabled")
configuration.preferences.setValue(true, forKey: "javaScriptCanOpenWindowsAutomatically")

// But prevent automatic window opening for security
configuration.preferences.javaScriptCanOpenWindowsAutomatically = false

Secure Content Delivery

WebViews are configured with security best practices:
let preferences = WKWebpagePreferences()
preferences.allowsContentJavaScript = true
configuration.defaultWebpagePreferences = preferences

Privacy Best Practices

Use Spaces for Separation

Create separate Spaces for different contexts to prevent cross-site tracking and maintain separate login sessions

Regular Data Cleanup

Periodically clear cache and cookies for Spaces you use for sensitive browsing

Private Windows for Sensitive Tasks

Use private browsing windows for banking, healthcare, or other sensitive activities

Review Site Permissions

Regularly audit which sites have access to camera, microphone, and location permissions

Advanced Privacy Features

Passkey Support

Ora supports WebAuthn and passkeys for secure, password-less authentication.

Picture-in-Picture Privacy

When switching tabs, Ora can automatically pause or continue media in Picture-in-Picture mode:
func togglePiP(_ currentTab: Tab?, _ oldTab: Tab?) {
    if currentTab?.id != oldTab?.id, SettingsStore.shared.autoPiPEnabled {
        currentTab?.webView.evaluateJavaScript("window.__oraTriggerPiP(true)")
        oldTab?.webView.evaluateJavaScript("window.__oraTriggerPiP()")
    }
}

Favicon Privacy

Favicons are cached locally to prevent tracking through repeated favicon requests:
var faviconDirectory: URL {
    let dir = urls(for: .cachesDirectory, in: .userDomainMask).first!
        .appendingPathComponent("Favicons")
    if !fileExists(atPath: dir.path) {
        try? createDirectory(at: dir, withIntermediateDirectories: true)
    }
    return dir
}
While Ora provides strong privacy protections, no browser can guarantee complete anonymity. For maximum privacy, consider using a VPN or Tor in addition to Ora’s privacy features.

Build docs developers (and LLMs) love