Quickstart (Flutter) • Documentation • Discord
- Supports iOS (arm64), MacOS (arm64/x64), Android (arm64), Windows (x64) (>= 10), Web/WASM
- glTF, KTX, PNG & JPEG texture support
- camera/entity manipulation with mouse (desktop) and gestures (mobile)
- skinning + morph animations
Uses the Filament PBR engine.
Use filamentVersion to select the matching Filament release when compiling
custom materials with matc:
import 'package:thermion_dart/filament_version.dart';
void main() {
print(filamentVersion); // v1.76.0
}It is also exported by package:thermion_dart/thermion_dart.dart. The constant
works with hosted, Git and path dependencies, and is the version used by the
native build hook. Recompile your custom materials when it changes.
After initializing Filament, FilamentApp.instance!.materialVersion gives the
material format number reported by matc --version. This number is distinct
from the Filament release version. Compile custom materials with matc from
the same Filament release as the application.
createMaterial rejects incompatible format versions and malformed chunk
layouts with a Dart FormatException before calling Filament's material
builder. It does not validate every payload or backend requirement; other
invalid packages can still cause a native panic.
From the command line:
flutter channel stable
flutter upgrade
flutter config --enable-native-assets In your Flutter app:
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: [
Positioned.fill(
child: ViewerWidget(
assetPath: "assets/cube.glb",
skyboxPath: "assets/default_env_skybox.ktx",
iblPath: "assets/default_env_ibl.ktx",
transformToUnitCube: true,
initialCameraPosition: Vector3(0, 0, 6),
background: Colors.blue,
manipulatorType: ManipulatorType.ORBIT,
onViewerAvailable: (viewer) async {
await Future.delayed(const Duration(seconds: 5));
await viewer.removeSkybox();
},
initial: Container(
color: Colors.red,
),
))]));
}the first time you build an app that consumes this package, the Dart native-assets build system will download static binaries from Cloudflare. This may take a few minutes (depending on which platform you are compiling for). These will be cached, so subsequent builds will be much faster.
Web builds need two files (thermion_dart.js and thermion_dart.wasm) sitting alongside your app's web/index.html. In the normal case, thermion_dart's build hook fetches them for you on flutter run/flutter build web — no extra step required:
flutter build webThe hook reads native/web/web.version, downloads the matching artifacts from Cloudflare R2, caches them under .dart_tool/thermion_dart/web/<sha>/, and copies them into your app's web/ directory. Subsequent builds are instant unless the version changes.
If you want to fetch them ahead of time (e.g. for an offline build), you can do so manually:
dart run thermion_dart:download_web # → ./web/
dart run thermion_dart:download_web -o custom # → custom/If you're modifying thermion_dart's native code and want to test on web without bumping native/web/web.version and waiting for CI to rebuild the R2 artifacts, build the emscripten target locally and opt in via your app's pubspec.yaml:
hooks:
user_defines:
thermion_dart:
web_local: true# Build the wasm (from native/web/build):
emcmake cmake ..
emmake make
# Then run/build your Flutter app:
flutter run -d chromeWhen set, the build hook copies thermion_dart.{js,wasm} from thermion_dart/native/web/build/build/out/ into your app's web/ directory instead of downloading from R2. Remove the flag (or set it to false) to go back to the pinned prebuilt.
The package:test suite runs on Chrome via a wrapper. Do not invoke dart test -p chrome directly — the multithreaded WASM build needs crossOriginIsolated (a COOP/COEP proxy), and each test file needs an HTML host that loads thermion_dart.js and the thermion_canvas. The wrapper handles both:
# from thermion_dart/
dart run tool/web_test_runner.dart --assets=../examples/assets test/texture_tests.dartIt stamps per-file test/<name>.html, starts tool/coi_proxy.dart on port 8899 (injecting the isolation headers and bridging thermion.assets / thermion.output sentinel hosts for asset reads and capture writes), runs dart test -p chrome, and prints a per-file summary.
Flags: --port=N, --timeout=DUR, --concurrency=N, --assets=DIR, --no-proxy (reuse an external proxy), --clean (delete the generated HTML on exit). With no test file arguments, it runs every test/*_test.dart and test/*_tests.dart.
test/thermion_dart.{js,wasm} are gitignored symlinks into native/web/build/build/out/, so they stay current after every make wasm.
Thermion uses the Filament Physically Based Rendering engine under the hood.
Special thanks to odd-io for sponsoring work on supporting Windows, raycasting, testing and documentation.
Thank you to the following people:
- @Hannnes1 for help migrating to
native-assets - @jarrodcolburn for documentation contributions
- @daverin for MacOS library contributions
- @LukasPoque for CI/refactoring work
- @alexmercerind for his work on integrating ANGLE textures on Flutter Windows
- @BrutalCoding for documentation fixes
- @chenriji for testing and bug fixes
- @JesperBellenbaum for Vulkan/Windows improvements
- @repentsinner for Linux/EGL/Windows stability + improvements
- @mwahnish for bug fixes and web improvements
- @aenriqu for bone animation fixes
- @mushogenshin for Android & Windows swapchain & backend fixes
- @arthur-lfn for Linux/Vulkan fixes
- @wperchinumio for detailed bug reports on memory leaks and missing features

