Open-source project
aloisdeniel/flutter_device_preview avatar
aloisdeniel/flutter_device_preview

flutter_device_preview 3.0: Simulate Any Device Inside a Running Flutter App

Approximate how your app looks and performs on another device.

2,407 stars394 forksJavaScriptMIT

At a glance

What is it?
Device Preview 3.0 swaps your running Flutter app onto another screen, safe area and locale without a rebuild, and drives it from DevTools, Dart or widget tests. Here is what the 3.0 layout actually contains, and where the approach stops being the right tool.
Who is it for?
Adopt Device Preview 3.0 if you ship Flutter UI to more than one screen class and want overflow, safe-area and text-scale problems to appear during development rather than in a customer demo. If your app is a single fixed-size kiosk build, or if you need real hardware behaviour such as GPU performance, thermals or platform channel latency, simulation is the wrong layer and you need a device or emulator.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 37 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What flutter_device_preview solves, and for whom

You develop on one screen and your users arrive on hundreds. The README frames the problem that way, and the failure modes it names are the familiar ones: a clipped headline, a button sitting under the home indicator, an overflow at 200 percent text. Each of those is cheap to fix during development and expensive to find in a demo.

Device Preview changes the running app's simulated environment rather than the app's code. Screen size, pixel ratio, safe areas, orientation, folds, the software keyboard, locales, brightness, text scale, accessibility settings and target platform all move together, and the app keeps reading them through the same MediaQuery it already used. That last part is the design decision that matters. Nothing in your widget tree needs to know a preview is active, so what you see is your normal layout logic reacting to different inputs, not a separate preview rendering path.

The audience is Flutter developers working on responsive or multi-form-factor UI: phone plus tablet, phone plus desktop window, or an app that has to survive large text and right-to-left locales. It is less useful if you never leave one screen size.

How the 3.0 architecture is split across the repository

The repository is not a single package. The README's structure table lists four working directories plus the website, and the split explains how the tool reaches a running app.

device_preview holds the published package: the binding, the controller, the presets, the service extensions, and a bundled DevTools extension build. device_preview_devtools_extension is the source of the DevTools web app and is never published; it is built into device_preview/extension/devtools/build. device_specs is the device catalog, one JSON file per device holding metrics, a screen outline and body artwork. Those JSON files are generated into both the extension catalog and the package's built-in DevicePresets, so the same device definition feeds the DevTools UI and the Dart API. docs is the website, including an interactive demo whose catalog is docs/device_catalog.json and which is rebuilt with tool/build_demo.sh.

The control channel is the DevTools protocol. Device artwork is carried by the built-in presets and pushed over that protocol, which is why the DevTools extension does not need to ship separately. One consequence worth noting: device_frame, the frame drawing package from the 2.x era, is marked legacy in the README, and nothing in the 3.0 release depends on it. If you have a 2.x setup that imports device_frame directly, that import is now outside the supported path.

Installing device_preview and running a first simulation

The README gives a two-step quickstart. Add the dependency to pubspec.yaml, then call DevicePreview.enable() before runApp.

yaml
dependencies:
  device_preview: <latest version>

The README writes the version as a placeholder, so check the pub.dev entry for device_preview rather than copying a number from the repository front page.

dart
void main() {
  DevicePreview.enable();
  runApp(const MyApp()); // runs as usual — now simulatable
}

That is the whole integration according to the README. After starting the app, open Flutter DevTools, select the device_preview tab, and pick a device. The app should keep running as before while the simulated screen, safe areas and locale change around it.

The enable() call is safe to leave in unconditionally: the README states simulation is active in debug and profile builds and completely off in release, so nothing ships to users. You can also decide yourself, with DevicePreview.enable(enabled: kDebugMode) for debug only or DevicePreview.enable(enabled: false) to switch it off. If you want to drive it from code instead of the DevTools panel, the README shows the controller API:

dart
import 'package:device_preview/presets.dart';

final c = DevicePreview.controller;
await c.applyPreset(DevicePresets.iPhone16Pro);
await c.setOrientation(Orientation.landscape);
await c.update((s) => s.copyWith(textScaleFactor: 2.0, platformBrightness: Brightness.dark));
await c.reset();

Presets come from the generated catalog, so DevicePresets.iPhone16Pro is one entry in a set built from device_specs JSON. Widget tests are supported through DevicePreviewBindingMixin, documented in device_preview/README.md rather than the root file.

The controller throws in release, and other limits you should plan around

The sharpest constraint is stated plainly: DevicePreview.controller throws when simulation is off, which the README says is every release build. Code that ships and touches the controller will crash in production. The documented escape hatch is DevicePreview.maybeController, which returns nothing instead of throwing, and the README explicitly tells you to use it from code that ships. If you build a debug-only settings screen around the controller, keep that boundary clean.

