PHPackages                             decent-newsroom/nostr-drive - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. decent-newsroom/nostr-drive

ActiveLibrary[File &amp; Storage](/categories/file-storage)

decent-newsroom/nostr-drive
===========================

A framework-agnostic PHP library for managing filesystem-like hierarchies on Nostr using Drive (kind:30042) and Folder (kind:30045) events

0.1.1(1mo ago)00MITPHPPHP ^8.2

Since Jan 16Pushed 1mo agoCompare

[ Source](https://github.com/decent-newsroom/nostr-drive)[ Packagist](https://packagist.org/packages/decent-newsroom/nostr-drive)[ RSS](/packages/decent-newsroom-nostr-drive/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (1)Versions (4)Used By (0)

nostr-drive
===========

[](#nostr-drive)

A framework-agnostic PHP library that implements a filesystem-like hierarchy on Nostr using Drive events (kind:30042) and Folder events (kind:30045). It provides deterministic CRUD for drives and folders, plus membership operations (add/remove/move/reorder) over addressable event coordinates.

Key Concepts
------------

[](#key-concepts)

- **Coordinate-first design**: Folder membership uses `a` tags (coordinates: `kind:pubkey:d-tag`) as the canonical reference for addressable events
- **Stable across updates**: Coordinates remain stable when events are replaced, unlike event IDs
- **Drive mounts roots**: Drive events mount root folders via `a` tags
- **Order matters**: Tag order defines display order (no explicit position field needed)

Event Format Examples
---------------------

[](#event-format-examples)

### Drive Event (kind:30042)

[](#drive-event-kind30042)

```
{
  "kind": 30042,
  "pubkey": "author_pubkey",
  "created_at": 1234567890,
  "content": "",
  "tags": [
    ["d", "my-drive"],
    ["title", "My Main Drive"],
    ["description", "Personal files and folders"],
    ["a", "30045:author_pubkey:themes", "wss://relay.example"],
    ["a", "30045:author_pubkey:magazines", "wss://relay.example"],
    ["a", "30045:author_pubkey:calendar", "wss://relay.example"]
  ]
}
```

### Folder Event (kind:30045)

[](#folder-event-kind30045)

```
{
  "kind": 30045,
  "pubkey": "author_pubkey",
  "created_at": 1234567891,
  "content": "",
  "tags": [
    ["d", "themes"],
    ["title", "Themes"],
    ["description", "Website themes and templates"],
    ["a", "30045:author_pubkey:themes/default", "wss://relay.example", "", "default"],
    ["a", "30041:author_pubkey:readme", "wss://relay.example", "event_id_hint", "README"],
    ["a", "30024:author_pubkey:article-1", "wss://relay.example"]
  ]
}
```

**Note:** Membership tags use `a` tag format:

- Minimal: `["a", "kind:pubkey:d-tag", "relay-hint"]`
- Extended: `["a", "kind:pubkey:d-tag", "relay-hint", "last-event-id", "name-hint"]`

Allowed Content Kinds
---------------------

[](#allowed-content-kinds)

Folders may contain entries with the following kinds:

- `30040` - Index
- `30041` - AsciiDoc content
- `30024` - Markdown article
- `30023` - Markdown draft
- `30045` - Folder (allows nesting)
- `31924` - Calendar (NIP-52)
- `31923` - Time-based calendar event (NIP-52)
- `31922` - Date-based calendar event (NIP-52)

Usage Example
-------------

[](#usage-example)

```
use DecentNewsroom\NostrDrive\Domain\Coordinate;
use DecentNewsroom\NostrDrive\Domain\FolderEntry;
use DecentNewsroom\NostrDrive\Service\DriveService;
use DecentNewsroom\NostrDrive\Service\FolderService;

// Create a drive coordinate
$driveCoord = new Coordinate(30042, $pubkey, 'my-drive');

// Create root folder coordinates
$themesCoord = new Coordinate(30045, $pubkey, 'themes');
$magazinesCoord = new Coordinate(30045, $pubkey, 'magazines');

// Create drive with root mounts
$drive = $driveService->create(
    $driveCoord,
    [$themesCoord, $magazinesCoord],
    'My Drive',
    'Personal workspace'
);

// Create a folder
$folder = $folderService->create(
    $themesCoord,
    [],
    'Themes',
    'Website themes'
);

// Add entry to folder
$articleCoord = new Coordinate(30024, $pubkey, 'my-article');
$entry = new FolderEntry($articleCoord, 'wss://relay.example', null, 'My Article');
$folderService->addEntry($themesCoord, $entry);

// Reorder entries
$coord1 = new Coordinate(30024, $pubkey, 'article-1');
$coord2 = new Coordinate(30024, $pubkey, 'article-2');
$folderService->reorderEntries($themesCoord, [$coord2, $coord1]);
```

Architecture
------------

[](#architecture)

- **Domain Models**: `Coordinate`, `Drive`, `Folder`, `FolderEntry`
- **Services**: `DriveService`, `FolderService` (CRUD + membership ops)
- **Contracts**: `EventStoreInterface` (adapter for relay communication)
- **Validation**: `KindValidator` (allowlist enforcement)

Delete vs Archive
-----------------

[](#delete-vs-archive)

Because these are replaceable events, "delete" is not reliably enforceable at the network level. The library provides:

- **Unlink**: Remove membership from parent folder
- **Archive**: Set `["status", "archived"]` tag (optional convention)

For NIP-09 deletions, implement at the integration layer.

See Also
--------

[](#see-also)

- [Integration Guide](docs/INTEGRATION.md) - How to use this library in another project
- [Full Specification](docs/SPECIFICATION.md) - Comprehensive technical spec
- [TODO](docs/TODO.md) - Implementation notes and refactoring guidance

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance91

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~100 days

Total

2

Last Release

42d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d4ffb86c945b20bb7352e03d7a50b84cb3a14056c6f846108c123b8fd0f49a1a?d=identicon)[nusapuksic](/maintainers/nusapuksic)

---

Top Contributors

[![nusapuksic](https://avatars.githubusercontent.com/u/18485210?v=4)](https://github.com/nusapuksic "nusapuksic (5 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (1 commits)")

---

Tags

filesystemnostrdrivedecentralized

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/decent-newsroom-nostr-drive/health.svg)

```
[![Health](https://phpackages.com/badges/decent-newsroom-nostr-drive/health.svg)](https://phpackages.com/packages/decent-newsroom-nostr-drive)
```

###  Alternatives

[league/flysystem

File storage abstraction for PHP

13.6k665.7M2.4k](/packages/league-flysystem)[league/flysystem-aws-s3-v3

AWS S3 filesystem adapter for Flysystem.

1.7k277.8M952](/packages/league-flysystem-aws-s3-v3)[knplabs/gaufrette

PHP library that provides a filesystem abstraction layer

2.5k40.9M129](/packages/knplabs-gaufrette)[knplabs/knp-gaufrette-bundle

Allows to easily use the Gaufrette library in a Symfony project

72429.6M99](/packages/knplabs-knp-gaufrette-bundle)[league/flysystem-local

Local filesystem adapter for Flysystem.

226254.9M71](/packages/league-flysystem-local)[oneup/flysystem-bundle

Integrates Flysystem filesystem abstraction library to your Symfony project.

64323.5M78](/packages/oneup-flysystem-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
