Skip to content
This repository has been archived by the owner. It is now read-only.

Proposal for `npm tip` #16300

Closed
wants to merge 5 commits into from

Conversation

Projects
None yet
6 participants
@lukem512
Copy link

commented Apr 10, 2017

This proposal arose from a conversation I had with @mathieudutour about how to fund authors of small but valuable open-source projects.

tl;dr: proposal for a way to tip package authors from NPM, request for comments and suggestions.

Motivation

It is very difficult to support yourself whilst contributing to open-source. Typically, maintainers of open-source projects do so in their spare time, with varying degrees of support from the community, whilst working in an unrelated position.

Also, maintaining an open-source project is more than just coding. When you maintain an open-source project of any size there are numerous support tasks to perform: triaging emails and issues, handling pull requests, managing dependencies and, if there are additional contributors on the project, organizing and distributing the workload. This can be extremely time consuming and lead to a feeling of “this is more than I signed up for”.

If you want to work on open-source full time, your options are currently:

  • work for Facebook or another large company with the resources to hire open-source developers
  • find an organization to sponsor you
  • appeal to users of your packages to sponsor you
  • or, as at least one developer has done, quit your job and move to Thailand

Whilst these solutions may work for some people they certainly do not satisfy every case.

What would be nice is a way for open-source developers and package maintainers to receive financial contributions for their work without having to ask for it and for those developers to be able to continue to work in open-source without being restricted by their job or employer.

Problem

The main problem is that it is hard for users of open-source software (developers like you and I, businesses, educational institutes, etc.) to give money to the people that create it. There are some projects in place that try to smooth this problem but they all feel disjointed from a developer's workflow and require extensive setup.

Patreon is a good solution, allowing users to contribute to supported projects by pledging an amount to a project each month. The Patreon model has supported artists and designers successfully, along with several game studios (notably the guys behind Dwarf Fortress). The downside to Patreon is that, due to the full-featured nature of the platform, the pledging process is quite involved.

Another solution that exists is to donate to an awesome organization like Open Collective and let them support open-source projects for you. This works pretty well (and it has certainly helped the likes of mocha and webpack) but it still requires a measure of setup and feels quite 'heavy' for what should be a simple task. There is also the caveat that the project you want to support will not necessarily be featured!

A third possibility is Tip4Commit, a platform that allows one-off Bitcoin payments to be sent to supported projects. Tip4Commit requires less setup that the other platforms (there is no account required, for instance), however, as with the other solutions, it does not easily integrate with the development process and requires additional steps to be taken.

The question remains: how can users of open-source software easily contribute to the packages they use, without additional setup and without interrupting their development flow?

Solution

This pull request extends npm to provide an additional command: tip. Using the tip command, users can send a financial contribution, a tip, to packages they are using and find valuable. The contribution can be sent from the command line, without downloading an additional tool and with very minimal setup!

To tip a package, a user must perform the following steps:

  1. link a Bitcoin account to send tips from using npm connect-tip-account
  2. tip an awesome package using npm tip

The first command, connect-tip-account, accepts a type and the tokens required to access the account API. These tokens are securely stored in the operating system keystore. There is currently only one supported account type: coinbase. Coinbase is a Bitcoin trading platform and a common place to store Bitcoin.

Once an account has been set up, using the second command, tip, will use the account API to send a transaction to the authors of the specified package. For this to happen the package will need to have set the tipAddress property in it’s package.json. The tippable package is available as an example.

The pull request includes help documentation with more information about each command.

Improvements

One improvement that was discussed is the provision of an auto-tipping feature. Auto-tipping would attempt to tip a project whenever npm i is run, using a specified or default amount. By enabling auto-tipping with a small default amount, the user would be supporting the packages they use without having to perform the action each time.

An extension to this would be the ability to set a periodic (daily, weekly or monthly) budget: once the budget has been exceeded the auto-tipper is disabled until the period has elapsed. This would prevent unexpected spending during periods of high-usage. Alternative schemes are conceivable and are discussed in the Questions and answers section, below.

Why is tipping sent using Bitcoin?

Bitcoin lends itself nicely to the problem as it is a digital currency with numerous providers exposing APIs. It is possible for anyone to create a Bitcoin address and begin to send or receive tips, regardless of nationality or locale. A bonus of using Bitcoin is the support of m-of-n addresses: addresses that require multiple keys to sign transactions from the account. This feature could allow packages with multiple authors to collectively manage their tips.

