Skip to content

Extract Minimal Viable LWS Server #89

@melvincarvalho

Description

@melvincarvalho

Summary

Create a minimal, standalone LWS (Linked Web Storage) server extracted from JSS that implements only the core W3C LWS protocol without Solid-specific or extended features.

Goal: Reference implementation and minimal server for LWS protocol testing, embedding, and education.

Related:

Motivation

JSS has grown to support many protocols and features:

  • Solid Protocol (LDP-based CRUD)
  • Solid-OIDC (DPoP, dynamic registration, RS256/ES256)
  • Passkey authentication (WebAuthn/FIDO2)
  • WebID-TLS client certificates
  • Nostr authentication (NIP-98)
  • ActivityPub federation
  • Nostr relay (NIP-01)
  • Git HTTP backend
  • Mashlib data browser
  • WebSocket notifications
  • Storage quotas
  • N3 Patch, SPARQL Update
  • Content negotiation (Turtle ↔ JSON-LD)

Problem: This makes JSS heavy for users who just want simple Linked Data storage following LWS spec.

Solution: Extract a minimal LWS server (~500-1000 LOC) that focuses solely on the core protocol.

Use Cases

  1. Reference Implementation - Demonstrate LWS spec compliance
  2. Client Testing - Lightweight server for testing LWS clients
  3. Embedding - Drop into other Node.js apps as a module
  4. Education - Learn LWS protocol without distractions
  5. Microservices - Lightweight storage layer for service architectures
  6. Development - Fast startup, minimal dependencies

Scope: What to Include

Core LWS Protocol (Minimal)

  • GET - Read resources and containers
  • HEAD - Resource metadata
  • POST - Create resources with Slug header
  • PUT - Create or update resources
  • DELETE - Remove resources
  • OPTIONS - CORS preflight
  • ETags - Concurrency control (If-Match, If-None-Match)
  • Link headers - Resource types, container metadata
  • CORS - Cross-origin support
  • File-based storage - Simple filesystem backend

Optional (Phase 2)

  • ⚠️ PATCH - Simple JSON Merge Patch (RFC 7386) only
  • ⚠️ Linkset endpoints - Metadata via /resource;linkset (when LWS spec defines it)
  • ⚠️ Basic auth - Simple token-based authentication
  • ⚠️ Multi-user - Optional pod isolation

Scope: What to EXCLUDE

All Solid-specific and extended features:

  • ❌ Solid-OIDC (full IdP/DPoP implementation)
  • ❌ Passkey authentication
  • ❌ WebID-TLS
  • ❌ Nostr authentication/relay
  • ❌ ActivityPub federation
  • ❌ Git HTTP backend
  • ❌ Mashlib data browser
  • ❌ WebSocket notifications
  • ❌ N3 Patch
  • ❌ SPARQL Update
  • ❌ Content negotiation (Turtle ↔ JSON-LD)
  • ❌ Storage quotas
  • ❌ Invite-only registration
  • ❌ WAC (Web Access Control)
  • ❌ WebID profiles
  • ❌ Complex IdP interactions

Proposed Architecture

File Structure

```
lws-server/
├── package.json
├── README.md
├── index.js # Main entry point
├── lib/
│ ├── server.js # Fastify setup
│ ├── handlers/
│ │ ├── get.js # GET/HEAD
│ │ ├── put.js # PUT
│ │ ├── post.js # POST
│ │ ├── delete.js # DELETE
│ │ └── options.js # OPTIONS
│ ├── storage.js # Filesystem operations
│ ├── headers.js # Link/ETag headers
│ └── auth.js # Simple token auth (optional)
└── test/
└── lws.test.js
```

