{"id":15555009,"url":"https://github.com/gabrimatic/restart_app","last_synced_at":"2026-05-02T10:02:27.152Z","repository":{"id":43693062,"uuid":"368472107","full_name":"gabrimatic/restart_app","owner":"gabrimatic","description":"A Flutter plugin that helps you to restart the whole Flutter app with a single function call by using native APIs.","archived":false,"fork":false,"pushed_at":"2026-02-27T09:05:06.000Z","size":169,"stargazers_count":105,"open_issues_count":5,"forks_count":98,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-27T13:38:38.814Z","etag":null,"topics":["dart","dartlang","flutter","flutter-package","flutter-restart","library"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/restart_app","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabrimatic.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-18T09:25:57.000Z","updated_at":"2026-02-27T09:05:10.000Z","dependencies_parsed_at":"2024-12-13T17:09:36.328Z","dependency_job_id":"8f8326b7-6ced-4ca6-9421-dbb6e9f6d70e","html_url":"https://github.com/gabrimatic/restart_app","commit_stats":{"total_commits":36,"total_committers":2,"mean_commits":18.0,"dds":0.2222222222222222,"last_synced_commit":"dad1e7f1950745fc3aec4553e856cf8518a39302"},"previous_names":["gabrimatic/restart"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gabrimatic/restart_app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrimatic%2Frestart_app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrimatic%2Frestart_app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrimatic%2Frestart_app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrimatic%2Frestart_app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrimatic","download_url":"https://codeload.github.com/gabrimatic/restart_app/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrimatic%2Frestart_app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32530176,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dartlang","flutter","flutter-package","flutter-restart","library"],"created_at":"2024-10-02T15:05:37.992Z","updated_at":"2026-05-02T10:02:27.145Z","avatar_url":"https://github.com/gabrimatic.png","language":"Dart","funding_links":["https://www.buymeacoffee.com/gabrimatic"],"categories":[],"sub_categories":[],"readme":"# restart_app\n\n[![pub package](https://img.shields.io/pub/v/restart_app.svg)](https://pub.dev/packages/restart_app) [![likes](https://img.shields.io/pub/likes/restart_app)](https://pub.dev/packages/restart_app/score) [![popularity](https://img.shields.io/pub/popularity/restart_app)](https://pub.dev/packages/restart_app/score) [![pub points](https://img.shields.io/pub/points/restart_app)](https://pub.dev/packages/restart_app/score)\n\nRestart or relaunch your Flutter app with a single function call.\n\nAndroid, macOS, Linux, and Windows use platform-specific relaunch behavior. Web reloads the page. iOS does not provide a public API for automatic full process restart, so `restart_app` supports an opt-in Flutter engine restart and keeps the old notification-based flow as an explicit legacy fallback.\n\n## Quick start\n\nAdd the dependency:\n\n```yaml\ndependencies:\n  restart_app: ^1.8.1\n```\n\nImport and call:\n\n```dart\nimport 'package:restart_app/restart_app.dart';\n\nfinal restarted = await Restart.restartApp();\n```\n\nReturns `true` if the restart was initiated. Returns `false` on failure (permission denied, missing executable, no launchable activity).\n\nFor structured errors and capabilities, use the newer API:\n\n```dart\nfinal result = await Restart.restart(\n  mode: RestartMode.platformDefault,\n);\n\nif (!result.success) {\n  // Show or log result.code and result.message.\n}\n```\n\n## Parameters\n\n| Parameter | Platform | Description |\n|-----------|----------|-------------|\n| `mode` | All | Requested restart behavior: `platformDefault`, `flutterEngine`, `process`, or `notificationFallback`. |\n| `webOrigin` | Web | Custom origin URL for the reload. Defaults to `window.origin`. Supports hash strategy (e.g. `'#/home'`). |\n| `notificationTitle` | iOS | Title of the local notification shown by the legacy notification fallback. |\n| `notificationBody` | iOS | Body of the local notification shown by the legacy notification fallback. |\n| `forceKill` | Android | When `true`, fully terminates the process after launching the new activity. Defaults to `false`. `RestartMode.process` enables this path automatically on Android. |\n\n## Platform behavior\n\n| Platform | Mechanism | Limitations |\n|----------|-----------|-------------|\n| **Android** | Relaunches the main activity via `PackageManager`. Supports Android TV and Fire TV via leanback launcher fallback. `RestartMode.process` and `forceKill: true` kill the process after launch for a clean cold start. | None |\n| **iOS** | Recommended: opt-in Flutter engine restart that creates a new `FlutterEngine`, runs Dart again, re-registers plugins, and replaces the root `FlutterViewController` in the same iOS process. Legacy: local notification + `exit(0)` + user tap. | iOS has no public API for automatic full process restart. Engine restart is not a process restart and cannot reset native singleton state. Legacy fallback requires notification permission and user action. |\n| **Web** | Reloads the page using `window.location`. | None |\n| **macOS** | Launches a new instance via `NSWorkspace` and terminates the current process. | Sandboxed (Mac App Store) builds cannot launch new instances of themselves. Returns `false` in this case. |\n| **Linux** | Replaces the current process via `execv`. Fully automatic. | None |\n| **Windows** | Launches a new instance via `CreateProcess` and terminates the current process. | MSIX-packaged (Microsoft Store) apps cannot be relaunched via `CreateProcess`. |\n\n## iOS\n\niOS does not provide a public API for an app to terminate itself and automatically launch a fresh process of the same app. Android-style full process restart is not available on iOS with public APIs.\n\n`restart_app` supports two iOS behaviors:\n\n1. **Flutter engine restart**, recommended. This keeps the iOS process alive, creates a new `FlutterEngine`, runs the Dart entrypoint again, re-registers plugins through the host app's `GeneratedPluginRegistrant`, creates a new `FlutterViewController`, replaces the active root view controller, and destroys the old engine context.\n2. **Notification fallback**, legacy. This schedules a local notification, calls `exit(0)`, and requires the user to tap the notification to reopen the app. This is not a true restart and is not recommended as normal product behavior.\n\n### Configure Flutter engine restart\n\nThe host app owns `GeneratedPluginRegistrant`, so iOS engine restart requires one app-side setup step.\n\nIn `ios/Runner/AppDelegate.swift`:\n\n```swift\nimport UIKit\nimport Flutter\nimport restart_app\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n  override func application(\n    _ application: UIApplication,\n    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n  ) -\u003e Bool {\n    RestartAppPlugin.configureEngineRestart { engine in\n      GeneratedPluginRegistrant.register(with: engine)\n    }\n\n    GeneratedPluginRegistrant.register(with: self)\n\n    return super.application(\n      application,\n      didFinishLaunchingWithOptions: launchOptions\n    )\n  }\n}\n```\n\nThen call:\n\n```dart\nfinal result = await Restart.restart(\n  mode: RestartMode.flutterEngine,\n);\n```\n\n`RestartMode.platformDefault` uses Flutter engine restart on iOS when this setup is present.\n\n### iOS capabilities\n\n```dart\nfinal capability = await Restart.restartCapability();\n\nif (capability.flutterEngineRestart) {\n  await Restart.restart(mode: RestartMode.flutterEngine);\n}\n```\n\n### What iOS engine restart resets\n\nIt resets:\n\n- Dart root isolate\n- Flutter widget tree\n- Flutter engine-owned platform channels\n- Flutter plugin registrations for the new engine\n- Platform-view factory registrations for the new engine\n\nIt does not reset:\n\n- The iOS process\n- Swift, Objective-C, C, or C++ static/global state\n- Native singleton state\n- Native resources retained by plugins\n- Unrelated Flutter engines or background isolates\n- Native app launch lifecycle callbacks from a real process launch\n\nFor code-push systems and plugins with heavy native state, verify behavior in a real release build. Same-process engine restart is not equivalent to full process restart.\n\n### Legacy notification fallback\n\nUse the notification fallback only when the tradeoff is acceptable:\n\n```dart\nRestart.restart(\n  mode: RestartMode.notificationFallback,\n  notificationTitle: 'Update applied',\n  notificationBody: 'Tap to reopen the app.',\n);\n```\n\nThe plugin requests notification permission at the moment of restart. If not already granted, iOS shows the system prompt right before exit, which feels abrupt.\n\nRequest permission earlier in your app's lifecycle. The [permission_handler](https://pub.dev/packages/permission_handler) package works well for this.\n\nIf notification permission has been denied, `restartApp()` returns `false` and `restart()` returns a failed result.\n\n### Provisioning profiles\n\n`restart_app` uses **local notifications only**, not push notifications. It adds no push-related entitlements to your app.\n\nIf you see `\"requires a provisioning profile with the Push Notifications feature\"` when exporting an IPA, another dependency is the cause (commonly `firebase_messaging`). Add the Push Notifications capability to your distribution provisioning profile.\n\n## Linux\n\n### Command-line arguments\n\nBy default, the restarted process launches without the original command-line arguments. To preserve them, call `restart_app_plugin_store_argv` in your `linux/main.cc` before running the Flutter engine:\n\n```cpp\n#include \u003crestart_app/restart_app_plugin.h\u003e\n\nint main(int argc, char** argv) {\n  restart_app_plugin_store_argv(argc, argv);\n  // ... rest of main()\n}\n```\n\nMost Flutter apps don't rely on command-line arguments, so this step is optional.\n\n## Background isolates\n\n`Restart.restartApp()` uses a platform channel and must run on the **main isolate**. Calling it from a background isolate throws:\n\n```\nBad state: The BackgroundIsolateBinaryMessenger.instance value is invalid\nuntil BackgroundIsolateBinaryMessenger.ensureInitialized is executed.\n```\n\nSend a message from your isolate to the main isolate instead:\n\n```dart\n// Main isolate: listen for restart signals\nfinal receivePort = ReceivePort();\nreceivePort.listen((message) {\n  if (message == 'restart') {\n    Restart.restartApp();\n  }\n});\n\n// Spawn the isolate with the SendPort\nawait Isolate.spawn(myIsolateFunction, receivePort.sendPort);\n\n// Background isolate: signal instead of calling restartApp() directly\nvoid myIsolateFunction(SendPort sendPort) {\n  // ... your background work ...\n  sendPort.send('restart');\n}\n```\n\n## Requirements\n\n**Dart SDK:** `\u003e=3.4.0` · **Flutter:** `\u003e=3.22.0`\n\n## Author\n\nCreated by [Soroush Yousefpour](https://gabrimatic.info)\n\n\u003ca href=\"https://www.buymeacoffee.com/gabrimatic\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Book\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" \u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrimatic%2Frestart_app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrimatic%2Frestart_app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrimatic%2Frestart_app/lists"}