A grid-based web browser for iPad that reimagines how users interact with multiple webpages at once.
Unlike traditional tab-based browsers, Waffle organizes pages into a customizable grid. Each cell hosts its own browsing context, allowing users to visually organize workflows, research sets, and dashboards side-by-side. Built with SwiftUI and WebKit for iOS 26, it offers a lightweight, intuitive, and deeply Apple-native browsing experience.
Waffle is designed for:
- iPad power users who multitask visually
- Researchers and developers who reference multiple sources simultaneously
- Designers and creatives who prefer spatial memory over tab stacks
- Customizable grid layout (up to unlimited rows/columns with premium)
- Independent browsing context per cell with full navigation
- Drag and drop to rearrange cells
- Pop-out windows for focused viewing
- Save and organize bookmarks with drag-to-reorder
- Create presets to save entire grid layouts
- Restore research sessions with one tap
- Share extension to save URLs directly into grid cells
- Quick capture from any app via share sheet
- iCloud Sync: Seamless bookmark and preset sync via CloudKit
- Multi-Window: Scene-based architecture with independent grid persistence
- Fullscreen Mode: Distraction-free browsing
- Grid dimensions beyond 2x2
- Grid rearrangement
- Pop-out windows
- Fullscreen mode
- Preset creation
- iPadOS 26.0+
- Xcode 16.0+
- macOS 15.0+ (Sequoia)
- Apple Developer account (for CloudKit capabilities)
- Clone the repository
- Open
Waffle.xcodeprojin Xcode - Configure signing with your Apple Developer account
- Update bundle identifiers and iCloud container identifiers
- Build and run on iPad simulator or device
Enable these in your Xcode project:
- iCloud (CloudKit with private database)
- App Groups
The app uses two window scenes:
- main: Primary grid browser interface
- DetachedWaffleCell: Pop-out windows for individual cells
WaffleApp
└── WaffleCoordinator (@Observable)
├── WaffleState (grid state, snapshots)
└── StoreManager (in-app purchases)
| Component | Responsibility |
|---|---|
WaffleCoordinator |
Central coordinator managing state and subscriptions |
WaffleState |
Observable grid state with 2D cell array |
WaffleCell |
Individual grid cell with WebPage context |
StoreManager |
StoreKit 2 subscription management |
- SwiftData with iCloud CloudKit sync for bookmarks and presets
- AppStorage for user preferences
- Codable Snapshots for grid state persistence
| Model | Description |
|---|---|
WaffleCell |
In-memory grid cell with WebPage |
Bookmark |
Saved URLs with sortIndex for reordering |
Preset |
Saved grid layouts (name, dimensions, URLs) |
SearchProvider |
Search engine enum (Google, DuckDuckGo) |
- MVVM with Coordinator: Views have nested ViewModels, coordinator manages app-wide state
- Dependency Injection: Coordinator injected via SwiftUI
@Environment - Feature Gating: Premium features controlled via
hasSyrupflag
Waffle/
├── WaffleApp.swift # App entry point with window scenes
├── WaffleCoordinator.swift # Central state coordinator
├── WaffleState.swift # Grid state management
├── Models/
│ ├── WaffleCell.swift # Grid cell model
│ ├── Bookmark.swift # SwiftData bookmark
│ └── Preset.swift # SwiftData preset
├── Views/
│ ├── Main/ # Primary interface
│ │ ├── MainView.swift # Root navigation
│ │ ├── SidebarView.swift # Navigation sidebar
│ │ └── WaffleGridView.swift # Grid container
│ ├── Cell/ # Cell views
│ │ ├── WaffleCellView.swift
│ │ └── EmptyCellView.swift
│ ├── Settings/ # Preferences
│ └── Syrup/ # Subscription UI
├── WebKit/ # WKWebView wrapper
└── Extensions/ # Utilities
WaffleShareExtension/ # Safari share extension
Waffle is designed with privacy in mind:
- All data stored in your private iCloud container
- No browsing history sent to third parties
- No analytics or tracking
- Local-first architecture
This project is licensed under the MIT License - see the LICENSE file for details.
Molargik Software LLC