fs
The fs package provides filesystem utilities built on the web File API. It bridges the gap between Node.js filesystem operations and web-standard File objects used throughout Remix.
Installation
The filesystem utilities are included with Remix. No additional installation is needed.
Import
ts
import { openLazyFile, writeFile } from 'remix/fs'API
openLazyFile(path)
Creates a LazyFile from a file on disk. The file's content is not read until it is accessed. Metadata (name, size, MIME type, last modified) is read immediately from the filesystem.
ts
function openLazyFile(path: string): Promise<LazyFile>ts
let file = await openLazyFile('./uploads/photo.jpg')
console.log(file.name) // 'photo.jpg'
console.log(file.type) // 'image/jpeg'
console.log(file.size) // 1048576
console.log(file.lastModified) // 1704067200000
// Content is read lazily
let stream = file.stream()writeFile(path, file)
Writes a File (or Blob) to the specified path on disk. Parent directories are created automatically if they do not exist.
ts
function writeFile(path: string, file: File | Blob): Promise<void>ts
let file = new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })
await writeFile('./output/hello.txt', file)Examples
Serve a File from Disk
ts
import { openLazyFile } from 'remix/fs'
import { createFileResponse } from 'remix/response/file'
router.map(fileRoute, async ({ request, params }) => {
let file = await openLazyFile(`./uploads/${params.filename}`)
return createFileResponse(file, request)
})The file is streamed to the client without being buffered in memory. createFileResponse automatically handles ETag headers, conditional requests, and byte-range requests.
Save an Uploaded File
ts
import { parseFormData, FileUpload } from 'remix/form-data-parser'
import { writeFile } from 'remix/fs'
router.map(uploadRoute, async ({ request }) => {
let formData = await parseFormData(request)
let upload = formData.get('file') as FileUpload
await writeFile(`./uploads/${upload.name}`, upload)
return new Response('Saved')
})Copy a File
ts
import { openLazyFile, writeFile } from 'remix/fs'
let file = await openLazyFile('./source/document.pdf')
await writeFile('./backup/document.pdf', file)Generate and Write a File
ts
import { writeFile } from 'remix/fs'
let csv = 'name,email\nAlice,alice@example.com\nBob,bob@example.com'
let file = new File([csv], 'users.csv', { type: 'text/csv' })
await writeFile('./exports/users.csv', file)Related
- lazy-file --- Deferred file reading.
- file-storage --- Key/value file storage abstraction.
- response --- File response helpers with ETag and range support.