The second limit is conceptual. This is a simulation of device characteristics, not of device behaviour. The README describes changing screen metrics, safe areas, orientation, folds, keyboard, locale, brightness, text scale, accessibility settings and target platform. It does not claim to reproduce GPU performance, memory pressure, thermal throttling or platform channel latency, and those are the things that make an app feel slow on an old phone. The repository description says the tool approximates how an app looks and performs on another device, but the mechanism described in the README is environment substitution, so treat performance claims as approximate by construction.

Third, the project is JavaScript at the top level because the DevTools extension is a web app, while the package your app imports is Dart. That is fine, but it means an issue in the extension UI and an issue in the package live in different codebases, and the extension is built into the package rather than published on its own.

Finally, the README does not document rollback or migration steps from 2.x to 3.0. Given that device_frame is now legacy and frames are rendered from device_specs artwork, a 2.x project that customized frames has no documented upgrade path in the root README.

flutter_device_preview versus running a real emulator or device

The obvious alternative is the Flutter tooling you already have: flutter run against an emulator, a simulator, or a physical device, switching targets when you want to check another form factor. The difference in approach is where the device lives. An emulator boots an entire platform image, so you get real platform behaviour, real input, real performance characteristics and real platform channels, at the cost of a boot cycle for every target and a heavier machine footprint. Device Preview keeps one running app and swaps the environment values the framework reports to it, so switching from a 320pt phone to a landscape tablet is instant and needs no second process.

That trade is not a tie. Anything that depends on the platform rather than on MediaQuery will not change when you switch devices in Device Preview: a plugin that reads a native screen size, a platform-specific permission flow, a native video surface. Those need the emulator. Equally, an emulator will not let you hold text scale at 200 percent and flip locale in the same session as quickly as the controller API does. The two tools answer different questions, and the README's claim of full framework fidelity is about the framework layer, not the platform layer.

There is also a naming trap in the ecosystem. Searches for device preview plus, or for a device preview package, surface other packages with similar names. Check that the pubspec entry is device_preview from this repository before following documentation that may describe something else.

Maintenance, licence and what an upgrade costs

The last push to the repository was on 2026-08-25, and the 3.0.0 release carries the same date. The repository is not archived. That is a recent, coherent release rather than a long tail of small commits, and the 3.0 version number signals that the device_specs and DevTools extension rework was a breaking change rather than an incremental one.

The licence is MIT, which is permissive and places few obligations on how you redistribute or modify the code. That is a statement about the licence text, not legal advice; if you vendor the package or ship a modified extension build, read the LICENSE file in the repository root and, where it matters to your organisation, get proper review.

The practical upgrade cost sits in three places. The package now bundles a DevTools extension build, so your toolchain needs a DevTools version that can load it. The frame rendering moved to device_specs artwork, so any 2.x code that reached into device_frame needs rewriting against the new presets. And the controller contract now distinguishes controller from maybeController, which means release-path code that previously called the controller unconditionally has to be audited. None of those are large, but all three touch code rather than configuration, so budget a real pass over the app rather than a dependency bump.

Editorial conclusion

Adopt Device Preview 3.0 if you ship Flutter UI to more than one screen class and want overflow, safe-area and text-scale problems to appear during development rather than in a customer demo. If your app is a single fixed-size kiosk build, or if you need real hardware behaviour such as GPU performance, thermals or platform channel latency, simulation is the wrong layer and you need a device or emulator. Before wiring it in, read device_preview/README.md for the DevicePreviewBindingMixin test setup, confirm the pub.dev entry for device_preview matches the 3.0.0 release, and check whether anything in your project still imports device_frame, which the 3.0 release does not depend on.

Frequently asked questions

How do I install flutter_device_preview in a Flutter project?

Add device_preview to the dependencies section of pubspec.yaml, then call DevicePreview.enable() before runApp in your main function. After that, open Flutter DevTools, select the device_preview tab and pick a device.

Why is flutter_device_preview not working in my app?

The README states that simulation is active in debug and profile builds and completely off in release, so a release build will not show the DevTools panel. Also check that you are using DevicePreview.controller only where simulation is on, since it throws when simulation is off; DevicePreview.maybeController is the version intended for code that ships.

Is there an alternative to flutter_device_preview?

You can run the app on an emulator, a simulator or a physical device instead. That gives real platform behaviour and real performance characteristics, but each target needs its own boot cycle, whereas Device Preview switches the running app's simulated environment instantly.

Can I take a screenshot from flutter_device_preview?

The README does not document a screenshot capability. It lists screen size, pixel ratio, safe areas, orientation, folds, the software keyboard, locales, brightness, text scale, accessibility settings and target platform as the values that change when you switch devices.

Where do I get the device_preview package?

The README points to the pub.dev listing for device_preview, and the package source lives in the device_preview directory of this repository. The repository root README writes the version as a placeholder, so check pub.dev for the current version rather than copying a number.

Official sources

  1. aloisdeniel/flutter_device_preview on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aloisdeniel-flutter-device-preview.svg)](https://hysenlabs.com/projects/aloisdeniel-flutter-device-preview)