This document provides context for AI assistants working on JavaScript Solid Server (JSS).
A lightweight Solid server implementation focused on simplicity and modern JavaScript. Alternative to Node Solid Server (NSS) and Community Solid Server (CSS).
Key differences from other Solid servers:
- Single-file JSON-LD storage (no quad stores)
- Content negotiation converts JSON-LD ↔ Turtle on the fly
- Built on Fastify (not Express)
- Uses oidc-provider for identity
- Supports Nostr NIP-98 authentication (unique to JSS)
src/
├── server.js # Fastify setup, route registration
├── handlers/ # LDP operations (GET, PUT, POST, PATCH, DELETE)
│ ├── resource.js # File operations
│ └── container.js # Directory operations, pod creation
├── auth/ # Authentication
│ ├── middleware.js # WAC authorization hook
│ ├── solid-oidc.js # DPoP token verification
│ ├── nostr.js # NIP-98 Schnorr signatures
│ └── token.js # Simple Bearer tokens
├── idp/ # Identity Provider (oidc-provider)
│ ├── provider.js # OIDC configuration
│ ├── interactions.js # Login/consent UI handlers
│ └── accounts.js # User account storage
├── wac/ # Web Access Control
│ ├── checker.js # Permission checking
│ └── parser.js # ACL file parsing/generation
├── rdf/ # RDF handling
│ ├── conneg.js # Content negotiation
│ └── turtle.js # Turtle ↔ JSON-LD conversion
├── notifications/ # WebSocket real-time updates
│ ├── websocket.js # solid-0.1 protocol handler
│ └── events.js # Event emitter for changes
├── ldp/ # Linked Data Platform
│ ├── headers.js # LDP response headers
│ └── container.js # Container JSON-LD generation
└── storage/ # File system operations
└── filesystem.js # Read/write/stat/list
All RDF is stored as JSON-LD. When clients request Turtle, we convert on the fly. This simplifies storage and allows non-RDF tools to read the data.
WebID profiles are HTML documents with embedded <script type="application/ld+json">. This allows:
- Human-readable profiles in browsers
- Machine-readable RDF via content negotiation
- Mashlib renders the profile using the embedded data
When subdomains: true, each pod gets its own subdomain (alice.example.com). This provides browser security isolation. Storage path includes pod name, but URLs use subdomains.
Mashlib expects Settings/ (capital S) with:
Settings/Preferences.ttlSettings/publicTypeIndex.ttlSettings/privateTypeIndex.ttl
Earlier versions used lowercase settings/prefs which broke mashlib.
- Files stored as JSON-LD regardless of upload format
.ttlextension triggers Turtle response regardless of Accept header- Container listings need conneg too (fixed in v0.0.33)
These paths bypass the auth middleware:
/.pods- Pod creation/.notifications- WebSocket endpoint/idp/*- Identity provider routes/.well-known/*- Discovery endpoints- OPTIONS requests
Uses legacy solid-0.1 protocol (not Solid Notifications Protocol):
Server: protocol solid-0.1
Client: sub https://example.org/resource
Server: ack https://example.org/resource
Server: pub https://example.org/resource (on change)
Discovered via Updates-Via header.
Solid-OIDC uses DPoP-bound tokens. The DPoP proof must match:
- HTTP method (htm)
- Request URL (htu)
- Be recent (iat within 5 minutes)
- Key thumbprint matches token binding (cnf.jkt)
WAC ACLs use acl:default for inheritance. When checking permissions:
- Look for resource-specific ACL (resource.acl or .acl for containers)
- Walk up to parent containers checking for
acl:defaultrules - Stop at pod root
npm test # Run all tests
npm run test:cth # Conformance Test Harness (requires setup)Tests use in-memory server instances. See test/helpers.js for test utilities.
npm install -g javascript-solid-server
jss --port 443 --ssl-key key.pem --ssl-cert cert.pem --idp --multiuserHAProxy handles SSL termination, JSS runs on localhost:8443. Wildcard cert needed for subdomain mode.
pm2 start "jss --config config.json" --name solid
pm2 logs solid
pm2 restart solid- oidc-provider: OpenID Connect implementation (complex, many warnings are normal)
- n3: Turtle/N3 parsing and serialization
- jose: JWT/JWK handling for Solid-OIDC
- @fastify/websocket: WebSocket support
Issues: https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues