{"id":11064,"library":"hypercore-blob-server","title":"Hypercore Blob Server","description":"hypercore-blob-server provides an HTTP server specifically designed for streaming data (blobs and files) from Hypercore and Hyperdrive instances. It allows applications to expose content from the peer-to-peer Holepunch ecosystem over standard HTTP, making it accessible to traditional web clients or tools. Currently at version 1.12.0, it is an actively developed part of the Holepunch (formerly Dat Project) ecosystem, offering a more flexible successor to 'serve-drive'. The package differentiates itself by tightly integrating with Corestore for data management, supporting partial content delivery via HTTP Range headers, and generating direct links for both raw Hypercore blobs and Hyperdrive files, facilitating interoperability between decentralized data structures and conventional web infrastructure.","status":"active","version":"1.12.0","language":"javascript","source_language":"en","source_url":"https://github.com/holepunchto/hypercore-blob-server","tags":["javascript"],"install":[{"cmd":"npm install hypercore-blob-server","lang":"bash","label":"npm"},{"cmd":"yarn add hypercore-blob-server","lang":"bash","label":"yarn"},{"cmd":"pnpm add hypercore-blob-server","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to manage and persist Hypercore and Hyperdrive instances that the server exposes.","package":"corestore","optional":false}],"imports":[{"note":"The official README example uses CommonJS `require()`. While ESM imports might work in some setups, `require()` is the most robust and documented approach for Node.js environments, especially with older v1.x projects in the Holepunch ecosystem.","wrong":"import BlobServer from 'hypercore-blob-server'","symbol":"BlobServer","correct":"const BlobServer = require('hypercore-blob-server')"},{"note":"For ESM environments, `import BlobServer from 'hypercore-blob-server'` is the correct syntax, as `BlobServer` is typically the default export. Attempting to destructure a CommonJS default export with `const { BlobServer } = require(...)` is a common mistake.","wrong":"const { BlobServer } = require('hypercore-blob-server')","symbol":"BlobServer","correct":"import BlobServer from 'hypercore-blob-server'"},{"note":"When using TypeScript, `BlobServerOptions` can be imported as a type for defining the configuration object passed to the `BlobServer` constructor.","symbol":"BlobServerOptions","correct":"import type { BlobServerOptions } from 'hypercore-blob-server'"}],"quickstart":{"code":"const BlobServer = require('hypercore-blob-server')\nconst Corestore = require('corestore')\nconst Hypercore = require('hypercore')\n\nasync function startServer () {\n  // Initialize a Corestore for data management and persistence\n  const store = new Corestore('./my-hypercore-data')\n  await store.ready()\n\n  // Create a Hypercore instance and append some data to it\n  const core = store.get({ name: 'my-test-feed' })\n  await core.ready()\n  await core.append(Buffer.from('Hello, Hypercore blob server!'))\n\n  // Instantiate the BlobServer with the initialized corestore\n  const server = new BlobServer(store, {\n    port: 49833,\n    host: '127.0.0.1',\n    // For production deployments, consider adding a 'token' for security:\n    // token: process.env.BLOB_SERVER_TOKEN ?? ''\n  })\n\n  // Start the HTTP server to listen for incoming requests\n  await server.listen()\n  const address = server.server.address()\n  console.log(`BlobServer listening on http://${address.address}:${address.port}`)\n\n  // Generate a public URL link to the appended blob data\n  // The 'blob' option requires precise byte offsets and lengths.\n  const link = server.getLink(core.key, {\n    blob: { blockOffset: 0, blockLength: 1, byteOffset: 0, byteLength: 29 },\n    type: 'text/plain'\n  })\n  console.log('Access your Hypercore blob data here:', link)\n\n  // To gracefully stop the server and close the corestore:\n  // await server.suspend()\n  // await store.close()\n}\n\nstartServer().catch(console.error)","lang":"javascript","description":"Demonstrates the full flow of initializing a Corestore, creating a Hypercore, appending data, starting a BlobServer, and generating a shareable link to the content."},"warnings":[{"fix":"Ensure `const store = new Corestore('./path/to/data'); await store.ready()` is called and awaited before passing the `store` instance to `BlobServer`.","message":"The `BlobServer` constructor requires a fully initialized `corestore` instance. Passing an uninitialized or incorrect object will lead to runtime errors when the server attempts to access it.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Configure the `token` option in the `BlobServer` constructor: `new BlobServer(store, { token: process.env.BLOB_SERVER_TOKEN })`. Clients will then need to pass this token in request headers for authorization.","message":"When serving sensitive data, the `token` option should be configured to secure access to the server. Without a token, the server is publicly accessible on its configured port to anyone who knows the URL.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Validate client `Range` header syntax and ensure byte offsets are within the blob's actual bounds. Ensure no spaces or invalid characters are present.","message":"Incorrectly formatted `Range` headers can lead to `416 Range Not Satisfiable` errors or unexpected partial content responses. The format must strictly follow `bytes=<start>-<end>` (e.g., `bytes=0-100` or `bytes=50-`).","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure the `blob` object accurately describes the segment of data within the Hypercore. This often requires careful tracking of data appended to the core, or using library utilities to derive these values.","message":"When generating links for Hypercore blobs, the `blob` option requires a precise `{ blockOffset, blockLength, byteOffset, byteLength }` object. Errors in these values will result in 404s or malformed responses, as the server cannot locate the specified data segment.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Initialize `Corestore` correctly and ensure `await store.ready()` has been called: `const Corestore = require('corestore'); const store = new Corestore('./data-path'); await store.ready();`","cause":"The `store` argument passed to the `BlobServer` constructor is either null/undefined, not an object, or is not a valid and initialized `Corestore` instance.","error":"TypeError: store is not an object or store.ready is not a function"},{"fix":"Change the `port` option in the `BlobServer` constructor to an available port (e.g., `port: 0` to let the OS assign a random available port), or terminate the process currently using the desired port.","cause":"The default port (49833) or the custom port specified in `BlobServer` options is already in use by another process on the system.","error":"Error: listen EADDRINUSE: address already in use :::49833"},{"fix":"Verify that the `key` is correct, the associated Hypercore/Hyperdrive has been opened and contains data, and the `blob` or `filename` parameters precisely match the content intended to be served.","cause":"The `key` for the Hypercore/Hyperdrive or the `blob` ID/`filename` provided in `server.getLink()` does not correspond to existing, accessible data within the `Corestore` being served.","error":"HTTP/1.1 404 Not Found (when attempting to fetch a generated link)"},{"fix":"Adjust the `Range` header to request valid byte ranges within the blob's actual size. Ensure the header format is strictly `bytes=<start>-<end>` (e.g., `Range: bytes=0-500`).","cause":"The `Range` header in the client request specifies byte ranges that are outside the bounds of the available data for the requested blob, or the header format is invalid.","error":"HTTP/1.1 416 Range Not Satisfiable (when fetching with a Range header)"}],"ecosystem":"npm"}