Disrupting Open Source: The Story of Fine Uploader

While it may not be obvious, this photo has a deep connection to my story. It is not a stock photo. It was taken by me, at a time when I was scared and exhausted, but still hopeful and optimistic. The sense of unknown was overpowering, but my instinct told me that the journey was important, and I should continue.

It’s funny (well, maybe not so much funny as surprising) how one single decision, how one email, how a few keypresses can have such a dramatic effect on your life and career. Since 2012, I’ve spent a fair amount of time focusing on one notable JavaScript library. It’s been a rollercoaster ride filled with unusual and interesting challenges. From bringing a dead library back to life, to fighting an avalanche of questions, bugs, and features requests in the middle of the night as the library became more popular than expected, to selling the rights and targeting enterprise users with commercial licensing, to bringing the library back to the free open source software community once again. I’ve been terrified, overwhelmed, inspired, and thankful on multiple occasions throughout this journey. This is the story of that journey, how it changed my life, how it affected those around me and my peers at Widen, and how I hope it can continue to have a positive net effect on the open source community and individual developers.

Over the course of this journey, I’ve changed my perspective on marketing, software development, and open source many times. I’ve made some great decisions that changed my career forever. I’ve made some big mistakes that I remember to this day. I’ve made some lasting connections, and even some enemies. I’m pretty sure I’ve pissed off a fair number of people.

But most of all, I’m pleased to have been able to help develop something useful, something that a lot of developers rely on to accentuate their projects, something that my employer depends on heavily. It’s a bit sad that so many other libraries sit undiscovered and unloved. Their authors have put in countless hours of development and planning. And what do they have to show for these efforts? An issue tracker filled with their own issues. 1 star on the GitHub repository (also their own). It’s frustrating to develop something that is apparently only important to you. I have a number of other projects that fit this description. It’s so very satisfying to develop and be singularly responsible for something that many users depend upon. That itself is an experience that I wish every software developer could have. It broadens your perspective and has a positive effect on all of your future endeavors as a developer.

Maybe the right thing to say is that I wouldn’t change anything. But in reality, there are some things I’ve done, some decisions I’ve made that I wish I could take back. Still, everything I’ve done with Fine Uploader has made me the developer I am today and given me a sense of purpose. I’m grateful for all of these experiences.


What is Fine Uploader, and why should I care?

Frankly, I’m not sure you should care. There are a lot of JavaScript libraries out there. In fact, six more were published in the time it took you to read this sentence. And a file upload library? Can’t you just upload files by submitting a form? Ah, naiveté, thy name is overoptimistic developer. By the time you realize your project should have pulled in a library to handle file uploads, a year has passed, along with dozens of bugs and development hours spent learning the File API, how to “simulate” ajax uploads in older browsers, and wringing your hands as you try to understand the nonsensical AWS signature generation algorithms (among other things).

As with all things, the initial and unenlightened requirement to “accept a file from a user” has morphed into something a bit more tricky. Now you need to display thumbnails for dropped images and scale them to conserve bandwidth on mobile networks. And of course, send them directly to your S3 bucket without hitting the server first. And allow users to drop entire folders. And handle several gigabyte files with a graceful recovery in case of the all-but-guaranteed network error. And it goes on (and on) from there.

Fine Uploader evolved into a solution to all of the above problems (and so many more). It started out simply, but grew into an insatiable beast that gobbled up features as users requested them. I resisted at first, but eventually eager developers depending on Fine Uploader convinced me to reconsider my goal to keep Fine Uploader strictly focused on sending files to a generic endpoint. There is certainly something to be said about developing small focused libraries, and I still believe this is a good overall design goal. One of my regrets with Fine Uploader wasn’t taking on development of features above and beyond sending files to the server, but rather I regret baking these all into a single library, even though the user base has benefitted immensely from some of the more peripheral and unique features.

Fine Uploader is and has been developed to solve a number of highly common and complex workflows, from the enterprise applications handling terabytes of incoming files, to small projects that simply need an easy solution for sending files to an S3 or Azure bucket as efficiently as possible. It has served as more than just another JavaScript library, it’s been a highly sought-after solution by developers, not only for the feature set and attention to detail, but also due to the unusually attentive and timely support that is exceptionally uncommon among software libraries. I’ve taken great pride in being almost always available to answer user questions, whether it be on a weekend, in the middle of the night, or from halfway across the world while recovering from tremendous jet lag.