One problem with Bitcoin is that it doesn't handle micro-payments very well: sending a really small amount, such as $0.01, can cost more in fees than the value of the transaction. Coinbase imposes a limit that transaction values must be at least 0.0001 BTC.

It would be nice to implement a truly agnostic tipping system but that was deemed to be beyond the scope of this pull request.

Questions for you

The proposed solution begs many questions and some initial answers have been given here. However, there are lots of unanswered questions and one of the motivations of this pull request is to find some answers to these.

What should happen if a tip is sent a package that has not specified an address?

Currently, nothing. One possibility is that the funds are sent to a 'holding' address and may be redeemed for a number of days by the author. The problem with this is the requirement to maintain such a holding address which, presumably, would need a trusted third-party.

Should it be possible for my employer to pay for my contributions?

This is a motivating question as many employers make extensive use of open-source software and it would be amazing if some opted to use such a scheme to provide some contribution. With the current scheme this is possible by performing the following set-up:

  1. create a single employer account or an account specific to each employee
  2. give each employee unique tokens to access an account (either the single, central account, or their own)
  3. fund the account(s) and encourage employees to tip valued packages

This solution is slightly limited, however, as the employer has no record of what has been installed, nor any assurance that the employee is using the account for work alone. One conceivable scenario is that an employee could be deliberately installing their own packages in order to profit.

Additional development, such as the logging of any tips made and, in the event of the inclusion of auto-tipping, centralised control of budgets, is required for this to work in the wild.

How would you want auto-tipping to handle sub-dependencies?

There are a lot of utility libraries that are used across a large number of packages (e.g. lodash.anything); there are also packages that are extended by other packages (e.g. mongodb is extended by mongoose) and may be infrequently or never installed by themselves. These packages are deserving of support and it would be nice to handle that automatically.

It is important that, in providing users with the ability to easily tip and support the packages they use, that the way packages are created and deployed is not affected.

Consider the following example:

babel and lodash

babel is a commonly-used package, the use of which typically requires several dependencies: babel, babel-core, babel-loader, babel-polyfill, etc. In the naive auto-tip implementation, each of those packages would receive a tip, despite many such packages being written by the same authors to perform the same or similar tasks as a unit.

Another example is lodash: some projects will use the modularized versions of several lodash methods, resulting in a number of dependencies, by a particular set of authors, that are part of a single library or larger package.

There is a danger that unscrupulous package maintainers will divide their packages into multiple components to capitalize upon auto-tipping users. This clearly needs to be mitigated against.

How would you like auto-tipping to split the tips across the budget period?

There are several obvious schemes that each have positive and negative aspects, described below. These schemes could be implemented and chosen at the user's discretion, using configuration settings in .npmrc or perhaps a separate .npmtip file.

First-come, first-served

The simplest solution is to tip, using a specified amount, each time a package is installed. When the budget has run out the auto-tipper is disabled until the next budget period begins. The downside to this scheme is that packages installed at the end of the month are unlikely to ever receive any contribution.

Equal shares

Another simple solution is to log all installations across the budget period and, at the end of the period, equally divide the budget amongst the packages and send the tips. One possible problem here is that a large number of installations may lead to each share being extremely small - potentially too small to be effectively transacted by the Bitcoin network.

Weighted shares

It may be desirable to tip some packages more than others, such as those used in every project (babel may be a good example here, or a framework such as react). This presents a problem, however: how to design a metric that defines this desirability?

One possible metric is the frequency of installs of packages, where packages installed more frequently are ranked higher. This seems like a reasonable suggestion.

Another possible metric is the size of packages, using the assumption that larger packages have taken more work to create and, perhaps, deserve more contribution as such. The size of a package could be easily measured in lines of code or tarball size. This metric has two potential caveats, however: the first is that size does imply quality and the second is that, if such a scheme were adopted, it is conceivable that unscrupulous package authors may simply write longer, more verbose code - a practise surely to be discouraged.

Another suggestion is to use code inspection to determine the number of times a given package was imported, where a oft-imported package is given a larger share of the budget. However, determining the number of imports presents it’s own problems: when should the count be taken, does a first import from one project ‘weigh’ the same as the 100th import from another, etc.

A final consideration is that some users may wish to create a custom weighting - to contribute a larger proportion to certain favorite or small projects. This scheme could feasibly be used with any of the others by including a list of package-specific weightings inside the configuration settings.

Disclosure

