---
title: 'File System'
description: 'Runtime-agnostic file system utilities optimized for Bun and Node.'
order: 7
---

import { CodeTabs } from '@/components/code-tabs';

# File System

The `@ecopages/file-system` package provides runtime-agnostic file system utilities with optimized implementations for both Bun and Node.js.

## Features

- **Runtime Detection**: Automatically selects the optimal adapter
- **Bun Optimized**: Uses `Bun.Glob`, `Bun.hash`, `Bun.file`, and `Bun.write` for maximum performance
- **Node.js Fallback**: Uses native `node:fs/promises.glob()` and `crypto` for full compatibility
- **Type Safe**: Consistent TypeScript interface across runtimes

## Installation

<CodeTabs
	name="file-system-install"
	tabs={[
		{ id: 'npm', label: 'npm', code: 'npm install @ecopages/file-system' },
		{ id: 'pnpm', label: 'pnpm', code: 'pnpm add @ecopages/file-system' },
		{ id: 'bun', label: 'bun', code: 'bun add @ecopages/file-system' },
	]}
	defaultSelectedKey="npm"
/>

## Usage

```typescript
import { fileSystem } from '@ecopages/file-system';

// Glob files
const files = await fileSystem.glob(['**/*.ts'], { cwd: './src' });

// Read files
const content = await fileSystem.readFile('file.txt');

// Hash files (Bun is 4.5x faster!)
const hash = fileSystem.hash('file.txt');

// Write files (sync)
fileSystem.write('output.txt', 'Hello World');

// Write files (async, uses Bun.write for optimized syscalls)
await fileSystem.writeAsync('output.txt', largeBuffer);

// Check existence
if (fileSystem.exists('file.txt')) {
	// ...
}

// Ensure directory exists
fileSystem.ensureDir('./dist/assets');

// Copy files and directories
fileSystem.copyFile('src.txt', 'dest.txt');
fileSystem.copyDir('./src', './dist');
```

## API Reference

### File Operations

| Method                      | Description                                            |
| :-------------------------- | :----------------------------------------------------- |
| `readFile(path)`            | Read file as string (async)                            |
| `readFileSync(path)`        | Read file as string (sync)                             |
| `readFileAsBuffer(path)`    | Read file as Buffer                                    |
| `write(path, content)`      | Write content to file (sync)                           |
| `writeAsync(path, content)` | Write content to file (async, uses `Bun.write` on Bun) |
| `exists(path)`              | Check if path exists                                   |
| `verifyFileExists(path)`    | Throw `FileNotFoundError` if missing                   |

### Directory Operations

| Method                           | Description                       |
| :------------------------------- | :-------------------------------- |
| `glob(patterns, options)`        | Find files matching glob patterns |
| `ensureDir(path, forceCleanup?)` | Ensure directory exists           |
| `copyDir(src, dest)`             | Copy directory recursively        |
| `emptyDir(path)`                 | Remove all contents of directory  |
| `isDirectory(path)`              | Check if path is directory        |

### File Management

| Method                      | Description                          |
| :-------------------------- | :----------------------------------- |
| `copyFile(src, dest)`       | Copy single file                     |
| `remove(path)`              | Remove file or directory (sync)      |
| `removeAsync(path)`         | Remove file or directory (async)     |
| `hash(path)`                | Get hash of file contents            |
| `gzipFile(path)`            | Gzip a single file                   |
| `gzipDir(path, extensions)` | Gzip all matching files in directory |

## Glob Options

```typescript
interface GlobOptions {
	cwd?: string; // Working directory (default: process.cwd())
	ignore?: string[]; // Patterns to ignore
}
```

## Performance

The Bun adapter uses optimized syscalls (`copy_file_range`, `sendfile`, `clonefile`) when available.

Benchmark results on Apple M4:

| Operation        | BunFileSystem    | NodeFileSystem | Winner              |
| :--------------- | :--------------- | :------------- | :------------------ |
| glob (100 files) | 64.85 µs         | 71.06 µs       | Bun ~10% faster     |
| hash (1MB file)  | 87 µs            | 393 µs         | **Bun 4.5x faster** |
| writeAsync (1MB) | Uses `Bun.write` | Uses `node:fs` | Bun optimized       |
| exists check     | 477 ns           | 464 ns         | ~same               |

## Direct Adapter Access

For advanced use cases, you can import adapters directly:

```typescript
// Force Bun adapter
import { BunFileSystem } from '@ecopages/file-system/bun';
const bunFs = new BunFileSystem();

// Force Node adapter
import { NodeFileSystem } from '@ecopages/file-system/node';
const nodeFs = new NodeFileSystem();
```

## Error Handling

The package exports a custom error class for file not found scenarios:

```typescript
import { fileSystem, FileNotFoundError } from '@ecopages/file-system';

try {
	fileSystem.verifyFileExists('/path/to/file');
} catch (error) {
	if (error instanceof FileNotFoundError) {
		console.log('File not found:', error.message);
	}
}
```