I know how much it sucks to find a library that seems to solve your problems and fit your requirements almost perfectly, only to discover that this immensely complex library doesn’t seem to work as you expect in a particular situation. Is it a bug, or a feature? And why can’t I get the developer to answer my question, or even respond to my question? What do I do now?! I don’t have time to maintain this myself! I gave this story 2 points under the assumption that this damn thing will do all of the work for me! Yes, I know this all too well. I’ve been there, but haven’t we all? I wanted to offer a different experience for users of Fine Uploader, and to some degree, I’ve maintained this same approach for other projects I’m involved in. Granted, I’m not perfect, and sometimes the stress of following through with this lofty goal has broken me and turned me into a less-than-pleasant person to deal with. It happens. Though some may argue I was broken long before Fine Uploader even existed. But I digress…


The beginning: valums/file-uploader

Back in 2010, Andris Valums created a GitHub repository, valums/file-uploader, to house a JavaScript library with a modest goal: simple cross-browser support for “ajax” file uploads. This small library became fairly popular over time, and even caught the eye of one of my coworkers at Widen in early 2012. We were exploring alternatives to an existing Java applet uploader used in our flagship digital asset management SaaS offering.

Soon after being exposed to valums/file-uploader, I began to replace our aging Java Applet uploader. Dealing with Java in the browser is a nightmare, and we were eager to move to a native JavaScript/HTML solution. I first looked into jQuery File Upload (the most popular upload library at the time), but was put off by the large number of required dependencies needed to get this up and running as well as the lack of cohesive documentation. File-uploader was unique in the respect that it was completely dependency free and very simple to integrate.

However, the plug-in had fallen into disrepair. It was no longer actively maintained, and needed bugs addressed and features tweaked in order to make it production-ready. While the work required was not substantial, it took a significant amount of time me for to address these issues due to the gaps in my knowledge of JavaScript, HTML, and CSS at the time. I pushed some of my changes back up to a forked GitHub repository. My code was sloppy and flawed, but it was sufficient. Some of these changes resulted in my first ever GitHub pull request, issued to a popular fork of file-uploader (which also was apparently abandoned). My efforts were noticed by Valums, who asked if I was interested in maintaining the library. And in August of 2012, I became the sole maintainer of a large and very popular JavaScript library. This turned out to be a pivotal moment in my career, but, at the time, I was completely unaware of the significance of this move.


The start of a side project and the birth of Fine Uploader

In 2012, shortly after I became the official maintainer of valums/file-uploader, Andris floated the idea of changing the name of the library to “Fine Uploader”. His thought was that it was “quite unique in terms of google results”, and he already owned fineuploader.com. While the GitHub repository remained valums/file-uploader for some time, the library was officially known as Fine Uploader from that point on.

Before my involvement in Fine Uploader, the library went though a number of license changes. In 2010, the sole license was GPLv2, a copyleft license popularized by the Linux operating system. In 2011, LGPL was added on, making the library dual-licensed. In 2012, a third license was added to the mix — MIT. Looking back, I’m fairly sure that this license combination included some redundancy, and probably even violated the terms of GPL, making the entire library effectively MIT-only.

During August and September of 2012, I worked hard to merge multiple abandoned forks that contained bugfixes and new features of the library back into the parent valums/file-uploader repository. This work was critical to moving forward with Fine Uploader, and the combined code would become the first ever official version of Fine Uploader — v2.0. I then began developing 3.0 alongside 2.x, in a separate branch. The goal of 3.0 was to clean up the codebase, address some issues with the API, provide an optional jQuery plug-in to wrap the library, and introduce a major new feature — file chunking. The file chunking feature was universally accepted, but there were a number of controversial discussions regarding the jQuery-centric change.