I would like to acknowledge that I believe some people will be unhappy with this proposal as it allows open-source to be seen in a more financial light. It is possible that, if such a proposal were accepted, more people would contribute to open-source as a means of work and, in some cases, the focus could shift from altruism (or whatever the current motivation may be) to profit-driven. My own feelings on this matter are not clear but I do feel like the possible benefits are numerous and outweigh the possible negatives.

Never postpone experiments that have clearly defined future benefits for fear of dangers that can't be quantified - James Watson

I would also like to make it known that I am not affiliated with Coinbase, Bitcoin, or any of the projects mentioned. In the past I have worked as a cryptocurrency consultant but, although I maintain an interest in cryptocurrency, I am no longer involved. I have never been affiliated with Coinbase and my only connection to the Bitcoin Project is a correction to one of their tests.

@isaacs isaacs added the review label Apr 10, 2017

@serapath serapath referenced this pull request Apr 10, 2017

Open

npm tip? #10

@lukem512

This comment has been minimized.

Copy link
Author

commented Apr 12, 2017

One criticism I have seen posted is that a malicious user could include a script in their code that automatically tips them (npm tip 1BTC <(echo y), for example). This could be mitigated against by requiring the user to enter their keystore/npm password to confirm the tip.

@catdad

This comment has been minimized.

Copy link

commented Apr 12, 2017

I have two other criticisms to add:

  1. The criticism of the forms of tipping listed here are that they are all too difficult to set up, or requite too many steps. This one is simple, it says, just type one command... provided you already have a Bitcoin wallet set up. But doing that is in and of itself difficult. Further, limiting this functionality to Bitcoin is a huge barrier to entry for most people. Disregarding anything that has to do with merits of Bitcoin itself, it is just not ubiquitous enough for a universal method of payment at this point. I worry that this would prevent the feature from getting any traction as well.

  2. I have not seen an argument as to why this needs to be built into NPM itself. NPM is a package registry, handling the regular package registry business. It is not a payment platform. Why does that concern need to be built into and supported by NPM itself. Why can't it just be a module that you install, e.g. npm i -g npm-tip? Please don't take this as commentary on the merits of financially supporting open-source developers, but what is the argument for this being provided by and supported by NPM itself rather than a community driven package/service?

@lukem512

This comment has been minimized.

Copy link
Author

commented Apr 13, 2017

Hi @catdad and thank you for contributing to the discussion!

  1. Is a valid criticism and one that I've considered. I chose Bitcoin for this PoC as it is a technology that I am familiar with and that could be implemented easily using an existing API. Using Stripe or another card processor might be a more universal solution but certainly one that requires more thinking about - how dos this fit nicely inside a command-line UI, for instance, and is it available to all users of the service? Bitcoin is universally available, which is nice.

  2. I would also like to see some discussion surrounding this. My thoughts are that, by including the tipping functionality in the main package manager, it is pushing the perception that tipping and financial support of open-source should be considered normal and central to the function of the open-source community. I also feel that removing as many barriers to entry as possible will encourage users to tip more readily.

I welcome the opinion of others on both of these points and any other questions. I would like to prompt some discussion surrounding this PR.

@zkat

This comment has been minimized.

Copy link
Contributor

commented Apr 17, 2017

Hey, I'm not gonna make an official response to this right now, but I wanted to drop a note that I noticed it and read it and mentioned it to folks, hence tags.

Thanks for taking the time to think through this, write it up, etc, and it seems like the discussion is pretty civil and thoughtful. Please continue being kind to each other while y'all talk about it, and we'll have a more concrete response once we've had the time to talk it through in the team. :)

Cheers~

@xdamman

This comment has been minimized.

Copy link

commented Apr 27, 2017

Great write up and great to see more people thinking about this. I wanted to reference another conversation on the very same topic that we had a couple of months ago here: opencollective/opencollective#178

I think this is definitely worth trying. Maybe at first as a separate package in user land. We would definitely be more than happy to support this and give an API endpoint to donate to an open collective.

My only concern about tipping is that the amounts are small unless you are the creator of Vue.js or Mastodon. We have seen that problem before with GitTip/Gratipay. The real money is in companies and they need an invoice to get any money out. That's what we are trying to solve with open collective. We wrote about this issue here: https://medium.com/open-collective/a-new-way-to-fund-open-source-projects-91a51b1b7aac?source=linkShare-388996e27d02-1493327243

