Pre-flight WASM compatibility audit for Dart and Flutter projects.
Checks your entire dependency tree before you build — identifying which packages
will block flutter build web --wasm before you spend time waiting for a failed compile.
dart pub global activate wasm_check# Analyze the current directory
wasm_check
# Analyze a specific project
wasm_check --path /path/to/your/project
# Show all packages (not just blockers)
wasm_check --verbose
# Machine-readable output for CI pipelines
wasm_check --json
# Exit with code 1 if any blockers found (for CI gating)
wasm_check --exit-code
# Only check direct dependencies (skip transitive)
wasm_check --direct-only──────────────────────────────────────────────────────────────
wasm_check · 42 packages · 2.8s
──────────────────────────────────────────────────────────────
BLOCKERS (2)
✗ flutter_secure_storage_web 1.2.1 [direct]
└─ depends on package:js (legacy JS interop — not supported in WASM)
✗ mapbox_gl 0.16.0 [transitive]
└─ depends on package:js (legacy JS interop — not supported in WASM)
COMPATIBLE (32)
✓ 32 packages confirmed WASM-compatible.
Run with --verbose to list them.
UNKNOWN (8)
? 8 packages could not be verified.
Run with --verbose to list them.
Some may use dart:html directly (undetectable via pub.dev API).
──────────────────────────────────────────────────────────────
✗ BLOCKED — 2 blockers found
· 1 direct — replace or upgrade to a WASM-compatible version.
· 1 transitive — owned by upstream packages; find alternatives.
──────────────────────────────────────────────────────────────
| Status | Meaning |
|---|---|
| BLOCKER | Confirmed WASM-incompatible. Depends on package:js (legacy JS interop). |
| COMPATIBLE | Confirmed WASM-compatible. Has wasm topic tag or uses package:web. |
| UNKNOWN | No compatibility signal found. May be fine, or may use dart:html directly. |
Direct vs. transitive blockers matter. Direct blockers are packages you listed in
your pubspec.yaml — you can upgrade or replace them. Transitive blockers are owned
by upstream packages; file issues with those maintainers or find alternatives.
# .github/workflows/wasm_check.yml
- name: Install wasm_check
run: dart pub global activate wasm_check
- name: Check WASM compatibility
run: wasm_check --exit-code --path .With --json, you can parse the output in CI scripts:
wasm_check --json | jq '.summary.blockers'import 'package:wasm_check/wasm_check.dart';
Future<void> main() async {
final report = await WasmAudit.analyze(projectPath: '.');
print('Blockers: ${report.blockers.length}');
print('Can proceed: ${report.canProceed}');
for (final dep in report.blockers) {
final reason = switch (dep.compatibility) {
Incompatible(:final reason) => reason,
_ => 'unknown reason',
};
print('${dep.name} ${dep.version}: $reason');
}
}wasm_check queries the pub.dev REST API for each
hosted package in your pubspec.lock and checks two signals:
Compatible if the package:
- Has the
wasmtopic tag on pub.dev, or - Lists
package:webas a dependency (the WASM-compatible interop library)
Incompatible if the package:
- Lists
package:jsas a dependency (the legacy interop library that doesn't compile to WASM)
Unknown if neither signal is present.
- Packages that use
dart:htmldirectly (withoutpackage:js) will appear as UNKNOWN rather than INCOMPATIBLE.dart:htmlis a Dart SDK library and doesn't appear in a package'spubspec.yamldependencies. - Dev dependencies (
dev_dependencies:) are not analyzed — they don't compile into WASM output. sdk,path, andgitdependencies are skipped.- Detection accuracy depends on pub.dev package authors correctly tagging their
packages and migrating to
package:web.