My first inclination, being unwisely anchored to jQuery at the time, was to rewrite the entire library with a hard jQuery dependency. My rationale was that this would make maintenance and evolution of the library a bit more elegant and trouble-free. The community was mostly in favor of this change (I put it to a vote) but there was a very vocal group of dissenters. It occurred to me that it may be shortsighted to throw out one of the more appealing attributes of Fine Uploader — a lack of dependencies. I ultimately compromised and wrote a small wrapper that could be used to address Fine Uploader as a proper jQuery plug-in. This wrapper was completely optional for those using the library, and no features would ever become dependent on it. Still, looking back, it was a mistake to ever do this. I believe the decision was made out of an urge to increase the popularity of the library and capitulate to the blind sense of importance myself and others placed on jQuery at the time. The wrapper added no benefit, and turned out to be a major stumbling block for integrators due to the differences between the conventional jQuery plug-in syntax, and that of the core unwrapped library. This was particularly evident when using jQuery’s custom event system to handle Fine Uploader callbacks.

After I realized the gravity of my mistake, I spent years trying to convince users to simply ignore this wrapper, and I continue this quest today. But this simple and innocent mistake led to a whole new perspective on jQuery. It forced me to question the importance of jQuery in my projects. I ultimately realized that I was using jQuery as a crutch, and other developers could benefit from this insight. What followed was a series of popular articles and even a book on the subject. Without Fine Uploader, perhaps none of this would have ever materialized. Perhaps I would have never grown past jQuery (or at least not as quickly).


Long nights and little sleep

Soon after I released Fine Uploader 2.0, the open source community of developers took notice. Fine Uploader was my side project, something I focused on after work, after my wife and kid went to bed at night. I thought this was sustainable. I was wrong.

Bug reports, feature requests, and questions poured in. I really hadn’t so much as dabbled in open source before Fine Uploader. Instead of testing the waters with a toe or two, I jumped right in. And now countless developers depended on me to answer their questions, to fix bugs for them, to add features to suit their requirements. Most nights, I didn’t go to bed until well after midnight. Often 1am or later, seven days a week. The barrage of questions and requests didn’t let up. I found myself struggling to find time to fix bugs and implement features. So much of my time was spent just sorting through emails and answering support questions. I worked on Fine Uploader later and later into the night.

At some point I added a link to my PayPal account in the project’s README file, hoping that goodwill and fairness would prevail. At that time, I was generating zipped up distributions with minified and non-minified source for each release, made available to users via the project’s GitHub repository. I can’t recall exact numbers, but I remember counting hundreds, perhaps even a thousand downloads per day on the high end, with only about $20 a month in donations to speak of. I was frustrated with this reality. I felt my hard word deserved more than an avalanche of support emails and the occasional nasty comment. But I resisted anything more than a passive donation link, for a while. Anything else felt dirty to me. After all, in the open source world, money shouldn’t really change hands. At least, this was my thinking at the time. I was very much turned off by any sort of marketing and sales tactics. Visions of used-car salesmen filled my head whenever I contemplated monetizing the library. That would change.


Selling open source

In late 2012, I watched a presentation titled “Open Source Ain’t Free” by David Desandro at the Fronteers 2012 conference. It changed my life. I saw open source and software marketing in an entirely different light. Suddenly, I felt “ok” finding new ways to compel Fine Uploader users to compensate me for my time and knowledge. I came up with an idea that allowed me to keep the library open source and the source code publicly available while increasing revenue. Instead of making the combined and minified JavaScript and CSS files easily accessible and unguarded on GitHub, I moved them behind a paywall.

By using an app that emailed copies of the appropriate Fine Uploader release zip file upon payment to my PayPal account, I was able to significantly increase the amount of money coming into the project from users. In fact, the $20 a month quickly turned into $6000 a month. I was shocked. While users were still free to clone the GitHub repository and build the combined and minified files themselves for free, they were clearly much more motivated to pay a fee for the convenience of downloading these files. Payment was now part of the process of obtaining a release.

This new source of income allowed me to continue to justify long hours spent supporting, maintaining, and evolving Fine Uploader, especially with a young family. While I was happy to contribute to the open source community, the money that Fine Uploader was now bringing in made it easier for me to dedicate so much of my free time and energy to this complex project. I didn’t feel bad about making a living off of open source anymore. Collecting from my users felt fair and just, especially since I was only charging $15 per release. But with this new revenue came new responsibilities. My users expected more from me now that they were paying customers. When all of my efforts were gratis, out of the goodness of my heart, it seemed acceptable to punt on feature requests or support emails that simply didn’t seem important to me. When donating your time, your level of responsibility is drastically reduced. But once you accept money, this changes things. Users want to see value. They expect their hard-earned dollars to mean something. At least, this is how I think. As such, my involvement in Fine Uploader became much more intense at this point, and my stress level increased proportionally.


