| 
 | 1 | +---  | 
 | 2 | +pcx_content_type: configuration  | 
 | 3 | +title: fs  | 
 | 4 | +---  | 
 | 5 | + | 
 | 6 | +import { Render } from "~/components";  | 
 | 7 | + | 
 | 8 | +<Render file="nodejs-compat-howto" product="workers" />  | 
 | 9 | + | 
 | 10 | +You can use [`node:fs`](https://nodejs.org/api/fs.html) to access a virtual file  | 
 | 11 | +system in Workers.  | 
 | 12 | + | 
 | 13 | +The `node:fs` module is available in Workers runtimes that support Node.js  | 
 | 14 | +compatibility using the `nodejs_compat` compatibility flag. Any Worker  | 
 | 15 | +running with `nodejs_compat` enabled and with a compatibility date of  | 
 | 16 | +`2025-09-01` or later will have access to `node:fs` by default. It is  | 
 | 17 | +also possible to enable `node:fs` on Workers with an earlier compatibility  | 
 | 18 | +date using a combination of the `nodejs_compat` and `enable_nodejs_fs_module`  | 
 | 19 | +flags. To disable `node:fs` you can set the `disable_nodejs_fs_module` flag.  | 
 | 20 | + | 
 | 21 | +```js  | 
 | 22 | +import { readFileSync, writeFileSync } from "node:fs";  | 
 | 23 | + | 
 | 24 | +const config = readFileSync("/bundle/config.txt", "utf8");  | 
 | 25 | + | 
 | 26 | +writeFileSync("/tmp/abc.txt", "Hello, world!");  | 
 | 27 | +```  | 
 | 28 | + | 
 | 29 | +The Workers Virtual File System (VFS) is a memory-based file system that allows  | 
 | 30 | +you to read modules included in your Worker bundle as read-only files, access a  | 
 | 31 | +directory for writing temporary files, or access common  | 
 | 32 | +[character devices](https://linux-kernel-labs.github.io/refs/heads/master/labs/device_drivers.html) like  | 
 | 33 | +`/dev/null`, `/dev/random`, `/dev/full`, and `/dev/zero`.  | 
 | 34 | + | 
 | 35 | +The directory structure initially looks like:  | 
 | 36 | + | 
 | 37 | +```  | 
 | 38 | +
  | 
 | 39 | +/bundle  | 
 | 40 | +└── (one file for each module in your Worker bundle)  | 
 | 41 | +/tmp  | 
 | 42 | +└── (empty, but you can write files, create directories, symlinks, etc)  | 
 | 43 | +/dev  | 
 | 44 | +├── null  | 
 | 45 | +├── random  | 
 | 46 | +├── full  | 
 | 47 | +└── zero  | 
 | 48 | +
  | 
 | 49 | +```  | 
 | 50 | + | 
 | 51 | +The `/bundle` directory contains the files for all modules included in your  | 
 | 52 | +Worker bundle, which you can read using APIs like `readFileSync` or  | 
 | 53 | +`read(...)`, etc. These are always read-only. Reading from the bundle  | 
 | 54 | +can be useful when you need to read a config file or a template.  | 
 | 55 | + | 
 | 56 | +```js  | 
 | 57 | +import { readFileSync } from "node:fs";  | 
 | 58 | + | 
 | 59 | +// The config.txt file would be included in your Worker bundle.  | 
 | 60 | +// Refer to the Wrangler documentation for details on how to  | 
 | 61 | +// include additional files.  | 
 | 62 | +const config = readFileSync("/bundle/config.txt", "utf8");  | 
 | 63 | + | 
 | 64 | +export default {  | 
 | 65 | +	async fetch(request) {  | 
 | 66 | +		return new Response(`Config contents: ${config}`);  | 
 | 67 | +	},  | 
 | 68 | +};  | 
 | 69 | +```  | 
 | 70 | + | 
 | 71 | +The `/tmp` directory is writable, and you can use it to create temporary files  | 
 | 72 | +or directories. You can also create symlinks in this directory. However, the  | 
 | 73 | +contents of `/tmp` are not persistent and are unique to each request. This means  | 
 | 74 | +that files created in `/tmp` within the context of one request will not be  | 
 | 75 | +available in other concurrent or subsequent requests.  | 
 | 76 | + | 
 | 77 | +```js  | 
 | 78 | +import { writeFileSync, readFileSync } from "node:fs";  | 
 | 79 | + | 
 | 80 | +export default {  | 
 | 81 | +	fetch(request) {  | 
 | 82 | +		// The file `/tmp/hello.txt` will only exist for the duration  | 
 | 83 | +		// of this request.  | 
 | 84 | +		writeFileSync("/tmp/hello.txt", "Hello, world!");  | 
 | 85 | +		const contents = readFileSync("/tmp/hello.txt", "utf8");  | 
 | 86 | +		return new Response(`File contents: ${contents}`);  | 
 | 87 | +	},  | 
 | 88 | +};  | 
 | 89 | +```  | 
 | 90 | + | 
 | 91 | +The `/dev` directory contains common character devices:  | 
 | 92 | + | 
 | 93 | +- `/dev/null`: A null device that discards all data written to it and returns  | 
 | 94 | +  EOF on read.  | 
 | 95 | +- `/dev/random`: A device that provides random bytes on reads and discards all  | 
 | 96 | +  data written to it. Reading from `/dev/random` is only permitted when within  | 
 | 97 | +  the context of a request.  | 
 | 98 | +- `/dev/full`: A device that always returns EOF on reads and discards all data  | 
 | 99 | +  written to it.  | 
 | 100 | +- `/dev/zero`: A device that provides an infinite stream of zero bytes on reads  | 
 | 101 | +  and discards all data written to it.  | 
 | 102 | + | 
 | 103 | +All operations on the VFS are synchronous. You can use the synchronous,  | 
 | 104 | +asynchronous callback, or promise-based APIs provided by the `node:fs` module  | 
 | 105 | +but all operations will be performed synchronously.  | 
 | 106 | + | 
 | 107 | +Timestamps for files in the VFS are currently always set to the Unix epoch  | 
 | 108 | +(`1970-01-01T00:00:00Z`). This means that operations that rely on timestamps,  | 
 | 109 | +like `fs.stat`, will always return the same timestamp for all files in the VFS.  | 
 | 110 | +This is a temporary limitation that will be addressed in a future release.  | 
 | 111 | + | 
 | 112 | +Since all temporary files are held in memory, the total size of all temporary  | 
 | 113 | +files and directories created count towards your Worker’s memory limit. If you  | 
 | 114 | +exceed this limit, the Worker instance will be terminated and restarted.  | 
 | 115 | + | 
 | 116 | +The file system implementation has the following limits:  | 
 | 117 | + | 
 | 118 | +- The maximum total length of a file path is 4096 characters, including path  | 
 | 119 | +  separators. Because paths are handled as file URLs internally, the limit  | 
 | 120 | +  accounts for percent-encoding of special characters, decoding characters  | 
 | 121 | +  that do not need encoding before the limit is checked. For example, the  | 
 | 122 | +  path `/tmp/abcde%66/ghi%zz' is 18 characters long because the `%66`does  | 
 | 123 | +not need to be percent-encoded and is therefore counted as one character,  | 
 | 124 | +while the`%zz` is an invalid percent-encoding that is counted as 3 characters.  | 
 | 125 | +- The maximum number of path segments is 48. For example, the path `/a/b/c` is  | 
 | 126 | +  3 segments.  | 
 | 127 | +- The maximum size of an individual file is 128 MB total.  | 
 | 128 | + | 
 | 129 | +The following `node:fs` APIs are not supported in Workers, or are only partially  | 
 | 130 | +supported:  | 
 | 131 | + | 
 | 132 | +- `fs.watch` and `fs.watchFile` operations for watching for file changes.  | 
 | 133 | +- The `fs.globSync()` and other glob APIs have not yet been implemented.  | 
 | 134 | +- The `force` option in the `fs.rm` API has not yet bee implemented.  | 
 | 135 | +- Timestamps for files are always set to the Unix epoch (`1970-01-01T00:00:00Z`).  | 
 | 136 | +- File permissions and ownership are not supported.  | 
 | 137 | + | 
 | 138 | +The full `node:fs` API is documented in the [Node.js documentation for `node:fs`](https://nodejs.org/api/fs.html).  | 
0 commit comments