An image hosting service on top of the LBRY protocol.
Clone or download
daovist Merge pull request #596 from lbryio/form-submit
allow form submit with enter key
Latest commit 02b8224 Sep 17, 2018
Failed to load latest commit information.
cli updated .gitignore Aug 15, 2018
client allow form submit with enter key Sep 10, 2018
client_custom removed yellow background Aug 13, 2018
config Delete slackConfig.json Aug 20, 2018
devConfig fixed conflicts for merging Apr 17, 2018
public moved components into repo Jul 31, 2018
server fixed embed view path. fixes #597 Sep 12, 2018
test added fullstart and Aug 9, 2018
utils added dynamic aliasing for custom scss folders Aug 13, 2018
.babelrc added babel to transpile SSR jsx Apr 18, 2018
.eslintignore cleaned up errors and updated build scripts Jul 31, 2018
.eslintrc added standard-jsx to eslint and fixed issues Feb 22, 2018
.gitignore Update babel packages to match major, fix dependency issues Sep 2, 2018
.npmignore added under client May 23, 2018
.sequelizerc updated sequelize cli paths via .sequelizerc Jul 26, 2018
LICENSE create initial LICENSE file Feb 5, 2018 updated quickstarts Aug 15, 2018 added customization guide Aug 9, 2018 updated quickstarts Aug 15, 2018
nginx_example_config Update babel packages to match major, fix dependency issues Sep 2, 2018
package-lock.json Update babel packages to match major, fix dependency issues Sep 2, 2018
package.json Update babel packages to match major, fix dependency issues Sep 2, 2018
server.js Update babel packages to match major, fix dependency issues Sep 2, 2018
webpack.config.js Update babel packages to match major, fix dependency issues Sep 2, 2018 is a web app that reads and publishes images and videos to and from the LBRY blockchain. You are encouraged to contribute to the shared code base, or fork it and make it your own.

You can create your own custom version of by installing this code base and then creating your own custom components and styles to override the defaults. (More details / guide on how to do that coming soon.)

Quick start

note: this is the quickstart guide, for an in-depth step-by-step overview visit the fullstart guide.

Install System Dependencies:

Clone this repo

$ git clone

Change directory into your project

$ cd

Install node dependencies

$ npm install

Create the config files using the built in CLI

$ npm run configure

Build & start the app

note: make sure lbry is running in the background before proceeding

$ npm run start

view in browser

customize your app

check out the customization guide to change your app's appearance and components

(optional) add custom components and update the styles

  • create custom components by creating React components in src/views/ (further instructions coming soon)
  • update the css by changing the files in public/assets/css/ (further instructions and refactor coming soon)

(optional) Syncing the full blockchain

  • Start the tool available at billbitt/
  • This is not necessary, but highly reccomended. It will decode the blocks of the LBRY blockchain and add the claims information to your database's tables



method: POST


curl -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg'


  • name (required)
  • file (required) (must be type .mp4, .jpeg, .jpg, .gif, or .png)
  • nsfw (optional)
  • license (optional)
  • title (optional)
  • description (optional)
  • thumbnail url to thumbnail image, for .mp4 uploads only (optional)
  • channelName channel to publish too (optional)
  • channelPassword password for channel to publish too (optional, but required if channelName is provided)


    "success": <bool>,
    "message": <string>,
    "data": {
        "name": <string>,
        "claimId": <string>,
        "url": <string>,
        "showUrl": <string>,
        "serveUrl": <string>,
        "lbryTx": {
            "claim_address": <string>,
            "claim_id": <string>,
            "fee": <number>,
            "nout": <number>,
            "tx": <string>,
            "value": <number>


method: GET




    "success": <bool>,  // `true` if succesfully checked the claim availability
    "data": <bool>, // `true` if claim is available, false if it is not available
    "message": <string> // human readable message of whether claim was available or not



The stack is MySQL, Express.js, Node.js, and React.js. also runs lbrynet on its server, and it uses the lbrynet api to make requests -- such as publish, create_channel, and get -- on the LBRY network. also runs a sync tool, which decodes blocks from the LBRY blockchain as they are mined, and stores the information in mysql. It stores all claims in the Claims table, and all channel claims in the Certificates table.


  • cli/ contains the code for the cli tool. Running the tool will create .json config files and place them in the config/ folder

    • configure.js is the entry point for the cli tool
    • cli/defaults/ holds default config files
    • cli/questions/ holds the questions that the cli tool asks to build the config files
  • client/ contains all of the client code

    • The client side of uses React and Redux
    • client/src/index.js is the entry point for the client side js. It checks for preloaded state, creates the store, and places the <App /> component in the document.
    • client/src/app.js holds the <App /> component, which contains the routes for react-router-dom
    • client/src/ contains all of the JSX code for the app. When the app is built, the content of this folder is transpiled into the client/build/ folder.
      • The Redux code is broken up into actions/ reducers/ and selectors/
      • The React components are broken up into containers/ (components that pull props directly from the Redux store), components/ ('dumb' components), and pages/
      • also uses sagas which are in the sagas/ folders and channels/
    • client/scss/ contains the css for the project *
  • client_custom is a folder which can be used to override the default components in client/

    • The folder structure mimics that of the client/ folder
    • to customize, place your own components ans scss in the client_custom/src/ and client_custom/scss folders.
  • server/ contains all of the server code

    • index.js is the entry point for the server. It creates the express app, requires the routes, syncs the database, and starts the server listening on the PORT designated in the config files.
    • server/routes/ contains all of the routes for the express app
    • server/controllers/ contains all of the controllers for all of the routes
    • server/models/ contains all of the models which the app uses to interact with the MySQL database.
      • uses the sequelize ORM for communicating with the database.
  • tests/ holds the end-to-end tests for this project

    • uses mocha with the chai assertion library
    • unit tests are located inside the project in-line with the files being tested and are designtated with a xxxx.test.js file name


  • This package uses mocha with chai for testing.
  • Before running tests, create a testingConfig.js file in devConfig/ by copying testingConfig.example.js
  • To run tests:
    • To run all tests, including those that require LBC (like publishing), simply run npm test
    • To run only tests that do not require LBC, run npm run test:no-lbc

URL formats has a few types of url formats that return different assets from the LBRY network. Below is a list of all possible urls for the content on


If you find a bug or experience a problem, please report your issue here on github and find us in the lbry discord!

Issue tags in this repo

level 1

Issues that anyone with basic web development can handle; little-to-no experience with the codebase is required.

level 2

Familiarity with web apps is required, but little-to-no familiarity with the lbry daemon is necessary

level 3

Familiarity with the code base and how the lbry daemon functions is required

level 4

Issues with lbry (e.g. the wallet, lbrynet configuration, etc.) that require strong familiarity with the lbry daemon and/or network to fix. Generally these issues are best suited for the lbry protocol team but are reported in this repo because of they are part of the implementation