Night becomes day

By February of 2013, Fine Uploader was thriving. In addition to a large userbase, I had implemented a number of sought after and complex features, such as CORS support, file chunking, the ability to resume interrupted files from previous sessions, and folder uploads (to name a few). These were all quite complicated to code, but turned out to be very popular and widely used. Over the course of the next few years, I would build further on some of these features to create new completely unique features that would further set Fine Uploader apart from the rest of the available libraries. At this point, I had determined that Fine Uploader was to be more than just a library that sent files from the browser to the server. It existed to conquer complex problems and fit nicely into common workflows. It wasn’t just a tool anymore, it was a solution.

As the number of users grew along with the library’s revenue, support became a stumbling block. By late January/early February of 2013, I figure about 90% of my time was spent answering emails, GitHub bug and feature reports, and general support requests ranging from simple user error to those that made me question the architecture of the library. At this point, it was common for me to be up until 2 or 3 am, and up again at 6am to continue working on Fine Uploader until I had to leave for work at 7:30. During my lunch hour, I wold take more time to wade through my inbox. Burnout was an eventuality, and every day felt like a battle. I was exhausted and on edge. I wasn’t sure how much longer I could keep this up. I considered abandoning the project to regain my sanity. The money was no longer important, I just wanted my life back. Then, a light appeared, just as I felt everything was going to hell.

Matthew Gonnering, the CEO of Widen (my employer) expressed an interest in bringing Fine Uploader onboard as an official Widen product. This possibility came out of a discussion we had in early February that unexpectedly involved touching on my work with Fine Uploader during off-hours. It seemed like a crazy idea at first, but this sort of unconventional thinking was something I had come to expect from Matthew. It’s one of the many reasons I love working at Widen. Internally, we were already depending on the library in all of our products. Receiving lots of files through the browser was an important part of a heavily used workflow that both Smartimage and Media Collective shared. I was a little more than surprised at the possibility of Fine Uploader becoming a commercial product, but I knew that the future of the library was in jeopardy if I didn’t do something. After little discussion, Andris and I sold the copyright to Widen. We both believed this was the best choice, and with a few signatures, Fine Uploader changed hands once again.

I was ecstatic, and felt a huge burden lifted off of my shoulders. Once again, I could breathe, and the support from my company started almost instantly. A designer was commissioned to develop a new website and logo. An internal team was put together to work on Fine Uploader, and a new developer was hired to help out. With the additional resources, it was once again possible to focus on big new features and provide the same level of top-tier support that Fine Uploader customers had become accustomed to. The new feature lineup included paste to upload, the ability to pause uploads, image validation, thumbnail generation, scaling and uploading scaled images, and perhaps the two most complex and popular features in the history of file upload libraries (if such a category exists): concurrent chunking and direct-to-S3 uploads. My sleepless nights were finally over, and Fine Uploader had a new lease on life as a daytime project.


Making support great again

One of the big changes we made as part of the transfer to Widen was to streamline support. Bugs and features requests always belonged in the project’s GitHub issue tracker. That seemed like an appropriate location. But I had always struggled to find the proper place to field traditional support requests. “What does this error mean?” and “Why doesn’t this custom validation callback properly reject invalid files?” I tried Google Groups, GetSatisfaction, and email. I even allowed these support requests to exist in the GitHub issue tracker for a brief moment. But none of these options seemed sufficient.

GitHub issues didn’t lend itself to community involvement in situations where the issue or question wasn’t entirely Fine Uploader related. Google Groups was (and is) an aging platform that is frustrating to use and devoid of any real value over email. GetSatisfaction was unreliable, awkward to use, and lacked good support for code and syntax highlighting. Only one option turned out to be the proper choice to field these types of questions — Stack Overflow.

In March of 2013, I began directing users to Stack Overflow for non-bug and non-feature related queries. Stack Overflow is great because it has a huge community of dedicated developers who follow the site very closely and are actively involved in advancing its mission and ensuring the community adheres to the rigid rules of the platform. Stack Overflow is challenging to use for casual developers for these reasons as well. It’s quite easy for a newcomer to ask a taboo question on SO, resulting in a barrage of down-votes and an eventual closure of the question. For those not familiar with the strict rules of the community, this is often a source of frustration.

