Miniapp APIs
File System
Read and write files and directories inside the miniapp sandbox with Nebula file system APIs.
Nebula provides an isolated sandboxed file system for each miniapp. Use getFileSystemManager() to obtain a file manager and perform file and directory operations.
Sandbox path
Each miniapp has its own sandbox directory:
import { Miniapp } from '@nebula-rn/sdk';
const sandboxRoot = Miniapp.getSandboxPath();
// Example: /Documents/MiniApps/my-appAll file operations are restricted to the sandbox.
Get the file manager
import { getFileSystemManager } from '@nebula-rn/client';
const fs = getFileSystemManager();Directory operations
mkdir — create a directory
await fs.mkdir({
dirPath: `${sandboxRoot}/data`,
recursive: true,
});readdir — list directory contents
const files = await fs.readdir({
dirPath: sandboxRoot,
});
console.log(files);rmdir — remove a directory
await fs.rmdir({
dirPath: `${sandboxRoot}/data`,
recursive: true,
});File operations
writeFile — write a file
await fs.writeFile({
filePath: `${sandboxRoot}/note.txt`,
data: 'File contents',
});readFile — read a file
const content = await fs.readFile({
filePath: `${sandboxRoot}/note.txt`,
});
console.log(content);appendFile — append content
await fs.appendFile({
filePath: `${sandboxRoot}/log.txt`,
data: '\nNew log line',
});copyFile — copy a file
await fs.copyFile({
srcPath: `${sandboxRoot}/note.txt`,
destPath: `${sandboxRoot}/note-backup.txt`,
});rename — move or rename
await fs.rename({
oldPath: `${sandboxRoot}/note.txt`,
newPath: `${sandboxRoot}/renamed.txt`,
});unlink — remove a file
await fs.unlink({
filePath: `${sandboxRoot}/renamed.txt`,
});access — check whether a file exists
try {
await fs.access({ path: `${sandboxRoot}/note.txt` });
console.log('File exists');
} catch {
console.log('File does not exist');
}saveFile — persist a temporary file into the sandbox
const result = await fs.saveFile({
tempFilePath: downloadedTempPath,
});
console.log('Saved path:', result.savedFilePath);File information
getFileInfo
import { getFileInfo } from '@nebula-rn/client';
const info = await getFileInfo({
filePath: `${sandboxRoot}/note.txt`,
});
console.log('File size:', info.size);removeFile
import { removeFile } from '@nebula-rn/client';
await removeFile({
filePath: `${sandboxRoot}/note.txt`,
});Complete example
import React, { useMemo, useState } from 'react';
import { Button, ScrollView, StyleSheet, Text } from 'react-native';
import { Miniapp } from '@nebula-rn/sdk';
import { getFileSystemManager, getFileInfo } from '@nebula-rn/client';
export default function FileDemoPage() {
const [result, setResult] = useState('');
const sandboxRoot = useMemo(() => Miniapp.getSandboxPath(), []);
const fs = getFileSystemManager();
const testFile = `${sandboxRoot}/demo.txt`;
const writeDemo = async () => {
await fs.writeFile({
filePath: testFile,
data: `Written at: ${new Date().toISOString()}`,
});
setResult('File written');
};
const readDemo = async () => {
const content = await fs.readFile({ filePath: testFile });
setResult(`Content: ${content}`);
};
const infoDemo = async () => {
const info = await getFileInfo({ filePath: testFile });
setResult(`Size: ${info.size} bytes`);
};
const listDemo = async () => {
const files = await fs.readdir({ dirPath: sandboxRoot });
setResult(`Files: ${files.join(', ')}`);
};
return (
<ScrollView contentContainerStyle={styles.container}>
<Button title="Write file" onPress={writeDemo} />
<Button title="Read file" onPress={readDemo} />
<Button title="File info" onPress={infoDemo} />
<Button title="List directory" onPress={listDemo} />
<Text style={styles.result}>{result}</Text>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: { padding: 20 },
result: { marginTop: 16, fontSize: 14, color: '#334155' },
});Notes
- All file paths must remain inside the sandbox directory.
- File operations are asynchronous, so always use
await. readdirreturns file names, not full paths.recursive: trueinrmdirremoves all nested contents.- Temporary files should be persisted with
saveFile, otherwise the system may clean them up.