npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@remix-run/file-storage

v1.0.1

Published

Key/value storage for JavaScript File objects

Readme

file-storage

Key/value storage interfaces for server-side File objects. file-storage gives Remix apps one consistent API across local disk and memory backends.

Features

  • Simple API - Intuitive key/value API (like Web Storage, but for Files instead of strings)
  • Multiple Backends - Built-in filesystem and memory backends
  • Streaming Support - Stream file content to and from storage
  • Metadata Preservation - Preserves all File metadata including file.name, file.type, file.size, and file.lastModified

Installation

npm i remix

Usage

File System

Use a directory dedicated to this backend. You can reuse an existing storage directory; storing a file under an existing key replaces that entry.

import { createFsFileStorage } from 'remix/file-storage/fs'

let storage = createFsFileStorage('./user/files')

let file = new File(['hello world'], 'hello.txt', { type: 'text/plain' })
let key = 'hello-key'

// Put the file in storage.
await storage.set(key, file)

// Then, sometime later...
let fileFromStorage = await storage.get(key)

if (fileFromStorage != null) {
  // All of the original file's metadata is intact
  fileFromStorage.name // 'hello.txt'
  fileFromStorage.type // 'text/plain'

  // The filesystem backend returns a LazyFile, so you can stream it directly.
  let response = new Response(fileFromStorage.stream())
}

// To remove from storage
await storage.remove(key)

Replacement Writes

set() and put() stage complete content and metadata in uniquely named temporary files beside their destinations, then atomically rename the content file into place followed by the metadata file. An upload stream error, size-limit rejection, or other failure during staging leaves the previous entry untouched.

The two renames are not a transaction. Between them, a reader can see complete new content with old metadata. If the metadata rename fails or the process stops between renames, that mismatch remains: the filename, MIME type, modification time, and listed size can be stale. get() obtains the size from the content file. For a new key, the content remains unpublished: get() returns null, has() returns false, and listings omit it.

A rejected write may therefore have changed the content. A successful retry replaces both files; supply a fresh upload if the original stream has already been consumed. Rolling back the package version does not repair an interrupted publication.

The storage key's SHA-256 hash determines the <hash>.dat and <hash>.meta.json paths. The file's name, content type, and bytes do not affect those paths. The filenames and metadata schema are unchanged, so existing entries need no migration and older versions can read and write entries produced by this version, subject to the filesystem permissions below.

Filesystem Requirements

The storage directory is managed by the application. Keep the application's filesystem user, groups, and directory inheritance rules consistent across restarts and deployments. Configure access for other readers through directory permissions and inheritance; custom per-file ownership and ACL changes are not preserved when an entry is replaced.

Use a filesystem that supports atomic rename on the same filesystem. The process needs permission to create, rename, and remove files in each storage subdirectory. Replacements preserve existing POSIX read/write/execute mode bits; owner, group, and ACLs follow the filesystem's rules for newly created files. Writes do not need to read existing metadata. Atomic rename does not guarantee persistence across power loss.

Coordinating Operations

Callers must coordinate overlapping reads, writes, removals, and listings across all instances and processes sharing the directory, including older versions. Coordination must cover consuming returned lazy files or finishing/canceling their streams, not just awaiting get() or put(). This backend does not provide locking or snapshot reads.

Temporary files are removed on a best-effort basis. A stopped process or failed cleanup can leave <hash>.dat.<uuid>.upload and <hash>.meta.json.<uuid>.upload files beside stored entries. Storage ignores these files, and each write uses a fresh UUID so abandoned uploads do not block later writes. Remove abandoned files only while all operations are stopped.

Related Packages

  • file-storage-s3 - S3 backend for file-storage
  • form-data-parser - Pairs well with this library for storing FileUpload objects received in multipart/form-data requests
  • lazy-file - The streaming File implementation used internally to stream files from storage

License

See LICENSE