https://github.com/TimMikeladze/use-fs
🗂️ A React hook that enables you to read, write, and manage files directly - eliminating the need for repeated file selection dialogs. This capability is ideal for creating powerful browser-based tools.
https://github.com/TimMikeladze/use-fs
directory-changes file-system file-system-watcher file-watcher filesystem fs react react-file-system react-fs use-fs use-watch-directory watch-directory
Last synced: 22 days ago
JSON representation
🗂️ A React hook that enables you to read, write, and manage files directly - eliminating the need for repeated file selection dialogs. This capability is ideal for creating powerful browser-based tools.
- Host: GitHub
- URL: https://github.com/TimMikeladze/use-fs
- Owner: TimMikeladze
- License: mit
- Created: 2023-09-04T20:41:24.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2025-07-25T17:40:43.000Z (3 months ago)
- Last Synced: 2025-09-09T21:16:32.108Z (about 1 month ago)
- Topics: directory-changes, file-system, file-system-watcher, file-watcher, filesystem, fs, react, react-file-system, react-fs, use-fs, use-watch-directory, watch-directory
- Language: TypeScript
- Homepage: https://use-fs.com
- Size: 2.52 MB
- Stars: 15
- Watchers: 2
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 🗂️ use-fs
A React hook for integrating with the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API). Visit [**use-fs.com**](https://use-fs.com) to try it out in your browser.
The File System Access API enables web applications to seamlessly work with files on a user's local system. After a user grants permission, web apps can read, write, and manage files directly - eliminating the need for repeated file selection dialogs. This capability is ideal for creating powerful browser-based tools.
Unlike traditional file selection dialogs, the user will be prompted to select a directory, the hook will watch the files in that directory for changes - rerendering when changes are detected.
> ⚠️ Note: The File System API is not supported in all browsers. Works on Desktop in Chrome, Edge and Opera.
## 📡 Install
```console
npm install use-fsyarn add use-fs
pnpm add use-fs
```> 👋 Hello there! Follow me [@linesofcode](https://twitter.com/linesofcode) or visit [linesofcode.dev](https://linesofcode.dev) for more cool projects like this one.
## 🚀 Getting Started
```tsx
import { useFs } from "use-fs";function App() {
const {
onDirectorySelection,
files,
isBrowserSupported,
onClear,
isProcessing,
writeFile,
deleteFile,
startPolling,
stopPolling,
isPolling
} = useFs({
// Optional array of filter functions to exclude files/directories. By default `commonFilters` is used to ignore .git, node_modules, etc.
filters: [
// Built-in filters available:
// - distFilter (excludes dist/, build/, node_modules/, etc.)
// - gitFilter (respects .gitignore)
// - miscFilter (excludes .DS_Store, etc.)
// Or use commonFilters which includes all of the above
],
// Called when new files are added to the watched directory
onFilesAdded: (newFiles, previousFiles) => {
console.log('Files added:', newFiles);
// newFiles: Map - path -> content
// previousFiles: Map - previous state
},// Called when existing files are modified
onFilesChanged: (changedFiles, previousFiles) => {
console.log('Files changed:', changedFiles);
// changedFiles: Map - path -> new content
// previousFiles: Map - previous state
},// Called when files are deleted from the watched directory
onFilesDeleted: (deletedFiles, previousFiles) => {
console.log('Files deleted:', deletedFiles);
// deletedFiles: Map - path -> last known content
// previousFiles: Map - previous state
},
});if (!isBrowserSupported) {
returnBrowser not supported;
}const handleSaveFile = async (path: string, content: string) => {
try {
await writeFile(path, content, { truncate: true });
console.log('File saved successfully');
} catch (error) {
console.error('Error saving file:', error);
}
};const handleDeleteFile = async (path: string) => {
try {
await deleteFile(path);
console.log('File deleted successfully');
} catch (error) {
console.error('Error deleting file:', error);
}
};return (
Select Directory
Clear
Start Polling
Stop Polling
Status: {isPolling ? 'Polling Active' : 'Polling Stopped'}
{files.size > 0 && (
Files ({files.size}):
{Array.from(files.entries()).map(([path, content]) => (
{path}
{content}
handleSaveFile(path, 'New content')}>
Save Changes
handleDeleteFile(path)}>
Delete File
))}
)}
);
}
```The hook provides several key features:
1. **File System Access**: Prompts users to select a directory and maintains access to it.
2. **File Writing**: Allows writing content to files with options for truncation and creation.
3. **File Deletion**: Enables safe removal of files from the selected directory.
4. **File Watching**: Continuously monitors selected directory for changes with automatic polling.
5. **Polling Control**: Manual control over when to start/stop monitoring for file changes.
6. **Content Management**: Provides access to file contents and updates in real-time.
7. **Filtering**: Built-in and custom filters to exclude unwanted files/directories.
8. **Performance Optimizations**:
- Batched file processing
- Content caching
- Debounced updates
- Efficient change detection### Props
- `filters?: FilterFn[]` - Array of filter functions to exclude files/directories
- `onFilesAdded?: (newFiles: Map, previousFiles: Map) => void` - Callback when files are added
- `onFilesChanged?: (changedFiles: Map, previousFiles: Map) => void` - Callback when files change
- `onFilesDeleted?: (deletedFiles: Map, previousFiles: Map) => void` - Callback when files are deleted
- `pollInterval?: number` - How often to check for changes (default: 100ms)
- `batchSize?: number` - How many files to process in parallel (default: 50)
- `debounceInterval?: number` - Debounce interval for updates (default: 50ms)
- `fileCacheTtl?: number` - How long to cache file contents (default: 5000ms)### Return Values
- `onDirectorySelection: () => Promise` - Function to open directory picker
- `onClear: () => void` - Function to stop watching and clear state
- `files: Map` - Current map of file paths to contents
- `isProcessing: boolean` - Whether files are being processed
- `isBrowserSupported: boolean` - Whether File System API is supported
- `writeFile: (path: string, data: string | ArrayBuffer | Blob, options?: FileWriteOptions) => Promise` - Function to write to files
- `deleteFile: (path: string) => Promise` - Function to delete files
- `startPolling: () => void` - Function to manually start polling for file changes
- `stopPolling: () => void` - Function to manually stop polling for file changes
- `isPolling: boolean` - Whether the hook is actively polling for changes## 📚 Contributing
1. Navigate to the `docs` directory
2. Run `pnpm install` to install the dependencies
3. Run `pnpm dev` to start the development server
3. Navigate to `http://localhost:3000` to view the demo.
5. Modify the `Demo.tsx` file to make your changes.If you're making changes to the `use-fs` package, you can run `pnpm build` to build the package and then run `pnpm link use-fs` to link the package to the `docs` directory for local development and testing.