Skip to main content

File system

@react-native-gpui/fs is a file system API for desktop apps. It follows node:fs, so code and habits from Node carry over, and adds file dialogs and the well-known folders of the operating system.

npm install @react-native-gpui/fs
JavaScript
import fs, { dialog, paths } from '@react-native-gpui/fs';

The module runs on its own thread, so a slow file never blocks JavaScript or the interface.

Reading and writing​

The default export is the node:fs object, with synchronous, callback and promise forms:

JavaScript
const text = fs.readFileSync(`${paths.documents}/notes.txt`, 'utf8');

await fs.promises.writeFile(
`${paths.appData}/state.json`,
JSON.stringify(state),
);

const entries = await fs.promises.readdir(paths.downloads, {
withFileTypes: true,
});

The common operations are available: readFile, writeFile, appendFile, stat, lstat, readdir, mkdir, rm, rename, copyFile, cp, access, realpath, readlink, symlink, truncate, utimes, chmod, mkdtemp, open with FileHandle, and existsSync. Encodings, Stats, Dirent, flags and constants behave as they do in Node. Errors carry Node's error codes, such as ENOENT.

Text is read and written as UTF-8 directly in native code. Other encodings and binary data go through ArrayBuffer.

Well-known folders​

paths holds the folders the operating system defines. They are created the first time you read them:

NameFolder
homeThe user's home folder.
documentsDocuments.
downloadsDownloads.
desktopThe desktop.
tempThe temporary folder.
appDataWhere the app keeps its data.
appCacheWhere the app keeps files it can recreate.
appLogsWhere the app writes logs.

Dialogs​

dialog opens the platform's file pickers. Cancelling is not an error: open resolves with an empty array, and save with null.

JavaScript
const [file] = await dialog.open({
title: 'Choose a document',
filters: [{ name: 'Text', extensions: ['txt', 'md'] }],
});

const target = await dialog.save({ defaultName: 'export.json' });
dialog.open optionDescription
titleThe title of the dialog.
defaultPathThe folder to start in.
multipleAllow several files.
directoryChoose a folder instead of a file.
filters{name, extensions} entries.

dialog.save takes title, defaultPath, defaultName and filters. On Linux the dialogs use the XDG portal, so GTK is not required.

Reveal and open​

JavaScript
await fs.promises.reveal(path); // show the file in Finder, Explorer or the file manager
await fs.promises.openExternal(path); // open a file or URL with its default application

Watching​

watch(path, listener) watches a file or folder, as in Node. The listener receives 'rename' or 'change' and the file name, and the watcher it returns has a close() method.