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

@epicenter/filesystem

v0.1.0

Published

Filesystem utilities for Epicenter. Markdown parsing, frontmatter handling, and file operations.

Downloads

15

Readme

@epicenter/filesystem

@epicenter/filesystem gives Epicenter a POSIX-style filesystem backed by Yjs data. File metadata lives in a workspace table, each file's content lives in its own Y.Doc-backed document, and the package turns that split into familiar operations like mkdir, writeFile, mv, rm, and stat. Apps use it when they want collaborative data to look and behave like files and folders instead of raw CRDT structures.

Installation

Inside this monorepo:

{
	"dependencies": {
		"@epicenter/filesystem": "workspace:*"
	}
}

This package has a peer dependency on yjs.

Quick usage

The basic setup from the tests is short: define the files table in a workspace, then hand the table helper and document collection to createYjsFileSystem.

import { createWorkspace } from '@epicenter/workspace';
import { createYjsFileSystem, filesTable } from '@epicenter/filesystem';

const ws = createWorkspace({ id: 'test', tables: { files: filesTable } });
const fs = createYjsFileSystem(ws.tables.files, ws.documents.files.content);

await fs.mkdir('/docs');
await fs.writeFile('/docs/hello.txt', 'Hello World');
await fs.appendFile('/docs/hello.txt', ' again');
await fs.mv('/docs/hello.txt', '/docs/greeting.txt');

const content = await fs.readFile('/docs/greeting.txt');
const stats = await fs.stat('/docs/greeting.txt');

That is the actual shape used in src/file-system.test.ts. The object returned by createYjsFileSystem matches the just-bash filesystem interface, with a few extra helpers layered on top.

How the model works

The package splits filesystem state into two parts.

  • The filesTable row tracks metadata: id, name, parentId, type, size, timestamps, and soft-delete state.
  • The content for each file lives in a document keyed by that row ID.

That gives you a useful mix of properties:

  • directory listings and path lookups stay cheap because they only touch table metadata
  • file content remains collaborative because each file is still a Yjs document
  • soft deletes are easy because rm marks rows as trashed instead of immediately destroying history

It feels like a filesystem because the package keeps resolving paths, parents, and names for you. Underneath, it is still workspace data all the way down.

API overview

Main exports from src/index.ts:

  • createYjsFileSystem() and YjsFileSystem — the POSIX-like filesystem orchestrator
  • filesTable, FileRow, and ColumnDefinition — the shared metadata table and related types
  • createFileTree() and createFileSystemIndex() — path/index helpers for the metadata layer
  • FS_ERRORS and FsErrorCode — filesystem-style error helpers
  • posixResolve() — path normalization for slash-separated paths
  • Markdown helpers like parseFrontmatter(), serializeMarkdownWithFrontmatter(), and serializeXmlFragmentToMarkdown()
  • Link helpers like convertWikilinksToInternalLinks() and makeInternalHref()
  • createSqliteIndex() — optional SQLite-backed indexing for search results

If you only need the filesystem abstraction, start with createYjsFileSystem() and filesTable. The rest supports indexing, markdown, and tree-level operations.

POSIX-style behavior

The surface area is intentionally familiar.

  • mkdir, readdir, and readdirWithFileTypes cover directory work
  • writeFile, appendFile, readFile, and readFileBuffer cover content I/O
  • mv and cp handle renames and copies
  • rm performs soft deletes, with recursive behavior for folders
  • stat, lstat, exists, realpath, and resolvePath cover inspection and path resolution

There are a few deliberate limits. Symlinks and hard links always throw ENOSYS. Permissions are mostly a validated no-op. That is not an accident—it keeps the model aligned with a collaborative CRDT-backed store instead of pretending to be a full kernel filesystem.

Relationship to other packages

@epicenter/filesystem sits on top of @epicenter/workspace and turns workspace tables plus document collections into file semantics.

@epicenter/workspace   typed tables + documents
        │
@epicenter/filesystem  tree index + file content orchestration
        │
apps like Opensidian   markdown notes, paths, links, indexing

In the monorepo, apps can treat shared workspace content as files without giving up Yjs collaboration. That is the point of this package.

Most Epicenter apps use @epicenter/workspace directly and don't need this package. Workspace tables are the right default when the app knows the shape of every record upfront—notes with titles, bookmarks with URLs, chat messages with timestamps. Reach for @epicenter/filesystem when the data model is inherently hierarchical files: a code editor, a note vault with nested folders, anything where users expect a file tree and path-based operations.

Honeycrisp (Apple Notes clone) uses only workspace tables. Opensidian (file-based editor with a bash terminal) uses both—filesTable from this package alongside plain workspace tables for chat and settings. See Your Data Is Probably a Table, Not a File for the full comparison.

License

MIT.