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 request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions