Skip to content

pub & pubspec.yaml

In React you manage dependencies through npm and package.json. In Flutter, pub is the package manager and pubspec.yaml is the project manifest. The registry is pub.dev instead of npmjs.com, but the workflow is the same: find a package, add it to the manifest, fetch it, import it in code.

A minimal pubspec.yaml has five sections that map directly to package.json concepts:

name: my_app
description: A Flutter application.
version: 1.0.0+1
environment:
sdk: '>=3.3.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
http: ^1.2.0
dev_dependencies:
flutter_test:
sdk: flutter
mocktail: ^1.0.4
flutter:
assets:
- assets/images/
- assets/icons/app_icon.png

name and description are identical to package.json. version uses a major.minor.patch+build format — the +1 is a build number used by app stores and has no npm equivalent. environment.sdk pins the Dart SDK range (no Node engine field in package.json does this by default, but it is the same intent). dependencies and dev_dependencies mirror npm’s dependencies and devDependencies. The flutter: block is unique — it is where you register assets so the framework can bundle them.

Flutter uses the same caret semantics as npm:

  • ^1.2.0 means >=1.2.0 <2.0.0 — compatible with the current major version.
  • ^0.4.3 means >=0.4.3 <0.5.0 — for pre-1.0 packages, the minor is the breaking boundary.
  • any accepts all versions. Use it sparingly; it makes reproducible builds fragile.
  • >=1.0.0 <2.0.0 is the explicit form that ^1.0.0 expands to.

pubspec.lock pins the resolved versions, exactly like package-lock.json or yarn.lock. Always commit it.

Terminal window
# Add a runtime dependency (like npm install http)
flutter pub add http
# Add a dev dependency (like npm install --save-dev mocktail)
flutter pub add --dev mocktail
# Fetch all dependencies after editing pubspec.yaml manually
flutter pub get
# Upgrade dependencies within their constraints
flutter pub upgrade
# Check for outdated packages
flutter pub outdated

flutter pub add http does two things in one step: it edits pubspec.yaml to add the entry under dependencies, then runs pub get to download the package. There is no separate “save” flag — the manifest is always updated.

In a React/Vite project you import images directly in JavaScript:

import logo from './assets/logo.svg';

Vite handles the bundling. In Flutter there is no bundler import. Instead, you declare asset paths in pubspec.yaml under flutter: assets:, and then reference them by string path in Dart:

Image.asset('assets/images/logo.png')

You can declare a whole directory (assets/images/) to include every file inside it, or list individual files for fine-grained control. Flutter will bundle exactly what you declare and nothing else.

Side-by-side: package.json vs pubspec.yaml

Section titled “Side-by-side: package.json vs pubspec.yaml”
React
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"react": "^18.2.0",
"axios": "^1.6.0"
},
"devDependencies": {
"@testing-library/react": "^14.0.0",
"vite": "^5.0.0"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "jest"
}
}
Flutter
name: my_app
version: 1.0.0+1
environment:
sdk: '>=3.3.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
http: ^1.2.0
dev_dependencies:
flutter_test:
sdk: flutter
mocktail: ^1.0.4
flutter:
assets:
- assets/images/
- assets/icons/app_icon.png
What is the pubspec.yaml equivalent of npm's devDependencies?
What does the version constraint "^1.2.0" mean in pubspec.yaml?
How do you add a package AND update pubspec.yaml in one command?
Where do you declare image assets in a Flutter project?