Size Target

  • ~500-1000 LOC (vs JSS's ~8000+ LOC)
  • ~5-10 dependencies (vs JSS's 22)
  • Single file option - Could bundle to single ESM file for embedding

Dependencies (Minimal)

```json
{
"dependencies": {
"fastify": "^5.x",
"@fastify/cors": "^10.x",
"fs-extra": "^11.x"
},
"devDependencies": {
"node:test": "builtin"
}
}
```

API Example

Programmatic Use

```javascript
import { createLWSServer } from 'lws-server';

const server = createLWSServer({
port: 3000,
root: './data',
cors: true,
auth: false // Optional token-based auth
});

await server.listen();
console.log('LWS server running on http://localhost:3000');
```

CLI Use

```bash
npm install -g lws-server

lws-server --port 3000 --root ./data
```

Single-User Mode (Default)

```bash

Creates flat structure (no /alice/ containers)

PUT /data.json # Creates /data.json
POST / + Slug=file # Creates /file.json
GET / # Lists all resources
```

Multi-User Mode (Optional)

```bash
lws-server --multiuser

PUT /alice/data.json # Creates /alice/data.json
PUT /bob/data.json # Creates /bob/data.json
```

Extraction Strategy

Option 1: Fork and Strip Down

  1. Fork JSS to new repo: `lws-server`
  2. Remove all non-LWS features
  3. Simplify handlers
  4. Remove dependencies
  5. Refactor to minimal core

Pros:

  • Reuse existing, tested code
  • Keep git history for core features
  • Faster initial development

Cons:

  • May carry technical debt
  • Harder to achieve size target

Option 2: Clean Room Implementation

  1. Create new repo from scratch
  2. Reference JSS handlers for logic
  3. Implement only LWS core
  4. Modern ESM-first design

Pros:

  • Clean codebase
  • Easier to hit size target
  • No legacy patterns

Cons:

  • More initial work
  • Need to retest everything

Recommendation: Option 1 (Fork and Strip)

Start with JSS handlers, progressively remove features until minimal.

Implementation Plan

Phase 1: Core Extraction (~4-8 hours)

  • Create `lws-server` repo
  • Extract core handlers (GET, PUT, POST, DELETE, OPTIONS)
  • Extract filesystem storage module
  • Extract header generation (Link, ETag, CORS)
  • Remove all Solid-specific code
  • Remove all extended features (IdP, passkeys, etc.)
  • Simplify server setup

Phase 2: Polish (~2-4 hours)

  • Add CLI interface
  • Add programmatic API
  • Write minimal README
  • Add basic tests
  • Publish to npm as `lws-server`

Phase 3: Documentation (~1-2 hours)

  • API documentation
  • LWS compliance notes
  • Migration guide from JSS
  • Embedding examples

Success Metrics

Size:

  • ✅ < 1000 LOC
  • ✅ < 10 dependencies
  • ✅ < 5MB node_modules

Performance:

  • ✅ < 100ms startup time
  • ✅ < 5ms per request (simple GET)
  • ✅ < 50MB memory footprint

Usability:

  • ✅ Single command to start
  • ✅ Zero config for basic use
  • ✅ Embeddable in Node.js apps

Comparison Table

Feature JSS lws-server
LOC ~8000+ ~500-1000
Dependencies 22 ~5-10
Startup ~500ms <100ms
Memory ~150MB <50MB
Protocols LDP, LWS, OIDC, AP, Nostr, Git LWS only
Auth 5 methods Simple token
Features 20+ 5 core CRUD

Package Name Options

  • `lws-server` ✅ (recommended)
  • `minimal-lws`
  • `lws-storage`
  • `simple-lws`
  • `lws-core`

Relationship to Existing Work

This builds on:

Differences:

Use together:

  • JSS `--lws-mode` for production multi-protocol server
  • `lws-server` for embedding, testing, education

Questions to Resolve

  1. Repository location: New org or under JavaScriptSolidServer?
  2. npm scope: Publish as `lws-server` or `@lwsprotocol/server`?
  3. Versioning: Start at 1.0.0 or 0.1.0?
  4. License: MIT (same as JSS)?
  5. Auth model: Include simple token auth or be completely auth-free?
  6. Timing: Wait for LWS spec to mature or start now as reference?

Priority: Low-Medium - Useful for ecosystem, not urgent
Effort: 1-2 days for functional MVP
Dependencies: None (can start anytime, spec still evolving)
Status: Awaiting LWS ecosystem signals (per #87 decision criteria)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestnostrNostr relay, did:nostr auth, NIP-related

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions