Skip to content

Flutter Setup & Toolchain

Playground note: This is a setup and toolchain lesson — no runnable in-browser snippet applies here. Follow the steps in your terminal.

Setting up Flutter is closer to installing the Go or Rust toolchain than to npm install. You download one SDK, add it to your PATH, and the flutter CLI handles everything else — dependency management, device emulation, builds, and hot reload.

Visit flutter.dev/docs/get-started/install and follow the guide for your OS (macOS, Windows, or Linux).

macOS shortcut (Homebrew):

Terminal window
brew install --cask flutter

After installation, run the doctor to verify your environment:

Terminal window
flutter doctor

flutter doctor is Flutter’s equivalent of npx create-react-app --check — it scans for missing dependencies (Xcode, Android Studio, connected devices) and tells you exactly what to fix.

Everything here is written against Flutter 3.47 (the current stable) on the React 19 side of the comparison. Flutter’s stable channel ships roughly every quarter, so a few platform requirements are worth checking before you start:

TargetRequirement on Flutter 3.47
iOSiOS 15 or later (raised from 13)
macOSmacOS 12 or later (raised from 10.15)
XcodeXcode 27 supported
RendererImpeller is the default on iOS, Android, macOS, Windows, and Linux
iOS pluginsSwift Package Manager; CocoaPods is in maintenance mode

Impeller replaced Skia as the renderer precisely to kill the “first animation stutters” problem: shaders are compiled at build time instead of being discovered at runtime. If you have read older Flutter posts complaining about jank on the first frame of an animation, that is the problem Impeller solves, and on 3.47 it is on by default everywhere.

The Swift Package Manager move matters the first time you add a plugin with native iOS code. Most popular plugins have already migrated; if you hit one that has not, you will see CocoaPods fall back in. That still works today, but treat an unmigrated plugin as a maintenance signal — the same way you would treat an npm package whose last publish was three years ago.

npm / Vite / CRAflutter CLIPurpose
npm create vite@latest my-appflutter create my_appScaffold a new project
npm installflutter pub getInstall dependencies
npm run devflutter runStart dev server + hot reload
npm run buildflutter build apk / flutter build webProduction build
npm install packageflutter pub add packageAdd a dependency
npm testflutter testRun tests
npx eslint .flutter analyzeLint / static analysis
Terminal window
flutter create my_app
cd my_app
flutter run

flutter create generates a project similar to what create-react-app produces: an entry point, a sample widget, and all the platform-specific boilerplate (iOS Xcode project, Android Gradle files, web index.html).

flowchart TB
  root["my_app/"]
  lib["lib/"]
  mainDart["main.dart — entry point (≈ src/main.tsx)"]
  test["test/"]
  widgetTest["widget_test.dart — tests (≈ src/__tests__/)"]
  pubspec["pubspec.yaml — dependencies (≈ package.json)"]
  android["android/ — Android native shell"]
  ios["ios/ — iOS native shell"]
  web["web/ — Web shell"]
  root --> lib --> mainDart
  root --> test --> widgetTest
  root --> pubspec
  root --> android
  root --> ios
  root --> web
Flutter project structure vs React

Your Dart code lives entirely in lib/. You almost never touch android/ or ios/ unless you need platform-specific native code.

pubspec.yaml
name: my_app
dependencies:
flutter:
sdk: flutter
dio: ^5.4.0 # HTTP client (≈ axios)
go_router: ^18.0.0 # routing (≈ react-router-dom)
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^6.0.0

After editing pubspec.yaml run flutter pub get (≈ npm install) to fetch packages from pub.dev — Dart’s npm registry.

Terminal window
flutter pub add dio

This edits pubspec.yaml and runs pub get in one step — equivalent to npm install dio.

VS Code (recommended for React developers):

  1. Install the Flutter extension (includes Dart language support).
  2. Open the command palette → Flutter: Select Device to pick a simulator/emulator.
  3. Press F5 or run Flutter: Run to start with hot reload.

Android Studio / IntelliJ: Install the Flutter and Dart plugins. This is the preferred IDE for Android-heavy work.

Both work the same way: edit a source file, save, and the running app updates in under a second without losing state. In Flutter:

  • Hot Reload (r in the terminal, or Ctrl+S in VS Code with the extension) — injects updated code, preserves widget state.
  • Hot Restart (R) — full restart, resets state. Equivalent to Ctrl+C + npm run dev.
Terminal window
# list available devices
flutter devices
# run on a specific device
flutter run -d "iPhone 16"
flutter run -d chrome
flutter run -d macos
What is the Flutter equivalent of `npm install`?
Where does your Dart application code live in a Flutter project?
Which command adds a new package to a Flutter project and updates pubspec.yaml?
Flutter's Hot Reload preserves widget state. What does Hot Restart do?
What problem does Impeller, the default renderer on Flutter 3.47, solve?