$30 off During Our Annual Pro Sale. View Details »

What I learned from WebTorrent

What I learned from WebTorrent

What I learned from WebTorrent: Lessons learned from starting and running a P2P open source project

Presented by Feross Aboukhadijeh in Berlin, Germany at Data Terra Nemo 2019 (https://dtn.is)

WebTorrent:
https://webtorrent.io
https://github.com/webtorrent
https://twitter.com/WebTorrentApp

Feross:
https://feross.org
https://github.com/feross
https://twitter.com/feross

Feross Aboukhadijeh

May 17, 2019
Tweet

More Decks by Feross Aboukhadijeh

Other Decks in Programming

Transcript

  1. WHAT I LEARNED FROM WEBTORRENT:
    LESSONS LEARNED FROM STARTING AND RUNNING A P2P OPEN SOURCE PROJECT

    View Slide

  2. WHAT WE DID RIGHT
    WHAT WE DID WRONG

    View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. LESSON 1
    SHARE YOUR WORK EARLY AND OFTEN

    View Slide

  10. > Late 2013: Announced WebTorrent
    > Early 2014: PeerCDN acquired, got job at Yahoo
    > Mid 2014: Released BitTorrent CLI
    > Late 2014: Works in the browser, end-to-end
    > Early 2015: Quit job
    > Mid 2015: WebTorrent is stable and useful

    View Slide

  11. LESSON 2
    FIND A JOB THAT ALLOWS SIDE PROJECTS

    View Slide

  12. > 2016: Released WebTorrent Desktop
    > 2017: Brave Browser bundles WebTorrent
    > Late 2017: Burnout
    > Early 2018: WebTorrent Desktop hits 1 million downloads

    View Slide

  13. View Slide

  14. WEBTORRENT IN 2019
    > Website: 150,000 page views and 65,000 users per month
    > JS Library: Loaded 5 million times per month
    > Desktop App: 2 million installs, 100,000 monthly users

    View Slide

  15. View Slide

  16. MIT/STANFORD PHILOSOPHY
    > Simplicity: the design must be simple, both in implementation and interface.
    It is more important for the interface to be simple than the implementation.
    > Correctness: the design must be correct in all observable aspects.
    Incorrectness is simply not allowed.
    > Consistency: the design must not be inconsistent. A design is allowed to be
    slightly less simple and less complete to avoid inconsistency.
    Consistency is as important as correctness.
    > Completeness: the design must cover as many important situations as is
    practical. All reasonably expected cases must be covered. Simplicity is
    not allowed to overly reduce completeness.

    View Slide

  17. WORSE-IS-BETTER PHILOSOPHY
    > Simplicity: the design must be simple, both in implementation and interface. It is more important
    for the implementation to be simple than the interface. Simplicity is the most important
    consideration in a design.
    > Correctness: the design must be correct in all observable aspects. It is slightly better to be
    simple than correct.
    > Consistency: the design must not be overly inconsistent. Consistency can be sacrificed for
    simplicity in some cases, but it is better to drop those parts of the design that deal with less
    common circumstances than to introduce either implementational complexity or inconsistency.
    > Completeness: the design must cover as many important situations as is practical. All
    reasonably expected cases should be covered. Completeness can be sacrificed in favor of any
    other quality. In fact, completeness must be sacrificed whenever implementation simplicity is
    jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained;
    especially worthless is consistency of interface.

    View Slide

  18. WORSE-IS-BETTER PHILOSOPHY
    > Simplicity: the design must be simple, both in implementation and interface. It is more important
    for the implementation to be simple than the interface. Simplicity is the most important
    consideration in a design.
    > Correctness: the design must be correct in all observable aspects. It is slightly better to be
    simple than correct.
    > Consistency: the design must not be overly inconsistent. Consistency can be sacrificed for
    simplicity in some cases, but it is better to drop those parts of the design that deal with less
    common circumstances than to introduce either implementational complexity or inconsistency.
    > Completeness: the design must cover as many important situations as is practical. All
    reasonably expected cases should be covered. Completeness can be sacrificed in favor of any
    other quality. In fact, completeness must be sacrificed whenever implementation simplicity is
    jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained;
    especially worthless is consistency of interface.

    View Slide

  19. int fd = open("file.txt", O_WRONLY | O_APPEND);
    write(fd, "hello, world\n", 13);

    View Slide

  20. char buf[] = "hello, world\n";
    int buf_size = sizeof(buf);
    int fd = open("file.txt", O_WRONLY | O_APPEND);
    int bytes_written = 0;
    while (bytes_written < buf_size) {
    bytes_written += write(fd, buf + bytes_written, buf_size - bytes_written);
    }

    View Slide

  21. WEBRTC IS WORSE-IS-BETTER
    > Has performance issues
    > Terrible API
    > Yet, it enabled P2P on today's web
    > proved that the dweb is a valid web use case
    > Makes it easier to argue for better P2P web APIs

    View Slide

  22. LESSON 3
    WORSE IS BETTER

    View Slide

  23. "The lesson to be learned from this is that it is often
    undesirable to go for the right thing first. It is better to
    get half of the right thing available so that it spreads
    like a virus. Once people are hooked on it, take the time
    to improve it to 90% of the right thing."

    View Slide

  24. $ webtorrent --help
    Usage:
    webtorrent [command]
    Example:
    webtorrent download "magnet:..." --vlc
    Commands:
    download Download a torrent
    seed Seed a file or folder
    create Create a .torrent file
    info Show info for a .torrent file or magnet uri
    Specify as one of:
    * magnet uri
    * http url to .torrent file
    * filesystem path to .torrent file
    * info hash (hex string)
    Options:
    --airplay Apple TV
    --chromecast Chromecast

    View Slide

  25. LESSON 4
    PROVIDE VALUE ALONG THE WAY

    View Slide

  26. View Slide

  27. WHO IS YOUR IDEAL USER?

    View Slide

  28. View Slide

  29. const client = new WebTorrent()
    client.add('magnet:...', torrent => {
    // Torrents can contain many files. Let's use the .mp4 file
    const file = torrent.files.find(file => file.name.endsWith('.mp4'))
    // Display the file by adding it to the DOM
    file.appendTo(document.body)
    })

    View Slide

  30. npm install render-media

    View Slide

  31. LESSON 5
    SOLVE ONE USE CASE PERFECTLY

    View Slide

  32. webtorrent_success = js_bet * electron_bet * webrtc_bet

    View Slide

  33. js_bet = .95
    electron_bet = .80
    webrtc_bet = .50
    webtorrent_success = nodejs_bet * electron_bet * webrtc_bet
    console.log(webtorrent_success) // 0.38

    View Slide

  34. LESSON 6
    TECHNICAL BETS ARE MULTIPLICATIVE

    View Slide

  35. View Slide

  36. LESSON 7
    HAVE A SIMPLE PITCH

    View Slide

  37. HTML – THE ORIGINAL WEB API


    View Slide

  38. View Slide

  39. LESSON 8
    DESIGN FOR THE LEAST TECHNICAL USERS

    View Slide

  40. Thanks for the feature request!
    WebTorrent Desktop values simplicity more than most torrent apps. This sometimes
    means saying 'No' to good ideas. We try to implement only the most important
    features that a torrent app needs and make those features as good as possible.
    We don't want the app to get overloaded with knobs and dials that may only
    benefit a small percentage of users.
    That's not to say we won't ever add large new features. We support powerful
    features like instant streaming, dynamic piece prioritization, web peers
    (WebRTC), etc. but only when they have a clear benefit to a vast majority of
    users. See the 80-20 rule.
    I don't think it makes sense to implement this feature right now. I hope this
    makes sense!

    View Slide

  41. View Slide

  42. View Slide

  43. View Slide

  44. View Slide

  45. LESSON 9
    IGNORE THE NERDS

    View Slide

  46. // App version
    telemetry.version = config.APP_VERSION
    // Screen resolution
    telemetry.screens = getScreenInfo()
    // OS version and amount of RAM
    telemetry.system = getSystemInfo()
    // # of torrents currently active, # in list, total size
    telemetry.torrentStats = getTorrentStats(state)

    View Slide

  47. View Slide

  48. View Slide

  49. LESSON 10
    GROWTH MATTERS

    View Slide

  50. View Slide

  51. LESSON 11
    BE PROACTIVE, NOT REACTIVE

    View Slide

  52. View Slide

  53. LESSON 12
    BUILDING DECENTRALIZED SOFTWARE
    WITH CENTRAL COORDINATION IS OKAY

    View Slide

  54. "MECHANICAL SYMPATHY"

    View Slide

  55. View Slide

  56. LESSON 13
    DWEB APPS ARE NOT ROBUST
    ( YET )

    View Slide

  57. !

    View Slide

  58. LESSON 14
    THE OPPORTUNITY IS HUGE

    View Slide

  59. HAPPY HACKING!
    @FEROSS • FEROSS.ORG

    View Slide