The expectation is that open source projects provide explicit guidance to their userbase before throwing them to the Stack Overflow wolves. I did indeed provide some such guidance, but admittedly I could have done more. There certainly have been a few unfortunate and likely avoidable incidents that have resulted in upset users. For this, I take full responsibility. Still, the site has made it much easier to manage user questions, and most of the users have been able to post on-topic questions and follow the rules of the site without much intervention. Stack Overflow was and continues to be the proper place to field Fine Uploader support questions, and I have always been quick to monitor and answer appropriate user questions on the site. Over the past few years, since Fine Uploader migrated support to SO, other bigger libraries have followed suit, such as React, Internet Explorer, Facebook, Instagram, and Android, among many others.


Finding the right license

Selecting an appropriate license has always been a challenge with Fine Uploader. By February 2013, it had already undergone three license changes. After being acquired by Widen, the GPL/LGPL/MIT/HSWHTMLs license was changed to a strict GPLv3. Why was it GPL v3 vs v2? Because lawyers. I’ll resist the urge to rant about lawyers and continue on with the story.

The first part of this grand experiment involved finding a way to continue to make Fine Uploader self-sufficient. More money was being poured into the library in terms of people and electronic resources (servers, etc). This was 2013, and Widen wasn’t nearly as big and successful as it is now. One goal was, of course, profit. We at least wanted to break even. At least, this was how I saw it. The GPL v3 license didn’t explicitly give us the ability to command payment to use Fine Uploader. Instead, we had a license (GPLv3) as well as a “statement of intent”. In other words, we were being nice. You could use Fine Uploader under the terms of GPLv3 and not pay us a dime. Totally legal. But we would be thrilled if you would pay us a fee if you intend to use Fine Uploader in a profitable commercial setting.

Licensing fees changed a bit over time, but the most common package involved a fee of $99 for a single domain, and $480 for unlimited domains. If you were using Fine Uploader to upload files through one domain, $99/year was expected. But for a SaaS product where a number of domains were involved, the latter plan was the best option. We also grouped installed applications (iOS/Android apps) into this $480 annual plan. Pretty early on, it became clear that the open source community would likely drift away from Fine Uploader and to libraries with more permissive licenses. Indeed, with the resources dedicated to Fine Uploader, our best bet was to target enterprise users. After all, Widen understood enterprise users. We are a typical enterprise user of Fine Uploader. This point-of-view drove a lot of the more lofty features, such as uploading directly to S3 and Azure, along with image scaling and concurrent chunking.

While GPLv3 with a statement of intent technically worked, and enterprises users were certainly purchasing licenses, there was some consternation over the effectiveness of this setup. And it didn’t feel entirely aboveboard. To me, it felt like we were almost tricking users into paying a fee, when they really didn’t have to do so. This was a carryover from the process I put in place when Fine Uploader was my side project — MIT licensed with combined/minified JS conveniently hidden behind a paywall to compel users to pay for my efforts. Let me be clear, the intent was never to “trick” users at any time. We just didn’t know how to properly license this thing. It was one big experiment, a learning experience. We really just wanted to recoup our investment in the library while still maintaining an open source license.

The eventual solution to the licensing conundrum was to abandon the open source GPLv3 license entirely and replace it with a proprietary commercial license, named the “Widen Commercial License”. This was completed in mid-December of 2014. It would not be the last license change, but it did start the longest period of stability in the history of the library, in terms of licenses. The terms of the Widen Commercial License codified our intent — commercial users must pay a fee, but free open source software users may continue to use Fine Uploader for free. This put our minds at ease a bit. At least our expectations were clear. But this was yet another change that further alienated the open source community that built up Fine Uploader for so many years. We neglected our base, and this fact escaped us for far too long.


Free at last!

