Compatibility and limits

The four published Effect Virtual FS packages implement a documented subset of POSIX filesystem behavior. They do not provide a mounted host filesystem, a complete POSIX implementation, or a way to intercept direct calls to node:fs.

This page records the supported package format, runtime evidence, filesystem differences, and resource limits. Follow the API links for exact types and signatures.

Package compatibility

PackageModule formatPurpose
@effect-vfs/coreESM onlyRuntime-neutral volumes, callers, handles, snapshots, and overlays
@effect-vfs/memoryESM onlyEffect FileSystem.FileSystem adapter
@effect-vfs/persistenceESM onlyNamed SQLite checkpoints and live-image storage
@effect-vfs/nfsESM onlyNFSv4.1 export with guarded experimental writes

Use an ES module build. Each published package declares its exact supported Effect version in peerDependencies.effect. Read it with npm view @effect-vfs/core peerDependencies.effect and install matching versions of any @effect/* packages that your application uses.

The published manifests do not declare a consumer Node.js version. The repository uses Node.js 24 or later and Bun 1.2.21 for development and validation. That contributor-toolchain requirement is not evidence that every earlier Node.js release works. Bun is required by the documented SQLite provider and its runtime tests, not by the core or memory APIs.

Runtime evidence

Runtime-neutral means the core does not import Node.js or Bun filesystem APIs. It does not mean that every operation has been run on every JavaScript runtime.

AreaWhat the repository checks
Core packageTypeScript build, NodeNext import compatibility, and behavior tests under the repository test runner
Memory adapterNodeNext import compatibility and a browser-target bundle
Browser targetThe bundle runs as a smoke test under Node.js; this is not a browser runtime test
PersistenceReal SQLite tests under Bun and NodeNext declaration compatibility; Node SQLite runtime behavior is not tested

Portable snapshot-delta operations use Effect's Crypto.Crypto service. Supply the appropriate Effect crypto layer for the runtime at the application boundary.

Implemented filesystem behavior

The core supports regular files, directories, symbolic links, hard links, component-by-component path lookup, directory-relative lookup, scoped file and directory handles, metadata, permissions, namespace changes, watches, and snapshot capture.

The behavior follows documented POSIX.1-2024 rules for this subset, with these important boundaries:

  • typed Effect failures replace global errno;
  • Effect scopes manage derived callers, handles, and watch subscriptions;
  • caller privilege is explicit and does not come from the host process;
  • storage is dense and in memory, not sparse or host-backed; and
  • the memory adapter may follow Effect FileSystem behavior where it differs from the lower-level core contract.

These packages do not claim full POSIX conformance. They do not provide a C filesystem API, simulated process, host-directory import or export, device files, FIFOs, filesystem sockets, or descriptor duplication. The NFS server tracks read locks between NFS clients, but direct VFS callers do not participate in those locks. Named checkpoints are explicit copies. The separate SQLite live-image store does not currently qualify for host fsync durability.

Path limits

LimitValueConfigurable
Path component255 bytesNo
Symbolic-link traversals during one resolution40No
Total encoded path lengthUnlimited by defaultYes, with maxPathBytes
String path encodingValid UTF-8 without NUL or lone surrogatesNo

BytePath preserves arbitrary non-NUL filename bytes. String-returning operations fail when a stored name cannot be represented as UTF-8.

Absolute paths ignore a supplied directory base. Relative paths can use a live DirectoryHandle from the same volume.

Volume capacity limits

Pass optional limits when creating or restoring a core volume.

OptionWhat it limitsDefault
maxEntriesNamespace entriesNo configured limit
maxBytesLogical bytes held by regular files and symbolic-link targetsNo configured limit
maxFileBytesBytes in one regular file4,294,967,295 bytes
maxPathBytesTotal encoded bytes accepted for one pathNo configured limit

The dense-file ceiling of 4,294,967,295 bytes is fixed. maxFileBytes may lower it but cannot raise it. File contents and symbolic-link targets are charged once per inode, so hard links do not duplicate their byte charge. An unlinked file remains charged while an open handle keeps it alive.

The VirtualFileSystem API reference documents VolumeOptions and the constructors that accept it.

Watch behavior

volume.watch opens a scoped stream of future committed create, update, and remove events.

  • Events are not replayed.
  • Registration is coordinated with mutations so an event cannot be lost while the subscription becomes active.
  • maxWatchEvents defaults to 256 queued events per subscriber and can be configured on a volume.
  • When a subscriber loses events, it receives Rescan at / and must read the volume again.
  • Closing the owning scope releases the subscription.

A slow consumer does not retain an unbounded event history. Treat Rescan as an invalidation signal, not a replay.

Glob limits

Globbing belongs to the memory adapter. Patterns are root-relative POSIX-style paths.

The adapter supports *, ?, **, character classes and ranges, class negation, escaped syntax, and nested comma-list brace expansion. Brace expansion is capped at 256 alternatives. That ceiling is fixed and callers cannot configure it.

The adapter does not support extglobs, numeric brace ranges, POSIX character classes, whole-pattern negation, or following symbolic links during traversal. A trailing slash matches directories only. Dotfiles require a pattern segment that explicitly starts with . or a positive character class that includes it.

Snapshot decode limits

decodeSnapshot requires a complete DecodeLimits value. There is no default decode policy.

FieldWork it bounds
maxEncodedBytesEncoded snapshot input bytes
maxRecordsStored metadata and content records
maxEntriesNamespace entries
maxDecodedBytesCombined decoded byte content

Encoded and decoded byte budgets use ByteSize.ByteSize. Record and entry limits are numbers. Restoring the decoded snapshot also applies the destination volume's capacity limits.

See the Snapshot API reference and VirtualFileSystem API reference.

Snapshot delta limits

One complete SnapshotDeltaLimits policy applies to delta creation, inspection, encoding, decoding, and application. Omitting it selects the frozen SnapshotDeltaLimits.default policy. SnapshotDeltaLimits.constrained is a smaller preset for memory-sensitive environments. A custom policy must provide every field.

The policy bounds encoded and decoded delta bytes, canonical identity work, base and target records, delta and output records, namespace entries, output payload bytes, and inherited-record work. Byte budgets use ByteSize.ByteSize; record and entry budgets use numbers.

See the Snapshot delta API reference for the preset values and complete policy schema.

Which limits callers can configure

AreaCaller-configurable
Volume capacity and total path lengthYes, through VolumeOptions
Snapshot decodingYes, and a complete policy is required
Snapshot delta workYes, through a preset or complete custom policy
Path component length and symlink traversal countNo
Dense-file hard ceilingNo, but maxFileBytes can lower it
Watch queueNo
Glob brace expansionNo