Never let anyone discourage you. Any experiment is always worth trying. There is always something to learn!

@lukem512

This comment has been minimized.

Copy link
Author

commented Apr 28, 2017

Thanks for the feedback and those [very] interesting links to read. When you say Open Collective will be happy to provide an API endpoint, what exactly did you have in mind?

I'm going to wait for the official response from NPM before going any further with this - although I'm still spending lots of time thinking and having regular conversations about it. We'll be in a better position to know how to proceed once we understand NPM's position.

If you want to chat sometime then you can reach me on Twitter (@LukeCrypto) or via email (hi@lukemitchell.co).

@zkat

This comment has been minimized.

Copy link
Contributor

commented Apr 28, 2017

@lukem512 I don't think there will be a concrete response quite yet. I think this sort of thing needs to spend more time being productized and integrated before it can go in the main CLI. I think my preference, tbh, is for this to be a third-party app, and have it be proven there. Once a third-party package manages to be popular enough, I think that's more a time when it would make sense to integrate this into npm. We tend to be pretty conservative about new commands because once they're in, they're incredibly hard to remove if we figure out we did it wrong.

This isn't a no or a final answer. Based on conversations on Twitter, and in here, I think this really just needs a lot more hashing out, and I'm not sure the current PR is the one we'd want to pick up for this.

I think it's really important to find sustainable models for paying open source people. I, for one, am someone who works full time on open source: I don't write literally any proprietary software in my day-to-day, and my prime directive is to serve the community's needs, not wring them for $. I have a lot of solidarity for this sort of push. I'm very interested in the sorts of things Open Collective are doing. I also think models like Patreon can work well for individual developers.

I'm inclined towards closing this specific issue, though: I'm not comfortable, for example, hardcoding currency values right in the CLI. The CLI is the sort of software that, once in legacy, will remain there for many years. This would be the case with most currencies, but BTC in particular has a history of being so unstable that you need to be fairly up-to-date to have a realistic market value. I remember when 1BTC was barely worth several fractions of a cent. I also remember when 1BTC was worth $1000.

So: I'll give it a while longer because there is some good conversation here, but this is a PR, not a general community planning platform. I will likely close this specific PR in the near future, but I encourage you to continue the conversation either in a feature-request issue, or in other community platforms where even more people with different concerns can join the conversation. I really don't know how something like this can fit into npm right now -- nothing seems quite proven or mature enough to be included by default. Note that many, many tools in the community right now enhance npm pretty smoothly simply as external packages: consider the various test runners, semantic-release, standard-version, npm-check-updates, and more! So I don't feel like I'm being dismissive of great ideas when I say I'm not sure they fit right in the CLI itself.

Cheers!

@lukem512

This comment has been minimized.

Copy link
Author

commented Apr 28, 2017

Thank you for taking the time to respond. I honestly assumed as much - as I've mentioned previously my main drive for making this PR was to encourage conversation and to unpick the problems with my proposal and I didn't really expect it to be supported in this early form.

I'll take a look at the packages you've mentioned and try to come up with something more agnostic and extensible.

I appreciate all the comments regarding this, here and elsewhere, and if anyone has anything to add to the conversation please do so whilst this is still open.

@zkat

This comment has been minimized.

Copy link
Contributor

commented May 18, 2017

well this seems to have been a good stopping point. I'm going to close this PR, as I said before. Thanks again @lukem512 for the thought-out proposal and for getting this conversation started. I look forward to seeing what sort of solutions we can come up with as a community. 🥇

@zkat zkat closed this May 18, 2017

@feross

This comment has been minimized.

Copy link

commented Feb 9, 2018

Hey everyone! I know it's been a while since this issue was opened, but I just discovered it while building thanks. I think it might be interesting to many of the folks in this thread.

thanks is a CLI tool that tells you which of your npm dependencies have authors who are seeking donations. Here's what it looks like in action:

npm-install-thanks

I punted on solving a lot of the hard problems discussed earlier in this issue thread, like payment methods, deciding how much to allocate to each maintainer, etc. The tool is deliberately simple -- it just tells you that a maintainer is asking for donations and directs you to their donation pages where you can read more and decide how much to donate.

I think it's a simple first step. It raises awareness that you may have dependencies looking for donations, but doesn't prescribe how much to donate or whether to donate at all.

We're also considering supporting a new package.json field. Please share your thoughts!

The repo is here if you're interested in collaborating or discussing further: https://github.com/feross/thanks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.