Skip to content

FileSystem

The @effect/platform/FileSystem module provides a set of operations for reading and writing from/to the file system.

The module provides a single FileSystem tag, which acts as the gateway for interacting with the filesystem.

Example (Accessing File System Operations)

import { FileSystem } from "@effect/platform"
import { Effect } from "effect"
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem
// Use `fs` to perform file system operations
})

The FileSystem interface includes the following operations:

OperationDescription
accessCheck if a file can be accessed. You can optionally specify the level of access to check for.
copyCopy a file or directory from fromPath to toPath. Equivalent to cp -r.
copyFileCopy a file from fromPath to toPath.
chmodChange the permissions of a file.
chownChange the owner and group of a file.
existsCheck if a path exists.
linkCreate a hard link from fromPath to toPath.
makeDirectoryCreate a directory at path. You can optionally specify the mode and whether to recursively create nested directories.
makeTempDirectoryCreate a temporary directory. By default, the directory will be created inside the system’s default temporary directory.
makeTempDirectoryScopedCreate a temporary directory inside a scope. Functionally equivalent to makeTempDirectory, but the directory will be automatically deleted when the scope is closed.
makeTempFileCreate a temporary file. The directory creation is functionally equivalent to makeTempDirectory. The file name will be a randomly generated string.
makeTempFileScopedCreate a temporary file inside a scope. Functionally equivalent to makeTempFile, but the file will be automatically deleted when the scope is closed.
openOpen a file at path with the specified options. The file handle will be automatically closed when the scope is closed.
readDirectoryList the contents of a directory. You can recursively list the contents of nested directories by setting the recursive option.
readFileRead the contents of a file.
readFileStringRead the contents of a file as a string.
readLinkRead the destination of a symbolic link.
realPathResolve a path to its canonicalized absolute pathname.
removeRemove a file or directory. By setting the recursive option to true, you can recursively remove nested directories.
renameRename a file or directory.
sinkCreate a writable Sink for the specified path.
statGet information about a file at path.
streamCreate a readable Stream for the specified path.
symlinkCreate a symbolic link from fromPath to toPath.
truncateTruncate a file to a specified length. If the length is not specified, the file will be truncated to length 0.
utimesChange the file system timestamps of the file at path.
watchWatch a directory or file for changes.
writeFileWrite data to a file at path.
writeFileStringWrite a string to a file at path.

Example (Reading a File as a String)

import { FileSystem } from "@effect/platform"
import { NodeContext, NodeRuntime } from "@effect/platform-node"
import { Effect } from "effect"
// ┌─── Effect<void, PlatformError, FileSystem>
// ▼
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem
// Reading the content of the same file where this code is written
const content = yield* fs.readFileString("./index.ts", "utf8")
console.log(content)
})
// Provide the necessary context and run the program
NodeRuntime.runMain(program.pipe(Effect.provide(NodeContext.layer)))

In testing environments, you may want to mock the file system to avoid performing actual disk operations. The FileSystem.layerNoop provides a no-operation implementation of the FileSystem service.

Most operations in FileSystem.layerNoop return a failure (e.g., Effect.fail for missing files) or a defect (e.g., Effect.die for unimplemented features). However, you can override specific behaviors by passing an object to FileSystem.layerNoop to define custom return values for selected methods.

Example (Mocking File System with Custom Behavior)

import { FileSystem } from "@effect/platform"
import { Effect } from "effect"
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem
const exists = yield* fs.exists("/some/path")
console.log(exists)
const content = yield* fs.readFileString("/some/path")
console.log(content)
})
// ┌─── Layer<FileSystem.FileSystem, never, never>
// ▼
const customMock = FileSystem.layerNoop({
readFileString: () => Effect.succeed("mocked content"),
exists: (path) => Effect.succeed(path === "/some/path")
})
// Provide the customized FileSystem mock implementation
Effect.runPromise(program.pipe(Effect.provide(customMock)))
/*
Output:
true
mocked content
*/