react-native-model-viewer-webview 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,112 @@
1
+ # Compatibility And Support Policy
2
+
3
+ This package is a WebView bridge. Compatibility depends on:
4
+
5
+ - React
6
+ - React Native
7
+ - `react-native-webview`
8
+ - the Android System WebView or iOS WKWebView
9
+ - Google's `<model-viewer>` web component
10
+ - how the consuming app bundles `.glb` and `.gltf` files
11
+
12
+ ## Supported Peer Ranges
13
+
14
+ ```json
15
+ {
16
+ "react": ">=18",
17
+ "react-native": ">=0.72",
18
+ "react-native-webview": ">=13"
19
+ }
20
+ ```
21
+
22
+ These ranges describe the intended support window, not a claim that every patch
23
+ release has been manually device-tested.
24
+
25
+ ## Tested In This Repository
26
+
27
+ Current local integration target:
28
+
29
+ - Expo SDK 54
30
+ - React 19.1
31
+ - React Native 0.81
32
+ - `react-native-webview` 13.15
33
+ - TypeScript 5.9
34
+
35
+ Automated checks validate:
36
+
37
+ - package utility behavior with Node's built-in test runner
38
+ - package source typechecking when package dependencies are installed
39
+ - package tarball contents with `npm pack --dry-run`
40
+ - integration with this repository's Expo app through TypeScript and Expo lint
41
+
42
+ ## Not Guaranteed
43
+
44
+ The package does not claim blanket support for all React Native versions.
45
+
46
+ Explicit limitations:
47
+
48
+ - React Native below `0.72` is unsupported.
49
+ - WebView bugs in specific Android System WebView or iOS versions may affect
50
+ rendering.
51
+ - Local `.glb` bundling depends on the consuming app's Metro config.
52
+ - Device rendering is not fully proven by unit tests.
53
+ - AR behavior is not a supported package guarantee.
54
+ - Long lists of many WebViews may have memory/performance problems.
55
+
56
+ ## Compatibility Review Checklist
57
+
58
+ Before expanding peer ranges or claiming support for a platform/version:
59
+
60
+ - install the package in a clean Expo app
61
+ - render a remote `.glb`
62
+ - render a bundled `.glb`
63
+ - verify `onModelLoaded`
64
+ - verify a failed model URL triggers `onModelError`
65
+ - test Android physical device or emulator
66
+ - test iOS physical device or simulator if claiming iOS support
67
+ - update this document with the tested versions
68
+
69
+ ## Recommended Consumer Setup
70
+
71
+ For Expo apps:
72
+
73
+ ```bash
74
+ npx expo install react-native-model-viewer-webview react-native-webview
75
+ ```
76
+
77
+ For bare React Native apps:
78
+
79
+ ```bash
80
+ npm install react-native-model-viewer-webview react-native-webview
81
+ ```
82
+
83
+ For local `.glb` imports, add `glb` and `gltf` to Metro's asset extensions.
84
+ See the package README for an example.
85
+
86
+ ## Local Symlink And `file:` Dependency Setup
87
+
88
+ When developing this package from a local checkout, avoid letting Metro load
89
+ peer dependencies from the package's own `node_modules`.
90
+
91
+ This package keeps `react`, `react-native`, and `react-native-webview` as peer
92
+ dependencies. A published npm install does not include this package's
93
+ development `node_modules`, but a local symlink or `file:../package` install can
94
+ expose them to Metro. If Metro bundles a package-local copy of React, the app
95
+ can fail with an invalid hook call even when both copies have the same version.
96
+
97
+ For local development, configure the consuming app's Metro setup to:
98
+
99
+ - watch the local package folder
100
+ - resolve `react`, `react-native`, and `react-native-webview` from the app's
101
+ `node_modules`
102
+ - exclude package-local dev copies of those peer dependencies from Metro's file
103
+ map
104
+
105
+ ## Dependency Update Policy
106
+
107
+ - Keep `react-native-webview` peer range broad unless a real incompatibility is
108
+ found.
109
+ - Keep dev dependencies pinned to one known-good React Native stack.
110
+ - Use CI and device smoke tests before raising support claims.
111
+ - If `<model-viewer>` changes behavior, update README examples and tests before
112
+ changing the default CDN URL.
@@ -0,0 +1,126 @@
1
+ # How It Works
2
+
3
+ `react-native-model-viewer-webview` is a small adapter around three pieces:
4
+
5
+ 1. React Native renders a `react-native-webview` instance.
6
+ 2. The package generates a complete HTML document containing Google's
7
+ `<model-viewer>` web component.
8
+ 3. The WebView sends structured status messages back to React Native through
9
+ `window.ReactNativeWebView.postMessage`.
10
+
11
+ It does not implement a renderer. The renderer is the platform WebView running
12
+ `<model-viewer>`.
13
+
14
+ ## Architecture
15
+
16
+ ```mermaid
17
+ flowchart LR
18
+ RN["React Native screen"] --> Component["ModelViewerWebView"]
19
+ Component --> Source["resolveModelSourceUri"]
20
+ Component --> HTML["buildModelViewerHtml"]
21
+ HTML --> WebView["react-native-webview"]
22
+ WebView --> ModelViewer["<model-viewer>"]
23
+ ModelViewer --> Events["load/error events"]
24
+ Events --> Bridge["postMessage JSON status"]
25
+ Bridge --> Component
26
+ ```
27
+
28
+ ## Why WebView
29
+
30
+ Native 3D stacks are better when 3D is the product. This package exists for the
31
+ opposite case: 3D is a preview inside a normal app screen.
32
+
33
+ Using WebView gives us:
34
+
35
+ - the same high-level `<model-viewer>` API used on the web
36
+ - simple camera controls and auto-rotate
37
+ - GLB/glTF support delegated to a maintained web component
38
+ - a small React Native API surface
39
+ - compatibility with Expo and bare React Native apps that already support
40
+ `react-native-webview`
41
+
42
+ It also means:
43
+
44
+ - startup cost is higher than a native view
45
+ - WebView memory matters in long lists
46
+ - WebView gesture behavior may need screen-level tuning
47
+ - rendering quality and bugs depend on the platform WebView
48
+
49
+ ## Source Resolution
50
+
51
+ `resolveModelSourceUri` accepts:
52
+
53
+ - string URLs, including `https:`, `data:`, and `file:`
54
+ - React Native static asset module numbers from `require(...)`
55
+ - asset-like objects with `localUri` and/or `uri`
56
+
57
+ For objects, `localUri` wins over `uri` because local files are preferred after
58
+ an Expo asset has been downloaded.
59
+
60
+ For module numbers, the package calls `Image.resolveAssetSource`. React Native
61
+ does not have a dedicated generic asset resolver with equivalent availability,
62
+ so `Image.resolveAssetSource` is used as the practical stable option.
63
+
64
+ ## HTML Generation
65
+
66
+ `buildModelViewerHtml` creates a full HTML document with:
67
+
68
+ - viewport metadata
69
+ - a `<model-viewer>` script tag
70
+ - WebView status bridge helpers
71
+ - a full-size `<model-viewer>` element
72
+ - generated model-viewer attributes
73
+
74
+ Attribute values are HTML-escaped. Attribute names must match a conservative
75
+ safe-name pattern before they are emitted. Basic CSS color values are sanitized
76
+ to avoid injecting arbitrary CSS into generated HTML.
77
+
78
+ ## Script Loading
79
+
80
+ By default, the HTML loads:
81
+
82
+ ```text
83
+ https://ajax.googleapis.com/ajax/libs/model-viewer/4.2.0/model-viewer.min.js
84
+ ```
85
+
86
+ Apps that need offline behavior can provide either:
87
+
88
+ - `modelViewerScriptUrl`, such as a `file:` URL to a bundled script
89
+ - `modelViewerScript`, an inline module script string
90
+
91
+ Inline script content escapes closing `</script>` sequences to avoid breaking
92
+ the generated document.
93
+
94
+ ## Event Flow
95
+
96
+ The generated HTML posts JSON messages:
97
+
98
+ ```json
99
+ { "type": "dom-ready", "message": "Model viewer DOM ready" }
100
+ ```
101
+
102
+ Important event types:
103
+
104
+ - `dom-ready`
105
+ - `model-loaded`
106
+ - `model-error`
107
+ - `page-error`
108
+
109
+ `ModelViewerWebView` parses these messages and exposes:
110
+
111
+ - `onStatus` for every status
112
+ - `onModelLoaded` for `model-loaded`
113
+ - `onModelError` for statuses ending in `error`
114
+
115
+ Raw or malformed WebView messages are converted into `page-error` statuses.
116
+
117
+ ## What This Package Does Not Do
118
+
119
+ - It does not implement native rendering.
120
+ - It does not expose a scene graph.
121
+ - It does not manage physics, shaders, or multiple model scenes.
122
+ - It does not guarantee AR support.
123
+ - It does not guarantee identical rendering across Android and iOS WebViews.
124
+
125
+ Those are native renderer concerns. Use Filament, React Three Fiber Native, or
126
+ Expo GLView for those workloads.
@@ -0,0 +1,169 @@
1
+ # Release And Maintenance Guide
2
+
3
+ This guide describes how to publish and maintain
4
+ `react-native-model-viewer-webview`.
5
+
6
+ The preferred release path is GitHub Actions plus npm Trusted Publishing. npm
7
+ documents Trusted Publishing as an OIDC-based flow that avoids long-lived npm
8
+ tokens and automatically generates provenance for supported public packages.
9
+
10
+ ## Release Workflow Summary
11
+
12
+ 1. Land changes through a PR.
13
+ 2. Run package checks and manual device smoke tests.
14
+ 3. Update `CHANGELOG.md`.
15
+ 4. Bump `package.json` version.
16
+ 5. Create a GitHub release or release tag.
17
+ 6. Let GitHub Actions publish to npm through Trusted Publishing.
18
+ 7. Verify the npm package page and install from a clean app.
19
+
20
+ ## One-Time npm Setup
21
+
22
+ On npmjs.com, configure a trusted publisher for the package:
23
+
24
+ - Publisher: GitHub Actions
25
+ - Organization/user: the GitHub owner
26
+ - Repository: the repository name
27
+ - Workflow filename: `release.yml`
28
+ - Environment name: `npm`, if you keep the workflow environment as configured
29
+ - Allowed action: `npm publish`
30
+
31
+ Trusted Publishing requires npm CLI `11.5.1` or later and Node `22.14.0` or
32
+ later in the publishing workflow.
33
+
34
+ If Trusted Publishing cannot be used, create an npm automation token and store
35
+ it as `NPM_TOKEN`, then update the release workflow to use that token. Prefer
36
+ Trusted Publishing whenever possible.
37
+
38
+ ## Versioning
39
+
40
+ Use semantic versioning:
41
+
42
+ - Patch: documentation fixes, internal test changes, bug fixes that do not
43
+ change public behavior.
44
+ - Minor: new props, new source forms, new supported options.
45
+ - Major: breaking prop changes, changed defaults, removed APIs, peer range drops.
46
+
47
+ Before `1.0.0`, minor releases may include breaking changes, but the changelog
48
+ must say so clearly.
49
+
50
+ ## Manual Pre-Release Checklist
51
+
52
+ From the package repository root:
53
+
54
+ ```bash
55
+ npm install
56
+ npm run check
57
+ ```
58
+
59
+ From a consuming Expo or React Native app, when validating integration:
60
+
61
+ ```bash
62
+ npm install
63
+ npx tsc --noEmit
64
+ npm run lint
65
+ ```
66
+
67
+ Device checks:
68
+
69
+ - remote `.glb` renders on Android
70
+ - bundled `.glb` renders on Android
71
+ - bad model URL triggers `onModelError`
72
+ - iOS render check is completed before claiming iOS support
73
+
74
+ Documentation checks:
75
+
76
+ - README examples match current API
77
+ - `docs-site/index.html` examples match current API
78
+ - `docs-site/llms.txt` links point to public docs or GitHub URLs
79
+ - `docs-site/sitemap.xml` and `docs-site/robots.txt` reference the canonical
80
+ Pages URL
81
+ - docs-site JSON-LD matches visible content and package metadata
82
+ - Open Graph and Twitter card metadata point to `docs-site/og-image.svg`
83
+ - `docs/COMPATIBILITY.md` lists tested versions
84
+ - `CHANGELOG.md` has the release entry
85
+ - package tarball contents from `npm pack --dry-run` contain only intended files
86
+ - GitHub Pages workflow deploys from `docs-site`
87
+
88
+ ## Release PR Steps
89
+
90
+ 1. Move `CHANGELOG.md` entries from `Unreleased` into a version heading.
91
+ 2. Update `package.json` version.
92
+ 3. Run all local checks.
93
+ 4. Open a PR.
94
+ 5. Wait for CI.
95
+ 6. Merge.
96
+
97
+ ## Publishing With Tags
98
+
99
+ The release workflow listens for tags matching:
100
+
101
+ ```text
102
+ v*
103
+ ```
104
+
105
+ For version `0.1.0`:
106
+
107
+ ```bash
108
+ git tag v0.1.0
109
+ git push origin v0.1.0
110
+ ```
111
+
112
+ The workflow verifies that the tag suffix matches `package.json`'s version
113
+ before publishing.
114
+
115
+ ## Publishing With workflow_dispatch
116
+
117
+ The release workflow can also be started manually from GitHub Actions.
118
+
119
+ Use this only after:
120
+
121
+ - the version bump is already merged
122
+ - CI is green
123
+ - npm Trusted Publishing is configured
124
+
125
+ ## Post-Publish Verification
126
+
127
+ After publishing:
128
+
129
+ ```bash
130
+ npm view react-native-model-viewer-webview version
131
+ npm view react-native-model-viewer-webview dist.integrity
132
+ ```
133
+
134
+ Then install it in a clean Expo app:
135
+
136
+ ```bash
137
+ npx create-expo-app model-viewer-publish-smoke
138
+ cd model-viewer-publish-smoke
139
+ npx expo install react-native-model-viewer-webview react-native-webview
140
+ ```
141
+
142
+ Render the remote model from `example/App.tsx`. If the release claims bundled
143
+ asset support, also test a local `.glb`.
144
+
145
+ ## Docs Site Deployment
146
+
147
+ The docs site is a dependency-free static site in `docs-site`. GitHub Pages is
148
+ deployed by `.github/workflows/pages.yml` on pushes to `main` that touch the
149
+ docs site or Pages workflow.
150
+
151
+ Before relying on the public docs link:
152
+
153
+ - enable GitHub Pages with GitHub Actions as the source in repository settings
154
+ - verify the workflow finishes successfully
155
+ - open the Pages URL and confirm the model preview loads
156
+ - check `docs-site/llms.txt` at the Pages root
157
+
158
+ ## Maintenance Rhythm
159
+
160
+ Monthly or before meaningful releases:
161
+
162
+ - check latest `react-native-webview` release notes
163
+ - check Expo SDK compatibility
164
+ - rerun Android smoke tests
165
+ - review open issues for WebView/platform-specific failures
166
+ - keep README limitations honest
167
+
168
+ Do not expand compatibility claims based only on typechecks. Use real device
169
+ rendering before changing support language.
@@ -0,0 +1,41 @@
1
+ import { useState } from "react";
2
+ import { SafeAreaView, Text, View } from "react-native";
3
+
4
+ import {
5
+ ModelViewerWebView,
6
+ type ModelViewerStatus,
7
+ } from "react-native-model-viewer-webview";
8
+
9
+ const REMOTE_MODEL =
10
+ "https://modelviewer.dev/shared-assets/models/Astronaut.glb";
11
+
12
+ export default function App() {
13
+ const [status, setStatus] = useState("Loading model...");
14
+
15
+ function handleStatus(nextStatus: ModelViewerStatus) {
16
+ setStatus(nextStatus.message ?? nextStatus.type);
17
+ }
18
+
19
+ return (
20
+ <SafeAreaView style={{ flex: 1, backgroundColor: "#ffffff" }}>
21
+ <View style={{ flex: 1, padding: 16, gap: 12 }}>
22
+ <Text style={{ fontSize: 20, fontWeight: "700" }}>
23
+ React Native Model Viewer WebView
24
+ </Text>
25
+ <ModelViewerWebView
26
+ modelSource={REMOTE_MODEL}
27
+ onStatus={handleStatus}
28
+ style={{ flex: 1, minHeight: 360 }}
29
+ htmlOptions={{
30
+ autoRotate: true,
31
+ cameraControls: true,
32
+ cameraOrbit: "0deg 65deg 3m",
33
+ exposure: 1,
34
+ shadowIntensity: 0.4,
35
+ }}
36
+ />
37
+ <Text>{status}</Text>
38
+ </View>
39
+ </SafeAreaView>
40
+ );
41
+ }
@@ -0,0 +1,43 @@
1
+ # Example
2
+
3
+ This folder contains a minimal Expo screen for smoke-testing the package with a
4
+ remote GLB.
5
+
6
+ ```bash
7
+ npx create-expo-app model-viewer-example
8
+ cd model-viewer-example
9
+ npx expo install react-native-model-viewer-webview react-native-webview
10
+ ```
11
+
12
+ Replace the generated `App.tsx` with this folder's `App.tsx`, then run:
13
+
14
+ ```bash
15
+ npx expo start
16
+ ```
17
+
18
+ ## Testing Bundled GLB Files
19
+
20
+ For local `.glb` imports, configure Metro:
21
+
22
+ ```js
23
+ const { getDefaultConfig } = require("expo/metro-config");
24
+
25
+ const config = getDefaultConfig(__dirname);
26
+
27
+ config.resolver.assetExts = [
28
+ ...config.resolver.assetExts,
29
+ "glb",
30
+ "gltf",
31
+ ];
32
+
33
+ module.exports = config;
34
+ ```
35
+
36
+ Then use:
37
+
38
+ ```tsx
39
+ <ModelViewerWebView modelSource={require("./assets/car.glb")} />
40
+ ```
41
+
42
+ Always test bundled assets on a real Android or iOS device before publishing a
43
+ release that claims bundled model support.
package/llms.txt ADDED
@@ -0,0 +1,79 @@
1
+ # react-native-model-viewer-webview
2
+
3
+ > A small React Native and Expo package for rendering simple GLB/glTF previews
4
+ > with Google's `<model-viewer>` web component inside `react-native-webview`.
5
+
6
+ Use this package when an app needs an inspectable 3D asset preview with orbit
7
+ controls, auto-rotate, and load/error callbacks, but does not need a native 3D
8
+ engine. For native rendering, custom scenes, shaders, physics, or AR, prefer
9
+ Filament, React Three Fiber Native, Three.js, or Expo GLView.
10
+
11
+ ## Essential docs
12
+
13
+ - [README](./README.md): install, quick start, props, tradeoffs, and
14
+ pre-publish checklist.
15
+ - [How it works](./docs/HOW_IT_WORKS.md): WebView bridge, source resolution,
16
+ HTML generation, script loading, and event flow.
17
+ - [Compatibility](./docs/COMPATIBILITY.md): peer ranges, tested versions,
18
+ platform notes, and limitations.
19
+ - [Agent usage](./docs/AGENT_USAGE.md): how AI agents should consume the
20
+ packaged `SKILL.md`, `AGENTS.md`, and this file.
21
+ - [Release guide](./docs/RELEASE.md): versioning, CI, npm Trusted Publishing,
22
+ and maintenance instructions.
23
+ - [Contributing](./CONTRIBUTING.md): scope, checks, testing expectations, and
24
+ PR checklist.
25
+ - [Security](./SECURITY.md): vulnerability reporting and support policy.
26
+ - [Changelog](./CHANGELOG.md): release history.
27
+
28
+ ## Agent assets
29
+
30
+ - [Package agent instructions](./AGENTS.md): stable coding-agent guidance for
31
+ this package.
32
+ - [Portable Agent Skill](./agent-skills/react-native-model-viewer-webview/SKILL.md):
33
+ installable skill entrypoint for skills-compatible agents.
34
+ - [Skill API reference](./agent-skills/react-native-model-viewer-webview/references/api.md):
35
+ compact API surface for agents.
36
+
37
+ ## Claude Code
38
+
39
+ Claude Code can use the portable skill after it is copied or symlinked to one of
40
+ Claude's filesystem skill locations:
41
+
42
+ - `~/.claude/skills/react-native-model-viewer-webview/SKILL.md`
43
+ - `.claude/skills/react-native-model-viewer-webview/SKILL.md`
44
+
45
+ Claude Agent SDK users should load user/project setting sources and enable
46
+ `skills="all"` or the specific `react-native-model-viewer-webview` skill.
47
+
48
+ ## Quick install
49
+
50
+ Expo:
51
+
52
+ ```bash
53
+ npx expo install react-native-model-viewer-webview react-native-webview
54
+ ```
55
+
56
+ Bare React Native:
57
+
58
+ ```bash
59
+ npm install react-native-model-viewer-webview react-native-webview
60
+ ```
61
+
62
+ If the app already has a compatible `react-native-webview`, install only
63
+ `react-native-model-viewer-webview`.
64
+
65
+ ## Minimal usage
66
+
67
+ ```tsx
68
+ import { ModelViewerWebView } from "react-native-model-viewer-webview";
69
+
70
+ export function Preview() {
71
+ return (
72
+ <ModelViewerWebView
73
+ modelSource="https://example.com/model.glb"
74
+ style={{ height: 320 }}
75
+ htmlOptions={{ autoRotate: true, cameraControls: true }}
76
+ />
77
+ );
78
+ }
79
+ ```
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "react-native-model-viewer-webview",
3
+ "version": "0.1.0",
4
+ "description": "A WebView-backed GLB and glTF model viewer for React Native and Expo.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/adityabhattad2021/react-native-model-viewer-webview.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/adityabhattad2021/react-native-model-viewer-webview/issues"
12
+ },
13
+ "homepage": "https://adityabhattad2021.github.io/react-native-model-viewer-webview/",
14
+ "engines": {
15
+ "node": ">=20"
16
+ },
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "react-native": "dist/index.js",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "react-native": "./dist/index.js",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "AGENTS.md",
30
+ "agent-skills",
31
+ "dist",
32
+ "example",
33
+ "src",
34
+ "CHANGELOG.md",
35
+ "CONTRIBUTING.md",
36
+ "LICENSE",
37
+ "llms.txt",
38
+ "README.md",
39
+ "SECURITY.md",
40
+ "docs",
41
+ "tsconfig.json"
42
+ ],
43
+ "sideEffects": false,
44
+ "scripts": {
45
+ "check": "npm test && npm run typecheck && npm run pack:dry-run",
46
+ "test": "node --test test/*.test.js",
47
+ "pack:dry-run": "npm pack --dry-run",
48
+ "typecheck": "tsc --noEmit"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "keywords": [
54
+ "react-native",
55
+ "expo",
56
+ "3d",
57
+ "glb",
58
+ "gltf",
59
+ "model-viewer",
60
+ "modelviewer",
61
+ "3d-model",
62
+ "webview"
63
+ ],
64
+ "peerDependencies": {
65
+ "react": ">=18",
66
+ "react-native": ">=0.72",
67
+ "react-native-webview": ">=13"
68
+ },
69
+ "devDependencies": {
70
+ "@types/react": "~19.1.0",
71
+ "react": "19.1.0",
72
+ "react-native": "0.81.5",
73
+ "react-native-webview": "13.15.0",
74
+ "typescript": "~5.9.2"
75
+ }
76
+ }