NebulaNebula
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-app

All 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`,
});
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.
  • readdir returns file names, not full paths.
  • recursive: true in rmdir removes all nested contents.
  • Temporary files should be persisted with saveFile, otherwise the system may clean them up.