diff --git a/examples/mobile-client/text-chat/.env.example b/examples/mobile-client/text-chat/.env.example
new file mode 100644
index 00000000..5c3949fe
--- /dev/null
+++ b/examples/mobile-client/text-chat/.env.example
@@ -0,0 +1 @@
+EXPO_PUBLIC_FISHJAM_ID=
diff --git a/examples/mobile-client/text-chat/.gitignore b/examples/mobile-client/text-chat/.gitignore
new file mode 100644
index 00000000..0206b71f
--- /dev/null
+++ b/examples/mobile-client/text-chat/.gitignore
@@ -0,0 +1,39 @@
+# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
+
+# dependencies
+node_modules/
+
+# Expo
+.expo/
+dist/
+web-build/
+
+# Native
+*.orig.*
+*.jks
+*.p8
+*.p12
+*.key
+*.mobileprovision
+
+# Metro
+.metro-health-check*
+
+# debug
+npm-debug.*
+yarn-debug.*
+yarn-error.*
+
+# macOS
+.DS_Store
+*.pem
+
+# local env files
+.env*.local
+
+# typescript
+*.tsbuildinfo
+android/*
+ios/*
+.env
+.cursor/
diff --git a/examples/mobile-client/text-chat/.prettierrc b/examples/mobile-client/text-chat/.prettierrc
new file mode 100644
index 00000000..1c5e9660
--- /dev/null
+++ b/examples/mobile-client/text-chat/.prettierrc
@@ -0,0 +1,3 @@
+{
+ "printWidth": 80
+}
diff --git a/examples/mobile-client/text-chat/App.tsx b/examples/mobile-client/text-chat/App.tsx
new file mode 100644
index 00000000..8cca7b35
--- /dev/null
+++ b/examples/mobile-client/text-chat/App.tsx
@@ -0,0 +1,19 @@
+import React from "react";
+import { NavigationContainer } from "@react-navigation/native";
+import { SafeAreaProvider } from "react-native-safe-area-context";
+import { FishjamProvider } from "@fishjam-cloud/react-native-client";
+import RootNavigation from "./navigation/RootNavigation";
+
+const App = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default App;
diff --git a/examples/mobile-client/text-chat/README.md b/examples/mobile-client/text-chat/README.md
new file mode 100644
index 00000000..daaaa66d
--- /dev/null
+++ b/examples/mobile-client/text-chat/README.md
@@ -0,0 +1,141 @@
+# Text Chat Example
+
+A React Native mobile app demonstrating real-time text messaging using [Fishjam Cloud](https://fishjam.io/) data channels. This example shows how to implement peer-to-peer text chat functionality in a mobile application using the Fishjam Cloud React Native SDK.
+
+## Features
+
+- Join a room with a custom room name and user name
+- Real-time text messaging between participants using WebRTC data channels
+- Reliable message delivery with automatic reconnection
+- Message history with sender names and timestamps
+
+## Getting Started
+
+### Prerequisites
+
+- [Node.js](https://nodejs.org/) (v18 or newer recommended)
+- [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/)
+- [Expo](https://docs.expo.dev/get-started/installation/): You do **not** need to install Expo CLI globally. Use `npx expo` to run Expo commands.
+
+### Installation
+
+1. **Clone the repository:**
+
+ ```sh
+ git clone https://github.com/fishjam-cloud/web-client-sdk.git
+ cd web-client-sdk
+ ```
+
+2. **Install dependencies:**
+
+ ```sh
+ yarn install
+ ```
+
+3. **Build the project:**
+
+ ```sh
+ yarn build
+ ```
+
+4. **Set up environment variables:**
+ - Create a `.env` file in the `examples/mobile-client/text-chat` directory:
+ ```env
+ EXPO_PUBLIC_FISHJAM_ID=
+ ```
+ - _You can obtain your Fishjam ID at [https://fishjam.io/app/](https://fishjam.io/app/)._
+ - You can also copy `.env.example` as a starting point:
+ ```sh
+ cp .env.example .env
+ ```
+
+5. **Prebuild native files:**
+ ```sh
+ cd examples/mobile-client/text-chat
+ npx expo prebuild --clean
+ ```
+ > [!NOTE]
+ > Be sure to run `npx expo prebuild` and not `yarn prebuild` as there's an issue with path generation for the `ios/.xcode.env.local` file
+
+### Running the App
+
+- **Start the Expo development server:**
+
+ ```sh
+ cd examples/mobile-client/text-chat
+ yarn start
+ ```
+
+- **Run on Android:**
+
+ ```sh
+ yarn android
+ ```
+
+- **Run on iOS:**
+ ```sh
+ yarn ios
+ ```
+
+## Usage
+
+1. Enter a room name and your user name on the Home screen.
+2. Tap **Connect** to join the room and initialize the data channel.
+3. Once connected, you can send and receive text messages in real-time.
+4. Messages from other participants will appear automatically.
+5. Tap **Leave** to disconnect from the room.
+
+## What This Demo Shows
+
+This example demonstrates how to use Fishjam Cloud's data channel functionality for real-time text messaging:
+
+- **Data Channel Initialization**: Shows how to initialize a reliable data channel after connecting to a Fishjam room
+- **Message Publishing**: Demonstrates encoding and sending JSON messages via the data channel using `publishData`
+- **Message Subscription**: Shows how to subscribe to incoming messages and decode them using `subscribeData`
+- **Peer-to-Peer Communication**: All messages are sent directly between peers using WebRTC data channels, without going through a server
+- **Reliable Delivery**: Uses reliable data channels to ensure messages are delivered in order
+
+## Architecture Overview
+
+- **React Native + Expo**: Cross-platform mobile app framework
+- **Fishjam Cloud SDK**: Handles WebRTC peer connections and data channel management
+- **Data Channels**: WebRTC data channels for peer-to-peer text messaging
+- **TypeScript**: Provides type safety and better developer experience
+
+## Troubleshooting & FAQ
+
+- **App fails to connect to a room:**
+ - Ensure your `.env` file is present and `EXPO_PUBLIC_FISHJAM_ID` is set correctly
+ - Check your network connection
+ - Review logs in the Metro/Expo console for errors
+
+- **Messages not appearing:**
+ - Make sure multiple participants have joined the same room
+ - Check that the data channel has initialized successfully (watch for "Opening data channel..." status)
+ - Verify both devices are connected to the internet
+
+- **Data channel errors:**
+ - Ensure you're using a recent version of the Fishjam SDK
+ - Check that both peers support data channels (most modern devices do)
+ - Review error messages in the app's status display
+
+## Development
+
+1. Whenever you make changes in the `packages` directory, make sure to build the app in the root directory (not in `examples/mobile-client/text-chat`). This ensures that all related workspaces are also built:
+
+ ```sh
+ yarn build
+ ```
+
+2. Linter (run in the root directory):
+ ```sh
+ yarn lint
+ ```
+
+## License
+
+This example is provided under the MIT License. See [LICENSE](../../LICENSE) for details.
+
+---
+
+_This project is maintained by the Fishjam team. For questions or support, visit [fishjam.io](https://fishjam.io/) or open an issue on GitHub._
diff --git a/examples/mobile-client/text-chat/app.json b/examples/mobile-client/text-chat/app.json
new file mode 100644
index 00000000..b261f695
--- /dev/null
+++ b/examples/mobile-client/text-chat/app.json
@@ -0,0 +1,41 @@
+{
+ "expo": {
+ "name": "mobile-text-chat",
+ "slug": "mobile-text-chat",
+ "version": "1.0.0",
+ "orientation": "portrait",
+ "icon": "../minimal-react-native/assets/icon.png",
+ "userInterfaceStyle": "light",
+ "newArchEnabled": true,
+ "splash": {
+ "image": "../minimal-react-native/assets/splash-icon.png",
+ "resizeMode": "contain",
+ "backgroundColor": "#ffffff"
+ },
+ "ios": {
+ "supportsTablet": true,
+ "bundleIdentifier": "io.fishjam.mobile.example.textchat",
+ "appleTeamId": "J5FM626PE2"
+ },
+ "android": {
+ "adaptiveIcon": {
+ "foregroundImage": "../minimal-react-native/assets/adaptive-icon.png",
+ "backgroundColor": "#ffffff"
+ },
+ "edgeToEdgeEnabled": true,
+ "package": "io.fishjam.mobile.example.textchat",
+ "permissions": [
+ "android.permission.ACCESS_NETWORK_STATE",
+ "android.permission.ACCESS_WIFI_STATE"
+ ]
+ },
+ "web": {
+ "favicon": "../minimal-react-native/assets/favicon.png"
+ },
+ "plugins": [
+ [
+ "@fishjam-cloud/react-native-client"
+ ]
+ ]
+ }
+}
diff --git a/examples/mobile-client/text-chat/eslint.config.js b/examples/mobile-client/text-chat/eslint.config.js
new file mode 100644
index 00000000..67be7d8b
--- /dev/null
+++ b/examples/mobile-client/text-chat/eslint.config.js
@@ -0,0 +1,10 @@
+// https://docs.expo.dev/guides/using-eslint/
+const { defineConfig } = require('eslint/config');
+const expoConfig = require('eslint-config-expo/flat');
+
+module.exports = defineConfig([
+ expoConfig,
+ {
+ ignores: ['dist/*'],
+ },
+]);
diff --git a/examples/mobile-client/text-chat/hooks/useConnectFishjam.ts b/examples/mobile-client/text-chat/hooks/useConnectFishjam.ts
new file mode 100644
index 00000000..45684b91
--- /dev/null
+++ b/examples/mobile-client/text-chat/hooks/useConnectFishjam.ts
@@ -0,0 +1,54 @@
+import { useEffect, useState } from "react";
+import { NavigationProp, useNavigation } from "@react-navigation/native";
+import {
+ useConnection,
+ useSandbox,
+} from "@fishjam-cloud/react-native-client";
+import { RootStackParamList } from "../navigation/RootNavigation";
+
+export const useConnectFishjam = () => {
+ const navigation = useNavigation>();
+ const { leaveRoom, joinRoom } = useConnection();
+ const { getSandboxPeerToken } = useSandbox();
+
+ const [isLoading, setIsLoading] = useState(false);
+ const [error, setError] = useState(null);
+
+ const connect = async (roomName: string, userName: string) => {
+ try {
+ setIsLoading(true);
+ setError(null);
+ const peerToken = await getSandboxPeerToken(
+ roomName,
+ userName,
+ "conference",
+ );
+ await joinRoom({
+ peerToken,
+ peerMetadata: {
+ displayName: userName,
+ },
+ });
+ navigation.navigate("Chat", { roomName, userName });
+ } catch (err) {
+ const error =
+ err instanceof Error ? err : new Error("Failed to connect to Fishjam");
+ console.error("Error connecting to Fishjam", error);
+ setError(error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ return () => {
+ leaveRoom();
+ };
+ }, [leaveRoom]);
+
+ return {
+ connect,
+ isLoading,
+ error,
+ };
+};
diff --git a/examples/mobile-client/text-chat/index.ts b/examples/mobile-client/text-chat/index.ts
new file mode 100644
index 00000000..e5802d26
--- /dev/null
+++ b/examples/mobile-client/text-chat/index.ts
@@ -0,0 +1,5 @@
+import { registerRootComponent } from "expo";
+
+import App from "./App";
+
+registerRootComponent(App);
diff --git a/examples/mobile-client/text-chat/navigation/RootNavigation.tsx b/examples/mobile-client/text-chat/navigation/RootNavigation.tsx
new file mode 100644
index 00000000..686d27f5
--- /dev/null
+++ b/examples/mobile-client/text-chat/navigation/RootNavigation.tsx
@@ -0,0 +1,38 @@
+import {
+ createNativeStackNavigator,
+ NativeStackScreenProps,
+} from "@react-navigation/native-stack";
+import HomeScreen from "../screens/home";
+import ChatScreen from "../screens/chat";
+
+export type RootStackParamList = {
+ Home: undefined;
+ Chat: {
+ roomName: string;
+ userName: string;
+ };
+};
+
+export type RootScreenProps =
+ NativeStackScreenProps;
+
+const RootStack = createNativeStackNavigator();
+
+const RootNavigation = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default RootNavigation;
diff --git a/examples/mobile-client/text-chat/package.json b/examples/mobile-client/text-chat/package.json
new file mode 100644
index 00000000..035eb2ab
--- /dev/null
+++ b/examples/mobile-client/text-chat/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "mobile-text-chat",
+ "version": "1.0.0",
+ "main": "index.ts",
+ "scripts": {
+ "start": "expo start",
+ "android": "expo run:android",
+ "ios": "expo run:ios",
+ "web": "expo start --web"
+ },
+ "dependencies": {
+ "@fishjam-cloud/react-native-client": "workspace:*",
+ "@react-navigation/elements": "^2.5.2",
+ "@react-navigation/native": "^7.1.14",
+ "@react-navigation/native-stack": "^7.3.21",
+ "expo": "~54.0.25",
+ "expo-status-bar": "~3.0.8",
+ "react": "19.1.0",
+ "react-native": "0.81.5",
+ "react-native-safe-area-context": "~5.6.0",
+ "react-native-screens": "~4.14.0"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.28.0",
+ "@types/react": "~19.1.0",
+ "eslint": "^9.29.0",
+ "eslint-config-expo": "~9.2.0",
+ "eslint-config-prettier": "^10.1.5",
+ "eslint-plugin-prettier": "^5.5.1",
+ "prettier": "^3.6.2",
+ "typescript": "~5.9.2"
+ },
+ "private": true
+}
diff --git a/examples/mobile-client/text-chat/screens/chat/index.tsx b/examples/mobile-client/text-chat/screens/chat/index.tsx
new file mode 100644
index 00000000..e95d2c4c
--- /dev/null
+++ b/examples/mobile-client/text-chat/screens/chat/index.tsx
@@ -0,0 +1,296 @@
+import React, { useCallback, useEffect, useRef, useState } from "react";
+import {
+ FlatList,
+ KeyboardAvoidingView,
+ Pressable,
+ StyleSheet,
+ Text,
+ TextInput,
+ View,
+} from "react-native";
+import {
+ useConnection,
+ useDataChannel,
+} from "@fishjam-cloud/react-native-client";
+import { RootScreenProps } from "../../navigation/RootNavigation";
+import { SafeAreaView } from "react-native-safe-area-context";
+
+type ChatMessage = {
+ timestamp: number;
+ sender: string;
+ payload: string;
+};
+
+const ChatScreen = ({ route, navigation }: RootScreenProps<"Chat">) => {
+ const { roomName, userName } = route.params;
+ const [messages, setMessages] = useState([]);
+ const [inputValue, setInputValue] = useState("");
+ const listRef = useRef>(null);
+
+ const { peerStatus, leaveRoom } = useConnection();
+ const {
+ publishData,
+ subscribeData,
+ initializeDataChannel,
+ dataChannelReady,
+ dataChannelLoading,
+ dataChannelError,
+ } = useDataChannel();
+
+ useEffect(() => {
+ if (peerStatus === "connected") {
+ initializeDataChannel();
+ }
+ }, [peerStatus, initializeDataChannel]);
+
+ useEffect(() => {
+ if (dataChannelLoading || !dataChannelReady) return;
+
+ const unsubscribe = subscribeData(
+ (data: Uint8Array) => {
+ const message = new TextDecoder().decode(data);
+ try {
+ const parsed = JSON.parse(message) as ChatMessage;
+ setMessages((prev) => [...prev, parsed]);
+ } catch {
+ console.error("Failed to parse message:", message);
+ }
+ },
+ { reliable: true },
+ );
+
+ return () => {
+ unsubscribe();
+ };
+ }, [dataChannelReady, dataChannelLoading, subscribeData]);
+
+ const handleLeave = useCallback(() => {
+ leaveRoom();
+ navigation.goBack();
+ }, [leaveRoom, navigation]);
+
+ const handleSend = useCallback(() => {
+ if (!inputValue.trim() || dataChannelLoading || !dataChannelReady) return;
+
+ const message: ChatMessage = {
+ timestamp: Date.now(),
+ sender: userName,
+ payload: inputValue.trim(),
+ };
+
+ const encoded = new TextEncoder().encode(JSON.stringify(message));
+ publishData(encoded, { reliable: true });
+ setMessages((prev) => [...prev, message]);
+ setInputValue("");
+ }, [inputValue, dataChannelLoading, dataChannelReady, userName, publishData]);
+
+ const renderMessage = ({ item }: { item: ChatMessage }) => {
+ const isOwn = item.sender === userName;
+ return (
+
+
+
+ {item.sender}{" "}
+
+
+ {new Date(item.timestamp).toLocaleTimeString([], {
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+
+
+
+ {item.payload}
+
+
+ );
+ };
+
+ return (
+
+
+
+ Fishjam Chat
+
+ Room: {roomName} • User: {userName}
+
+
+
+ Leave
+
+
+
+ {(peerStatus === "connecting" ||
+ dataChannelLoading ||
+ dataChannelError) && (
+
+ {peerStatus === "connecting" && Connecting...}
+ {dataChannelLoading && Opening data channel...}
+ {dataChannelError && (
+ {dataChannelError.message}
+ )}
+
+ )}
+
+
+ `${item.timestamp}-${item.sender}`}
+ renderItem={renderMessage}
+ contentContainerStyle={styles.messagesContainer}
+ keyboardShouldPersistTaps="handled"
+ keyboardDismissMode="interactive"
+ onContentSizeChange={() =>
+ listRef.current?.scrollToEnd({ animated: true })
+ }
+ ListEmptyComponent={
+ No messages yet
+ }
+ />
+
+
+
+
+ Send
+
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ padding: 16,
+ gap: 12,
+ },
+ header: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ gap: 12,
+ },
+ title: {
+ fontSize: 20,
+ fontWeight: "600",
+ },
+ subtitle: {
+ color: "#666",
+ marginTop: 4,
+ },
+ leaveButton: {
+ paddingVertical: 8,
+ paddingHorizontal: 12,
+ backgroundColor: "#dc3545",
+ borderRadius: 6,
+ },
+ leaveButtonText: {
+ color: "white",
+ fontWeight: "600",
+ },
+ statusContainer: {
+ paddingVertical: 8,
+ },
+ errorText: {
+ color: "#dc3545",
+ },
+ kavContainer: {
+ flex: 1,
+ },
+ messagesContainer: {
+ paddingHorizontal: 4,
+ paddingBottom: 8,
+ gap: 12,
+ },
+ emptyStateText: {
+ textAlign: "center",
+ color: "#999",
+ marginTop: 24,
+ },
+ message: {
+ padding: 10,
+ borderRadius: 10,
+ maxWidth: "80%",
+ },
+ ownMessage: {
+ backgroundColor: "#007bff",
+ alignSelf: "flex-end",
+ },
+ otherMessage: {
+ backgroundColor: "#e9e9e9",
+ alignSelf: "flex-start",
+ },
+ messageMeta: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ marginBottom: 4,
+ },
+ sender: {
+ fontWeight: "600",
+ color: "#111",
+ },
+ time: {
+ color: "#666",
+ },
+ payload: {
+ color: "#111",
+ },
+ ownMessageText: {
+ color: "rgba(255, 255, 255, 0.9)",
+ },
+ inputContainer: {
+ flexDirection: "row",
+ gap: 8,
+ alignItems: "center",
+ paddingTop: 8,
+ borderTopWidth: StyleSheet.hairlineWidth,
+ borderTopColor: "#ccc",
+ },
+ messageInput: {
+ flex: 1,
+ borderColor: "#ccc",
+ borderWidth: 1,
+ borderRadius: 8,
+ paddingHorizontal: 12,
+ paddingVertical: 10,
+ },
+ sendButton: {
+ backgroundColor: "#28a745",
+ paddingVertical: 10,
+ paddingHorizontal: 16,
+ borderRadius: 8,
+ },
+ sendButtonDisabled: {
+ opacity: 0.6,
+ },
+ sendButtonText: {
+ color: "white",
+ fontWeight: "600",
+ },
+});
+
+export default ChatScreen;
diff --git a/examples/mobile-client/text-chat/screens/home/index.tsx b/examples/mobile-client/text-chat/screens/home/index.tsx
new file mode 100644
index 00000000..403a5108
--- /dev/null
+++ b/examples/mobile-client/text-chat/screens/home/index.tsx
@@ -0,0 +1,90 @@
+import React, { useState } from "react";
+import {
+ Button,
+ Keyboard,
+ Pressable,
+ StyleSheet,
+ Text,
+ TextInput,
+ View,
+} from "react-native";
+import { useConnectFishjam } from "../../hooks/useConnectFishjam";
+import { SafeAreaView } from "react-native-safe-area-context";
+
+const HomeScreen = () => {
+ const [roomName, setRoomName] = useState("");
+ const [userName, setUserName] = useState("");
+ const { connect, isLoading, error } = useConnectFishjam();
+
+ return (
+
+
+
+
+
+ {error && (
+
+ Failed to connect. Please try again.
+
+ )}
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ content: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ padding: 16,
+ },
+ form: {
+ width: "100%",
+ gap: 16,
+ },
+ input: {
+ width: "100%",
+ height: 40,
+ borderColor: "gray",
+ borderWidth: 1,
+ paddingHorizontal: 16,
+ borderRadius: 8,
+ },
+ errorText: {
+ color: "#dc3545",
+ marginBottom: 8,
+ },
+});
+
+export default HomeScreen;
diff --git a/examples/mobile-client/text-chat/tsconfig.json b/examples/mobile-client/text-chat/tsconfig.json
new file mode 100644
index 00000000..7886cc19
--- /dev/null
+++ b/examples/mobile-client/text-chat/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "expo/tsconfig.base",
+ "compilerOptions": {
+ "jsx": "react",
+ "strict": true
+ }
+}
diff --git a/packages/mobile-client/src/index.ts b/packages/mobile-client/src/index.ts
index 2a801ddc..e6920ec9 100644
--- a/packages/mobile-client/src/index.ts
+++ b/packages/mobile-client/src/index.ts
@@ -32,6 +32,7 @@ export {
InitializeDevicesSettings,
useConnection,
useCustomSource,
+ useDataChannel,
useLivestreamStreamer,
useLivestreamViewer,
usePeers,
@@ -78,6 +79,9 @@ export type {
TracksMiddlewareResult,
AuthErrorReason,
JoinErrorReason,
+ UseDataChannelResult,
+ DataCallback,
+ DataChannelOptions,
Metadata,
ReconnectConfig,
ReconnectionStatus,
diff --git a/yarn.lock b/yarn.lock
index 8e78d6c2..b7e3ce49 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -15302,6 +15302,31 @@ __metadata:
languageName: node
linkType: hard
+"mobile-text-chat@workspace:examples/mobile-client/text-chat":
+ version: 0.0.0-use.local
+ resolution: "mobile-text-chat@workspace:examples/mobile-client/text-chat"
+ dependencies:
+ "@babel/core": "npm:^7.28.0"
+ "@fishjam-cloud/react-native-client": "workspace:*"
+ "@react-navigation/elements": "npm:^2.5.2"
+ "@react-navigation/native": "npm:^7.1.14"
+ "@react-navigation/native-stack": "npm:^7.3.21"
+ "@types/react": "npm:~19.1.0"
+ eslint: "npm:^9.29.0"
+ eslint-config-expo: "npm:~9.2.0"
+ eslint-config-prettier: "npm:^10.1.5"
+ eslint-plugin-prettier: "npm:^5.5.1"
+ expo: "npm:~54.0.25"
+ expo-status-bar: "npm:~3.0.8"
+ prettier: "npm:^3.6.2"
+ react: "npm:19.1.0"
+ react-native: "npm:0.81.5"
+ react-native-safe-area-context: "npm:~5.6.0"
+ react-native-screens: "npm:~4.14.0"
+ typescript: "npm:~5.9.2"
+ languageName: unknown
+ linkType: soft
+
"mp4box@npm:^0.5.2":
version: 0.5.4
resolution: "mp4box@npm:0.5.4"