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

@siglum/filesystem

v0.2.1

Published

Unified filesystem abstraction for browser storage (OPFS, IndexedDB)

Readme

@siglum/filesystem

Unified filesystem abstraction for browser storage with automatic fallback.

Installation

npm install @siglum/filesystem

Quick Start

import { fileSystem } from '@siglum/filesystem'

// Auto-select best backend (OPFS if available, else IndexedDB)
await fileSystem.mountAuto('/documents')

// Use unified API
await fileSystem.writeFile('/documents/main.tex', '\\documentclass{article}...')
const content = await fileSystem.readFile('/documents/main.tex')

Auto-mounting with Fallback

The mountAuto method automatically selects the best available backend:

import { fileSystem } from '@siglum/filesystem'

// Uses OPFS if available, falls back to IndexedDB
const backend = await fileSystem.mountAuto('/documents')
console.log(`Using ${backend.name} backend`)  // 'opfs' or 'indexeddb'

Force a Specific Backend

// Force OPFS (throws if not available)
await fileSystem.mountAuto('/documents', { backend: 'opfs' })

// Force IndexedDB
await fileSystem.mountAuto('/legacy', { backend: 'indexeddb' })

// Explicit auto (same as default)
await fileSystem.mountAuto('/data', { backend: 'auto' })

Check OPFS Availability

import { isOPFSAvailable } from '@siglum/filesystem'

if (isOPFSAvailable()) {
  console.log('OPFS is supported!')
}

Check Backend Type

// Get the backend type for a mounted path
const type = fileSystem.getBackendType('/documents')  // 'opfs', 'indexeddb', or null

Manual Backend Selection

For direct control, import and mount backends explicitly:

import { fileSystem, opfsBackend, indexedDBBackend } from '@siglum/filesystem'

fileSystem.mount('/documents', opfsBackend)
fileSystem.mount('/legacy', indexedDBBackend)

Batch Operations

For reading multiple files efficiently:

const paths = ['/documents/a.txt', '/documents/b.txt', '/documents/c.txt']
const results = await fileSystem.readBinaryBatch(paths)
// Returns Map<string, Uint8Array> - missing files are omitted

For writing multiple files with progress tracking:

const entries = [
  { path: '/documents/a.txt', content: new Uint8Array([1, 2, 3]) },
  { path: '/documents/b.txt', content: new Uint8Array([4, 5, 6]) },
]

await fileSystem.writeBinaryBatch(entries, {
  createParents: true,
  onProgress: (completed, total) => console.log(`${completed}/${total}`),
  concurrency: 20,  // parallel writes (default: 20)
})

Web Worker Support

For accessing the filesystem from Web Workers (including classic workers that can't use ES modules):

// In your worker
import {
  readBinaryIDB,
  writeBinaryIDB,
  readBinaryOPFS,
  writeBinaryOPFS,
  isOPFSAvailable
} from '@siglum/filesystem/worker'

// Read/write directly without the full service
const data = await readBinaryIDB('/path/to/file')
await writeBinaryOPFS('/path/to/file', new Uint8Array([1, 2, 3]))

Storage Constants

Access the underlying storage identifiers (useful for direct IndexedDB/OPFS access):

import {
  IDB_NAME,        // 'siglum_filesystem'
  IDB_VERSION,     // 1
  IDB_FILES_STORE, // 'files'
  IDB_DIRS_STORE,  // 'directories'
  OPFS_ROOT        // ''
} from '@siglum/filesystem/constants'

Backends

OPFS (Origin Private File System)

Fast, persistent storage using the browser's Origin Private File System API.

  • Best performance for large files
  • Streaming support

IndexedDB

Fallback for browsers without OPFS support.

  • Universal browser support
  • Slightly slower for large files

API

FileSystemService

Mounting

  • mount(path, backend) - Mount a backend at a path
  • mountAuto(path, options?) - Mount with automatic backend selection
  • unmount(path) - Unmount a backend
  • getMounts() - List all mount points
  • isMounted(path) - Check if a path has a mounted backend
  • getBackendType(path) - Get backend type ('opfs' | 'indexeddb' | null)

File Operations

  • readFile(path) - Read text content
  • writeFile(path, content, options?) - Write text content
  • readBinary(path) - Read binary data
  • writeBinary(path, data, options?) - Write binary data
  • readBinaryBatch(paths) - Read multiple files efficiently (returns Map<string, Uint8Array>)
  • writeBinaryBatch(entries, options?) - Write multiple files with progress tracking
  • deleteFile(path) - Delete a file
  • copyFile(src, dest) - Copy a file
  • rename(oldPath, newPath) - Rename or move a file

Directory Operations

  • mkdir(path) - Create directory (and parents)
  • rmdir(path, options?) - Remove directory ({ recursive?: boolean })
  • readdir(path) - List directory contents (returns FileEntry[])

Query Operations

  • exists(path) - Check if path exists
  • stat(path) - Get file/directory stats (returns FileStats)

Events

  • subscribe(handler) - Subscribe to filesystem events, returns unsubscribe function

Types

interface FileStats {
  size: number
  isDirectory: boolean
  isFile: boolean
  mtime: Date
}

interface FileEntry {
  name: string
  path: string
  isDirectory: boolean
}

type FileSystemEvent =
  | { type: 'file:created'; path: string }
  | { type: 'file:modified'; path: string }
  | { type: 'file:deleted'; path: string }
  | { type: 'directory:created'; path: string }
  | { type: 'directory:deleted'; path: string }

License

MIT