A professional, developer-centric iOS Simulator for testing web apps on your desktop.
This project solves the pain of testing mobile web experiences without needing a physical device or the heavy Xcode Simulator. It provides a lightweight, Electron-based environment that accurately mimics iOS behaviors, including safe areas, touch events, and virtual keyboards.
-
📱 Accurate Device Emulation:
- iPhone 13 Pro (Notch)
- iPhone 14 Pro (Dynamic Island)
- iPad Pro 11 (Tablet layout)
- Matches accurate screen dimensions, pixel ratios, and user agents.
-
👆 True Touch Environment:
- Force Touch Events: Automatically maps mouse interactions (mousedown/move/up) to native TouchEvents (touchstart/move/end).
- Hover Disabled: Overrides
matchMedia('(hover: hover)')tofalseto strictly enforce mobile behavior. - Max Touch Points: Polyfills
navigator.maxTouchPointsto simulate a real touch screen.
-
📐 Safe Area & Notch Injection:
- Automatically injects CSS variables into the simulated page:
--safe-area-inset-top--safe-area-inset-bottom
- Handles differences between Notch and Dynamic Island layouts.
- Automatically injects CSS variables into the simulated page:
-
⌨️ Virtual Keyboard Simulation:
- Detects focus on inputs (
text,password,email, etc.) and content-editable elements. - Slides up a glassmorphism keyboard overlay.
- Adjusts the viewport and scrolls the focused element into view, mimicking iOS behavior.
- Detects focus on inputs (
-
🎨 Theme & UI Sync:
- Light/Dark Mode: Toggles system-wide theme preferences, syncing with
prefers-color-scheme. - Dynamic Theme Color: Observes
meta[name="theme-color"]to update the simulator's frame and overscroll background.
- Light/Dark Mode: Toggles system-wide theme preferences, syncing with
-
🌐 Network & PWA Tools:
- Network Throttling: Simulate slow connections (3G, 4G, Offline) via Electron's session API.
- PWA Mode: Toggle between "Safari" (browser chrome) and "Standalone" (fullscreen) modes.
This simulator is built on Electron to leverage the <webview> tag, which provides a separate process for the simulated content.
- Isolation: The simulated website runs in a sandboxed
<webview>container, isolated from the simulator's UI. - Preload Scripts: We inject a
preload.jsscript that bridges the gap between the host (Electron) and the guest (Webview). - Runtime Injection:
- CSS: We inject CSS variables for safe areas directly into the
:rootof the loaded page. - Events: We intercept mouse events at the window level and re-dispatch them as
TouchEventsto ensure your app reacts exactly as it would on a phone.
- CSS: We inject CSS variables for safe areas directly into the
- IPC Bridge: The main process communicates with the renderer to handle system-level tasks like network emulation and theme switching.
- Node.js (v16 or higher)
- npm or yarn
-
Clone the repository
git clone https://github.com/yourusername/ios-simulator-desktop.git cd ios-simulator-desktop -
Install dependencies
npm install
-
Run the Simulator
npm start
This command concurrently starts the Vite dev server for the UI and the Electron app.
-
Build for Production
npm run build
ios-simulator-desktop/
├── src/
│ ├── main/ # Electron Main Process
│ │ ├── main.js # Window creation & IPC handlers
│ │ └── preload.js # Context bridge
│ ├── renderer/ # React UI (The Simulator Shell)
│ │ ├── components/
│ │ │ ├── Simulator.jsx # Core logic (Webview, Injection)
│ │ │ ├── Header.jsx # Toolbar controls
│ │ │ └── ...
│ │ ├── App.jsx # State management
│ │ └── constants.js # Device definitions (sizes, UAs)
│ └── cli/ # Helper modules
├── package.json
└── vite.config.js
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.
