File system (fs)
Node's fs, ported from lib/fs.js to TypeScript: the synchronous functions, their callback and promise forms, FileHandle, the file streams and fs.watch. Each operation is one native request — on the calling thread for a *Sync function, on the thread pool with the callback on the event loop otherwise — as libuv's are.
fs.readFileSync(path[, options])
ExactReads the whole file: a Buffer of its exact bytes with no encoding, a string decoded in any Buffer encoding with one. A file descriptor reads to its end (readFileSync(0, 'utf8') is stdin). Errors are Node's system errors, with code, errno, syscall and path. Node's lib/fs.js, ported to TypeScript over one native request per operation.
Returnsstring | Buffer — The contents.
const text = fs.readFileSync('config.json', 'utf8')fs.writeFileSync / fs.appendFileSync
ExactWrites (or appends) a string in any encoding or any ArrayBufferView to a path or descriptor, with Node's { encoding, mode, flag, flush } options.
fs.writeFileSync('/tmp/out.txt', 'hello\n')
fs.appendFileSync('/tmp/out.txt', 'more')fs.existsSync / fs.accessSync
ExactexistsSync reports whether the path exists and never throws; accessSync throws Node's error when the process lacks the access mode (F_OK, R_OK, W_OK, X_OK).
console.log(fs.existsSync('/tmp/out.txt'))fs.statSync / lstatSync / fstatSync
Works, with caveatsNode's Stats: the numeric fields (dev, mode, nlink, uid, gid, rdev, blksize, ino, size, blocks, atimeMs, mtimeMs, ctimeMs, birthtimeMs), the atime/mtime/ctime/birthtime Dates and the kind predicates. throwIfNoEntry: false returns undefined for a missing path. On Linux the stat is statx, so birthtime is real.
const st = fs.statSync('/tmp/out.txt')
console.log(st.size, st.isFile(), st.mtime){ bigint: true }is ignored: noBigIntStats.
fs.statfsSync(path) → StatFs
Works, with caveatsFile-system statistics of the volume holding path: { type, bsize, frsize, blocks, bfree, bavail, files, ffree }.
console.log(fs.statfsSync('/').bavail){ bigint: true }is ignored: the fields are numbers.
fs.mkdirSync / mkdtempSync / rmdirSync / rmSync / unlinkSync
Works, with caveatsDirectory creation (recursive returns the first directory made), temporary directories, and removal: rmSync removes a tree with recursive and ignores a missing path with force; a directory without recursive is Node's ERR_FS_EISDIR.
fs.mkdirSync('/tmp/a/b/c', { recursive: true })
fs.rmSync('/tmp/a', { recursive: true, force: true })rmSync'smaxRetries/retryDelayare validated and unused.
fs.readdirSync(path[, options])
Works, with caveatsA directory's entries, sorted as libuv sorts them: names, Buffers with encoding: 'buffer', or Dirents (name, parentPath, the kind predicates) with withFileTypes; recursive walks the subtree breadth-first.
for (const d of fs.readdirSync('.', { withFileTypes: true })) console.log(d.name, d.isDirectory())dirent.path(removed in Node v24) is a compile-time error rather thanundefined.
fs.renameSync / copyFileSync / linkSync / symlinkSync / readlinkSync / realpathSync
Works, with caveatsMoving, copying (the copy takes the source's mode; COPYFILE_EXCL refuses an existing destination), hard and symbolic links, and path canonicalization: realpathSync is Node's lstat walk, realpathSync.native is realpath(3). Two-path errors name both paths.
fs.copyFileSync('a.txt', 'b.txt', fs.constants.COPYFILE_EXCL)COPYFILE_FICLONE_FORCEfails withENOTSUP: no copy-on-write clone.
fs.openSync / closeSync / readSync / writeSync / readvSync / writevSync
ExactThe descriptor-level API: open with any flag string or a numeric mask, read and write buffers (offset, length, position, or an options object) or strings (position, encoding), scatter/gather, close.
const fd = fs.openSync('/tmp/out.txt', 'r')
const n = fs.readSync(fd, Buffer.alloc(16), 0, 16, 0)
fs.closeSync(fd)fs.fsyncSync / fdatasyncSync / ftruncateSync / truncateSync
ExactFlush a descriptor to disk and resize a file, by descriptor or path.
fs.truncateSync('/tmp/out.txt', 0)fs.chmodSync / fchmodSync / chownSync / fchownSync / lchownSync
ExactPermission bits (a number or an octal string) and ownership, by path or descriptor. The chown family does nothing on Windows, as libuv's.
fs.chmodSync('/tmp/out.txt', 0o600)fs.utimesSync / futimesSync / lutimesSync
ExactSet access and modification times, as seconds, a numeric string or a Date, by path, descriptor or link.
fs.utimesSync('/tmp/out.txt', new Date(), new Date())Callback forms
ExactEvery operation's callback form: each request runs on the thread pool and calls back on the event loop, as libuv's do. readFile and writeFile take an AbortSignal.
fs.readFile('config.json', 'utf8', (err, text) => { if (err) throw err; console.log(text) })fs.promises / fs/promises
ExactNode's promise API: each function is its callback form's request settling a promise; readFile/writeFile/appendFile also take a FileHandle.
const text = await fs.promises.readFile('config.json', 'utf8')fs.open / read / write / writev / readv / fsync / close
ExactThe descriptor-level callback operations with Node's argument forms, validation errors and system errors. A positioned read or write is a single transfer at the offset on every platform.
fs.open('a.txt', 'r', (err, fd) => fs.close(fd))fsPromises.open → FileHandle
Works, with caveatsOpens a file and resolves to a FileHandle: fd, read, write, writev, sync, datasync, stat, truncate, chmod, utimes, readFile, writeFile, appendFile, createReadStream/createWriteStream, and close, which waits for the streams that hold the handle.
import { open } from 'fs/promises'
const h = await open('a.txt')
await h.close()- Not ported:
chown,readv,readLines,readableWebStream,[Symbol.asyncDispose].
fs.createReadStream / createWriteStream
ExactReadable and Writable streams over a file, with Node's options (start/end, flags, mode, fd, fs, signal, autoClose, emitClose, flush, highWaterMark). Node's lib/internal/fs/streams.js.
fs.createReadStream('in.txt').pipe(fs.createWriteStream('out.txt'))fs.watch
ExactNative, event-driven change watching in the event loop: an FSWatcher (an EventEmitter) emitting 'change' with (eventType, filename), and 'close', with ref()/unref() and persistent. libuv on every platform; recursive watches the whole tree, with names relative to the watched directory.
const w = fs.watch('config.json', (ev, name) => { console.log(ev, name); w.close() })fs.constants
ExactNode's per-platform constants table, a real object.
fs.accessSync('a.txt', fs.constants.R_OK)fs.cp / opendir / glob / watchFile / openAsBlob / lchmod
Not supportedNot ported yet.
// not supported yetFile / FileReader / FileSystemFileHandle
Not supportedThe browser-flavored File API is not planned — these model browser sandbox/permission concepts this compiler has no equivalent for. A native CLI/microservice program has direct filesystem access via the fs functions above instead.