Over the course of many months, there was much talk about moving Fine Uploader back to a permissive open source license. Widen, like most other software companies, depends heavily on open source software, and we had been looking for ways to give back to the community. After much internal discussion, the decision was made to re-issue Fine Uploader under the exceptionally permissive MIT license. Fine Uploader became 100% free open source software. While I personally championed this change, I had mixed feelings about it. I felt Fine Uploader was more than worth the licensing fee, given the time, effort, and resources put into the library. But giving the library back to the open source community, no strings attached, felt like the right move. It felt like something we had to do. When the deed was done, I was once again delighted. We were good citizens of the FOSS movement at Widen. This was not the beginning of our contributions back to the community, but it certainly was the most notable. This license change opened up a new chapter in the long and storied life of Fine Uploader, one that will hopefully have a profoundly positive impact on the community as a whole.


The future

The MIT license change does not mean that we are giving up on Fine Uploader at Widen. Quite the opposite! Remember, we are heavily dependent on this library ourselves. There are big plans for the library in terms of features. I’m even in the process of developing a sibling library, Modern Uploader, which will target only modern browsers and apply all of the lessons I have learned as the maintainer of Fine Uploader and other JavaScript libraries over the last five years.

It’s quite common for open-source libraries to drift into obsolescence and become abandonware. All of the other popular file upload libraries have already suffered this exact fate by deciding what they have is “good enough”. As the long-time maintainer of the library, I won’t allow this to happen as long as I am involved in the project. Too much work has gone into Fine Uploader, and so much more is left to do. There are many more workflows to accommodate, and so many more tough problems that we have yet to solve. Instead of developing Fine Uploader, Modern Uploader, and all of the other related projects ourselves, we want to get the FOSS community more involved. Fine Uploader really should be a project owned and driven by the community. One of the many remaining challenges is to complete the transition from commercial to free open source by seeking adoption of the library by stakeholders in the community, and I am prepared to put forth whatever effort is necessary to make this a reality.


Being good citizens

I have always felt that this project is a unique one. A trend-setter to some degree. This includes the various experiments involving licensing, support, and monetization. After this long journey, one thing is now clear — I want the free open source software community to be involved in the development of Fine Uploader and Modern Uploader. Libraries like this shouldn’t be developed in a vacuum. Dissenting opinions are important. Alternate points of view are critical. Together, we can all build something amazing, a library that can elegantly address a wide variety of workflows and problems while being flexible without getting in the way and becoming a nuisance. I’m happy to continue to organize the effort and remain one of the primary voices in the development of Fine Uploader, and Widen is happy to continue to sponsor the project and the community to ensure the needed resources are available to make all of this a reality.

But why should Fine Uploader grow? What is left to do other than develop more features and fix more bugs? What is the next step? All of the frustration, the late nights, the endless hours — this can’t all have been just to turn a buck and make it easier to send ones and zeros from a browser to a server. There must be a greater purpose. There must be some other reason why I have made it to this point. I wondered about this on and off for some time, and the ultimate goal of Fine Uploader revealed itself to me very recently.

In addition to sponsoring and helping to maintain groundbreaking open source libraries, I, and the rest of the team at Widen, want to make a profound difference in the open source community. We want to venture off the beaten path and be good citizens. We want to disrupt open source by changing the rules and make it more appealing to new developers, and even experienced developers who have been too shy to venture into the harsh world of pull requests. All the codes of conduct in the world don’t make it easier for the vast majority of developers and aspiring developers to take a leap and make an attempt to contribute to open source. What is really needed isn’t a markdown document with rules that no one reads. Instead, we need a place where developers know they can feel comfortable contributing back to the FOSS movement. We want Fine Uploader, Modern Uploader, and all of the other projects that Widen oversees to be places where this can happen. If you’re a developer who has been apprehensive about being part of open source, please know that we want you to participate, and will do everything we can to make your efforts worthwhile and your next contribution even better.

If you’d like to contribute to Fine Uploader, Modern Uploader, any of the projects in the FineUploader GitHub organization, or even in the Widen organization, please do. Whether it be a fix for a typo, an enhanced README, a bug report, a feature request, a bug fix, code for a new feature, a better logo or website, or even a thoughtful discussion, we’d love to have your help and input, and we hope that the experience can be mutually beneficial. There aren’t enough people willing to give their time to improve and maintain the countless valuable software libraries that we all rely on every day, and we’d like to change that. Please help make open source a more tolerant community where developers are free to give of themselves without fear and anxiety.