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 🙏

© 2025 – Pkg Stats / Ryan Hefner

opfsx

v0.1.0

Published

An OPFS wrapper providing path support and an API based on Unix commands.

Readme

OPFSX

A wrapper around the Origin private file system providing path support and an API based on Unix commands.

Installation

npm install opfsx

Usage

OPFSX provides "commands" which can be used on the main thread and within workers.
A list of all available commands can be found below with basic code snippets and example usages can be found in ./examples.

Importing

You can import all commands or specific commands individually:

import * as opfsx from "opfsx"

await opfsx.write("hello.txt", "hello world")
await opfsx.tree("/")
import {write, tree} from "opsfx"

write("hello.txt", "hello world")
tree("/")

Path Format

A path like /example/path or even /example/path.txt is ambiguous and could refer to a file or directory.
It's obvious for most commands if a path should be treated as a file or directory (mkdir, ls, tree, etc), however in situations where there could be ambiguity a trailing slash is used to signal that the path is intended as a directory.

Commands

resolve

Resolve the given path into a FileSystemDirectoryHandle or FileSystemFileHandle.
A path with a trailing slash will resolve to a directory and paths without will resolve to a file.

The default behaviour is to throw an error if any directory/file doesn't exist, passing the create: true option will instead create all required directories and potentially the file itself, before returning the handle of the new directory/file.

import * as opfs from "opfsx"

const fileHandle = await opfs.resolve("/example/path/test.txt")

// will resolve to file as there is no trailing slash
const fileHandle2 = await opfs.resolve("/example/path/test", {create: true})

// will cause any missing directories to be created, then return the handle for the 'yet.txt' directory
const directoryHandle = await opfs.resolve("/example/not/create/yet.txt/", {create: true})

The resolve command is useful if you wish to make use of the faster FileSystemSyncAccessHandle within a worker too:

import * as opfs from "opfsx"

const fileHandle = opfs.resolve("/example/path/test.txt")
const syncAccessHandle = await fileHandle.createSyncAccessHandle();

write

Write a string, Blob or File to the given file path. This command will recursively create any missing directories and the file itself if missing.

Write text content to a file:

import * as opfs from "opfsx"

await opfs.write("/example/path/test.txt", "hello world")

Write a file:

import * as opfs from "opfsx"

const markdownFile = new File(["# hello world \n this is some **example** markdown"], "hello.md", {type: "text/markdown"})
await opfs.write(`/example/path/hello.md`, markdownFile)

You are not limited to just text files, you could write things like images too:

import * as opfs from "opfsx"

// assuming an input accepting image files...
const profileImage = document.getElementById("profile-image").files[0];
await opfs.write(`/images/profile/${profileImage.name}`, profileImage)

read

Read a file, returning the File instance retrieved from FileSystemFileHandle.getFile().
If you are writing code within a worker, you may want to consider fetching the handle via resolve() and using FileSystemSyncAccessHandle instead.

import * as opfs from "opfsx"

const file = await opfs.read("/example/path/hello.md")
const content = await file.text()
console.log(file.name) // hello.md
console.log(content) // hello world

Construct URL from an image file:

import * as opfs from "opfsx"

const file = await opfs.read("/images/example.png")
const url = URL.createObjectURL(file)
console.log(file.name) // example.png
console.log(url) // something like 'blob:https://example.com/7bf69880-a2d0-4a12-81a8-56637cc80b23' which you could now add to an <img/> element

ls

List items in a directory. Only direct children are returned by default, but you can pass the recursive: true flag to also include all subdirectories and their files.
This command always returns a flat array, even with the recursive options set. If you wish to list all content while preserving the directory structure, use the tree() command instead.
In future this command may support some form on built-in filtering, but for now it will always return all files and directories.

import * as opfs from "opfsx"

// List files and directoreis at the given location
await opfs.ls("/example/path")

// List all .md files in a directory and all subdiretories
const items = await opfs.ls("/example/nested", {recursive: true})
const markdownFiles = items.filter(item => item.kind === 'file' && item.name.endsWith('.md'))

Recursive list .md files in a directory:

import * as opfs from "opfsx"

const items = await opfs.ls("/example", {recursive: true})
const markdownFiles = items.filter(item => item.kind === 'file' && item.name.endsWith('.md'))

tree

Get the "tree" structure of a directory, recursively reading all subdirectories and files.

import * as opfs from "opfsx"

await opfs.tree("/example")

mkdir

Create a directory, recursively creating any folders in the path that don't exist yet.

import * as opfs from "opfsx"

await opfs.mkdir("/example/nested/path")

rm

Remove a file or directory. To remove a directory, you must pass the recursive: true option.

import * as opfs from "opfsx"

await opfs.rm("/example/hello.md")

// Pass 'recursive' option to delete a directory
await opfs.rm("/", {recursive: true})

cp

Copy a file or directory to another location, will fail if any directory in destination path doesn't exist unless passing create: true option.
In cases where the destination path could be interpreted as either a file or directory, a trailing slash is used to signal that the path is a directory.

Copy a file:

import * as opfs from "opfsx"

await opfs.cp("/example/hello.md", "/example2/hello.md")

Copy an entire directory:

import * as opfs from "opfsx"

// assuming /example2 doesn't exist yet, create option is required here
await opfs.cp("/example", "/example2/nested", {create: true})

Handling ambiguous paths:

import * as opfs from "opfsx"

// test.md would be copied to a file called 'nested' with no file extension:
await opfs.cp("/example/test.md", "/example2/nested")

// test.md would be copied into the directory called 'nested'. This requires the `create` option if the directory doesn't exist yet.
await opfs.cp("/example/test.md", "/example2/nested/", {create: true})

// would copy 'folder' into the 'nested' directory
await opfs.cp("/example/folder", "/example2/nested", {create: true})

mv

OPFS has no concept of moving files, so this command just runs cp() then rm(). The operation will fail if any directory in destination path doesn't exist unless passing create: true option. Ambiguous paths are handled just like cp(), using a trailing slash to signal a directory.

import * as opfs from "opfsx"

await opfs.mv("/example/hello.md", "/example2/hello.md")

await opfs.mv("/example/nested/test1", "/example/new-folder", {create: true})

stat

Get metadata about a given directory or file:

import * as opfs from "opfsx"

await opfs.stat("/example/nested/test1")

Contributions

Feel free to suggest features, give feedback, suggest improvements, raise bugs, open PRs and anything else.

License

This project is released under the MIT license.