The AI-first 3D & AR SDK for Jetpack Compose, SwiftUI and the web.
The AI-first 3D & AR SDK for Jetpack Compose, SwiftUI and the web.
Declarative 3D and AR for app developers who want a model on screen, or in the room, without a game engine: Filament + ARCore on Android, RealityKit + ARKit on Apple, Filament.js + WebXR in the browser — with Flutter, React Native and Compose Multiplatform bridges on top. Open source, Apache 2.0.
AI-first means one thing here: an assistant that reads llms.txt or
the MCP server writes SceneView code that works on the first try. When it doesn't, the
API or the doc gets fixed.
The demo apps are built from samples/. Any demo opens straight from a link:
https://sceneview.github.io/open?demo=<id>. Start with
Cosmos, the galaxy the catalogue opens on, or
Rerun AR Replay, a real AR session rebuilt in 3D.
One minimal, working example per platform. The full reference for each is in
llms.txt.
// build.gradle.kts
implementation("io.github.sceneview:sceneview:4.56.0")
@Composable
fun ModelScreen() {
SceneView(modifier = Modifier.fillMaxSize()) { // orbit camera + default lighting
rememberModelInstance(modelLoader, "models/helmet.glb")?.let { instance ->
ModelNode(modelInstance = instance, scaleToUnits = 1.0f, autoAnimate = true)
}
}
}
models/helmet.glb lives in src/main/assets/. rememberModelInstance returns null until the
model is loaded, then recomposes. Never call modelLoader.createModel* from a background
coroutine: Filament calls must run on the main thread, and rememberModelInstance handles that.
// build.gradle.kts
implementation("io.github.sceneview:arsceneview:4.56.0") // includes the 3D module
@Composable
fun ARScreen() {
var anchor by remember { mutableStateOf<Anchor?>(null) }
ARSceneView(
modifier = Modifier.fillMaxSize(),
planeRenderer = true,
onSessionUpdated = { _, frame ->
if (anchor == null) {
anchor = frame.getUpdatedPlanes()
.firstOrNull { it.type == Plane.Type.HORIZONTAL_UPWARD_FACING }
?.let { frame.createAnchorOrNull(it.centerPose) }
}
}
) {
val helmet = rememberModelInstance(modelLoader, "models/helmet.glb")
anchor?.let { a ->
AnchorNode(anchor = a) {
helmet?.let { ModelNode(modelInstance = it, scaleToUnits = 0.5f) }
}
}
}
}
Plane detected → anchor set → Compose recomposes → the model appears. AR state is just Kotlin
state. For placement without a tap, grounded and gesture-ready, start from
AutoPlacementScene (see llms.txt).
Swift Package Manager: https://github.com/sceneview/sceneview.git, from 4.39.0.
import SwiftUI
import SceneViewSwift
struct ModelScreen: View {
@State private var model: ModelNode?
var body: some View {
SceneView { root in
if let model { root.addChild(model.entity) }
}
.contentID(model != nil) // re-run the builder once the model has loaded
.environment(.studio)
.cameraControls(.orbit)
.task { model = try? await ModelNode.load("helmet.usdz") }
}
}
The content closure runs once unless its .contentID(_:) changes: without that line, a model
that finishes loading after the scene appears is never added.
<canvas id="viewer" style="width: 100%; height: 480px"></canvas>
<script src="https://cdn.jsdelivr.net/gh/sceneview/sceneview@v4.56.0/website-static/js/filament/filament.js"></script>
<script src="https://cdn.jsdelivr.net/gh/sceneview/sceneview@v4.56.0/website-static/js/sceneview.js"></script>
<script> SceneView.modelViewer("viewer", "model.glb") </script>
// commonMain dependencies
implementation("io.github.sceneview:sceneview-compose:4.56.0")
SceneViewer(model = ModelSource.Asset("models/helmet.glb"), modifier = Modifier.fillMaxSize())
A viewer by design — load, orbit, light, tap; no AR. Scope and the one-time iOS setup:
sceneview-compose/.
// pubspec.yaml → flutter_sceneview: ^4.56.0
final controller = SceneViewController();
SceneView(
controller: controller,
onViewCreated: () => controller.loadModel(
const ModelNode(modelPath: 'models/helmet.glb'),
),
)
// npm install @sceneview-sdk/react-native
import { SceneView } from '@sceneview-sdk/react-native';
<SceneView
style={{ flex: 1 }}
modelNodes={[{ src: 'models/helmet.glb', position: [0, 0, -2] }]}
cameraControlMode="orbit"
/>
Flutter and React Native bridge a subset of the native API — see
flutter/ and
react-native/ for what is covered.
claude mcp add sceneview -- npx -y sceneview-mcp # Claude Code
codex mcp add sceneview -- npx -y sceneview-mcp # Codex
Then ask: "Add a 3D model viewer to my Compose screen." Every other client is in Use with AI.
Each row is a published package plus an app or page you can open today, backed by a real capture of it.
| Platform | Status | Install | Open it | Capture |
|---|---|---|---|---|
| Android | Shipped · Stable | Maven Central | Google Play | |
| iOS | Shipped · Alpha | Swift Package | App Store | |
| Web | Shipped · Alpha | npm sceneview-web | Live web demo |
Shipped means released and publicly reachable; the second word is the API maturity. The other platforms in the table below join this section once a capture backs them.
| Platform | Renderer | Framework | Status |
|---|---|---|---|
| Android | Filament | Jetpack Compose | Stable |
| Android TV | Filament | Compose TV | Alpha |
| iOS / macOS / visionOS | RealityKit | SwiftUI | Alpha |
| Web | Filament.js (WebGL2 / WASM) | JavaScript + Kotlin/JS | Alpha |
| Compose Multiplatform | Filament (Android, desktop) · RealityKit (iOS) | sceneview-compose | Alpha — viewer subset |
| Desktop (JVM) | Filament, via filament-kmp | Compose Desktop (sceneview-compose) | Alpha |
| Flutter | Native per platform | PlatformView | Alpha |
| React Native | Native per platform | Fabric | Alpha |
| AI assistants | — | llms.txt, MCP server, skills | Stable |
| Platform | Coordinate |
|---|---|
| Android 3D | io.github.sceneview:sceneview:4.56.0 |
| Android AR | io.github.sceneview:arsceneview:4.56.0 |
| Compose Multiplatform | io.github.sceneview:sceneview-compose:4.56.0 |
| KMP core only (math, collision, physics) | io.github.sceneview:sceneview-core:4.56.0 |
| Apple (SPM) | https://github.com/sceneview/sceneview.git, from 4.39.0 |
| Web, script tag | the two <script> tags in Web |
| Web, bundler (Kotlin/JS) | npm install sceneview-web — see SceneView Web |
| Flutter | flutter_sceneview on pub.dev |
| React Native | @sceneview-sdk/react-native on npm |
| AI assistants | npx -y sceneview-mcp — see Use with AI |
Everything an assistant needs to write SceneView code ships with the SDK:
llms.txt — the complete API reference in one file: composables, every node
type, threading rules, recipes. Its Kotlin snippets are compiled in CI. Served at
https://sceneview.github.io/llms.txt for tools without MCP support.AGENTS.md (Codex, Cursor, GitHub Copilot, Gemini in Android Studio and
others), CLAUDE.md (Claude Code), .github/copilot-instructions.md, and .cursorrules for
older Cursor versions.validate_code (checks a snippet against the real public API before you run it),
get_node_reference (the exact node signature, not an invented one), list_samples /
get_sample (38 samples to start from), and get_setup / get_ar_setup (project wiring).sceneview is a GitHub repository, indexed on Flowy in the Mobile category. Flowy has no install command for it. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it