Skip to content

Quick Start

This 5-minute tutorial will get you started with Enhanced s5.js, from installation to uploading your first file.

  • Node.js 20+ or modern browser
  • Basic JavaScript/TypeScript knowledge
  • npm or yarn package manager
Terminal window
npm install @julesl23/s5js@beta
import { S5, generatePhrase } from '@julesl23/s5js';
// Create S5 instance and connect to network
const s5 = await S5.create({
initialPeers: [
"wss://z2DWuPbL5pweybXnEB618pMnV58ECj2VPDNfVGm3tFqBvjF@s5.ninja/s5/p2p",
"wss://z2Das8aEF7oNoxkcrfvzerZ1iBPWfm6D7gy3hVE4ALGSpVB@node.sfive.net/s5/p2p"
]
});

The S5 instance automatically connects to the network using the provided peer list.

Your identity controls access to your files. Enhanced s5.js uses 12-word seed phrases compatible with BIP-39.

// Generate a new seed phrase
const seedPhrase = generatePhrase(s5.api.crypto);
console.log('Save this seed phrase:', seedPhrase);
// Load the identity
await s5.recoverIdentityFromSeedPhrase(seedPhrase);

Important: Save your seed phrase securely! You’ll need it to recover your files.

// Use your existing seed phrase
const existingSeedPhrase = "word1 word2 word3 ... word12";
await s5.recoverIdentityFromSeedPhrase(existingSeedPhrase);

S5 portals provide upload services. Register on a portal to enable file uploads:

// Register on s5.vup.cx (supports Enhanced s5.js)
await s5.registerOnNewPortal("https://s5.vup.cx");

This creates an account on the portal using your identity. The portal will store your uploaded files.

// Create initial directory structure
await s5.fs.ensureIdentityInitialized();

This creates home and archive directories in your S5 storage — but only for a genuinely new identity. If the root already exists, existing directories are never overwritten (a partial root is healed; a root that exists but is temporarily unreadable throws a retryable error instead of being re-initialized). It’s safe to call on every startup.

// Store a text file
await s5.fs.put('home/documents/hello.txt', 'Hello, S5!');
console.log('✅ File uploaded!');
// Get the file back
const content = await s5.fs.get('home/documents/hello.txt');
console.log('File content:', content); // "Hello, S5!"
// List all files in home/documents
for await (const item of s5.fs.list('home/documents')) {
console.log(`${item.type}: ${item.name} (${item.size} bytes)`);
}

Here’s a complete working example combining all steps:

import { S5, generatePhrase } from '@julesl23/s5js';
async function quickStart() {
// 1. Create S5 instance
const s5 = await S5.create({
initialPeers: [
"wss://z2DWuPbL5pweybXnEB618pMnV58ECj2VPDNfVGm3tFqBvjF@s5.ninja/s5/p2p"
]
});
// 2. Generate seed phrase (save this!)
const seedPhrase = generatePhrase(s5.api.crypto);
console.log('🔑 Seed phrase:', seedPhrase);
// 3. Load identity
await s5.recoverIdentityFromSeedPhrase(seedPhrase);
// 4. Register on portal
await s5.registerOnNewPortal("https://s5.vup.cx");
// 5. Initialize filesystem
await s5.fs.ensureIdentityInitialized();
// 6. Upload files
await s5.fs.put('home/hello.txt', 'Hello, S5!');
await s5.fs.put('home/data.json', { message: 'JSON works too!' });
// 7. Read files back
const text = await s5.fs.get('home/hello.txt');
const json = await s5.fs.get('home/data.json');
console.log('Text file:', text);
console.log('JSON file:', json);
// 8. List directory
console.log('\n📁 Files in home:');
for await (const item of s5.fs.list('home')) {
console.log(` ${item.type}: ${item.name}`);
}
}
quickStart().catch(console.error);
  1. P2P Connection: Your S5 instance connects to peers via WebSocket
  2. Identity: Ed25519 keypair derived from your seed phrase
  3. Portal Registration: Creates authenticated account for uploads
  4. Blob Upload: Files are split into blobs and uploaded to portal
  5. Registry: Metadata stored in distributed registry (like DNS for files)
  6. CBOR Encoding: Directory structures use DAG-CBOR serialization
// Text
await s5.fs.put('home/readme.txt', 'Some text');
// JSON/Objects (automatically encoded as CBOR)
await s5.fs.put('home/config.json', { version: '1.0' });
// Binary data (images, PDFs, etc.)
const imageBlob = new Blob([imageData], { type: 'image/jpeg' });
await s5.fs.put('home/photo.jpg', imageBlob);
// Automatically generate thumbnail
const result = await s5.fs.putImage('home/photos/sunset.jpg', imageBlob, {
generateThumbnail: true,
thumbnailMaxWidth: 200,
thumbnailMaxHeight: 200
});
// Get the thumbnail
const thumbnail = await s5.fs.getThumbnail('home/photos/sunset.jpg');
// Create nested structure
await s5.fs.put('home/projects/app/src/index.ts', 'console.log("hi")');
// List recursively
import { DirectoryWalker } from '@julesl23/s5js';
const walker = new DirectoryWalker(s5.fs);
for await (const item of walker.walk('home/projects', { recursive: true })) {
console.log(item.path);
}
// Delete a file
await s5.fs.delete('home/old-file.txt');
// Delete a directory (recursive)
await s5.fs.delete('home/old-folder');
const content = await s5.fs.get('home/file.txt');
if (content !== undefined) {
console.log('File exists!');
}
const metadata = await s5.fs.getMetadata('home/large-file.mp4');
console.log('Size:', metadata.size);
console.log('CID:', metadata.cid);
let cursor = undefined;
do {
const results = [];
for await (const item of s5.fs.list('home/photos', { limit: 100, cursor })) {
results.push(item);
}
console.log(`Batch: ${results.length} items`);
cursor = results[results.length - 1]?.cursor;
} while (cursor);
  • Check your internet connection
  • Verify the portal URL is correct (https://s5.vup.cx)
  • Ensure you’ve generated/recovered an identity first
  • Ensure you’ve registered on a portal
  • Check portal quota/limits
  • Verify file size is reasonable (<100 MB for beta)
  • Verify the path is correct (case-sensitive)
  • Ensure you’re using the same identity that uploaded the file
  • Check network connectivity to peers

A S5DirectoryLoadError with retryable: true means a directory is known to exist but its content is temporarily unavailable (e.g., a transient 404 while the network propagates). Retry the operation with backoff — don’t treat it as a missing file. See Error Handling.

Check out the demos folder for more examples:

  • Complete tutorial with all features
  • Media processing demos
  • Performance benchmarks
  • Integration tests