Jeremy Kahn's Dev Blog

There's always a method to my madness.

Keeping It Real Boring

I am an incredibly boring and un-trendy programmer. I don’t salivate over the latest Hacker News headlines (I don’t even go there anymore), I don’t curate Twitter lists of industry thought leaders, and I use hardly any bleeding-edge tools. This isn’t to say I don’t care about programming, I am ridiculously passionate and obsessive about what I do. People who know me personally would say this it’s something that defines me. Despite this, my choice of tools and methodology, to some, seem… unusual.

I love (LOVE) Backbone.js, Require.js/AMD, Grunt, and Bower, to name a few. These tools have become something of an in-joke amongst the current web development thought leaders. They’re just so… two years ago. We have such exciting new options now — React, Ember, Angular, Gulp, Webpack — the list goes on. And you know what? They’re all really cool! But I don’t use any of them, and I’m not really interested in switching to them. Why? Because these wonderful and exciting tools solve problems that I do not have.

YAGNI gone wild

When I was still new with programming, I got a great thrill out of constructing fantastically complex systems for doing things. I think that the motivation was something along the lines of “I made a very complex thing. Only smart and impressive people can understand or make complex things, therefore I am smart and impressive.” Thankfully, a few years of experience has extinguished this haphazard naïvety, but a lot of programmers start out this way. Experience has made me older, somewhat wiser, and much, much lazier. What was the big change between then and now? Instead of academic projects to complete for a grade, I have a job where I am depended on to get things done, and I don’t want to screw around with needless and avoidable complexity. Luckily, I developed a sense for differentiating between problems that are trendy and fashionable, and problems that I actually have. For the projects that I work on, there is very little overlap between the two.

I build software with lots of users. A large portion of my user base is not 20-something techies. Instead, it’s Normal People. Normal People use old and terrible browsers, and the code I write has to work properly for them. Hopefully this a problem you have as well, because that means you are making a product with a diverse userbase. The exciting new tools that I listed above won’t really impact my ability to write code that works for Normal People.

What I really want out my tools is reliability and simplicity. I want a proven track record. My unfashionable utility belt of Backbone and AMD has yet to let me down on any project, and I’m as happy with it now as I was two years ago. Does React and Browserify work well for you? Awesome, then you should use those! You probably have different problems than I. Alternatively, you may just have a different perspective on solving the same problems as I, and that’s good too. Diversity is a good thing in technology.

Tech is not a zero sum game

One of the most bizarre quirks about the tech industry is the idea of tools and ideas “winning.” Many developers want their favorite tools to win. A mindset has developed where many developers want the tools that they don’t like to lose so that their favorites can win. I don’t know where this oppositional mindset came from, but it’s silly, immature, and it’s really wasting a lot of time. This town is big enough the two of us. I use Backbone, and you might use Ember, but we can still be friends.

If it fits, I sits

If Backbone is as effective a tool for me in 20 years as it is now, I will be using it. If I outgrow it, I’ll switch to something else or just roll my own (probably the latter, but that’s just how I am). But I will not drop a tool simply because it isn’t cool anymore. Engineering isn’t about fashionability to me, it’s about pragmatically solving problems. I feel that less is more and tools that work well should be used. This means something different to everyone, and that is awesome. Use the tools that make you happy and productive.

Open Source Does Not Mean Free Labor

Everyone loves to get something for free. It’s just human. Additionally, people have a tendency to maximize the return on an investment as much as possible. When something appears to require no tangible resources from a consumer to produce, said consumer will try to get as much of the potential benefit as they can. Once a limit to the return on free investment is established, or a cost to obtaining the benefit is imposed, reasonable people will respect the rules of the transaction and either pay up or opt out of the transaction altogether.

None of this is new, it’s as old as currency itself. Open source is a relatively new concept, and is often misunderstood in a variety of ways. A common misconception is that open source is equivalent to free labor, that users are entitled to having feature requests implemented, and that open source developers owe them something. Essentially, open source has bred a new form of entitlement.

Open source is not same as free software

First, let’s clear up the most common misconception: “open source” is not a synonym for “free software.” Open source means that a software project is developed openly. Generally, this means that people who have a license to use a piece of software also have access to the source code. That typically means, at minimum, software license holders are free to modify the source code for their own means. Many open source licenses also entitle license holders to redistribute the source code, modified or unmodified, but this is not strictly required.

Free software, in the FSF sense of the term, refers to the rights of the users of the software. It’s “free” as in “freedom.” I suggest reading about the four freedoms on the FSF’s website for a more detailed explanation. Monetary price is orthogonal to the concept of free software. The only real problem with this is the confusion resulting from the terminology; it’s not immediately clear that free software can cost money. This immediately calls into question how anyone can make money with free software, but that is outside the scope of this blog post.

In any case, neither open source nor free software means anything with regards to the monetary value of software or obtaining a license for it. The former term describes a development model, and latter is a philosophy. The confusion behind both of these terms is primarily exacerbated by fact that the majority of both free and open source software is distributed at no cost. But, nobody is really complaining about that.

Why people work for free

Considering how much good free and open source software is available, it’s reasonable to wonder why so many talented developers would work for free. This is a question with many answers that vary from developer to developer. Personally, I create open source software for fun, to learn, and as a form of civic duty. Others have different motivations. Believe it or not, giving software away for free can be a key business strategy (again, the “how” of this is outside the scope of this blog post).

No matter how or why a person might spend their time developing software, it is challenging and takes time. Code that has no monetary cost is as hard and time-consuming to produce as code that costs millions of dollars. Additionally, maintaining and managing code requires the same mental and temporal resources regardless of how much money is made by the software or how much it is sold for. This is not immediately clear to end users. After all, when something is done well, it appears to have been done effortlessly.

In addition to the challenge of writing code in the first place, bug fixes and feature requests take time and effort. When you are paying for a license for software, or there is some form of an SLA, it is reasonable to expect a certain level of reciprocity and response time for bugs and feature requests filed against a project. That level of service is not necessarily appropriate to expect from software projects for which a developer has no stated or contractual obligation to provide. This is the case for many free and open source projects; you are using the software at your own risk. This is clearly stated in just about every open source license.

That being said, open source developers do not owe you a feature when you request it. They are not obligated to fix a bug, no matter how trivial or severe it may be. Especially for hobbyists like myself, free and open source software is created, maintained, and distributed based on goodwill. The open source development model empowers you as a user to make fixes and implement new features yourself. This is why open source software is better than closed source software. With open source software, you are free to solve your problems instead of artificially being limited to the whims of the developer. If the developer isn’t available to or interested in adding a feature you need, you are free to do it yourself. It’s comparable to the wiki model: Anyone can make changes. If you see an error or want to add or change content, you can do so yourself, rather than depend on the author or maintainer. This is critical for businesses that have deadlines.

Being a good open source citizen

Just because open source developers are not obligated to do much of anything to help you out doesn’t mean that they shouldn’t. Part of participating in a healthy community means that you help your neighbor when you can. Particularly with bug reports, developers should respond to and address issues quickly, clearly, and effectively. It’s not a matter of being professional, it’s a matter of being a decent human being. Feature requests are a little different, since what a user may want from a project may not be consistent with what the developer wants. Or, as is often the case with my own projects, a user wants a feature that I don’t have any interest in, therefore I have little motivation to implement it. In those cases, I do my best to provide a workaround. Additionally, assuming that the proposed feature does not negatively impact the project, I also invite the user to submit a Pull Request implementing the feature if they are willing to put in the time to do it themselves.

I take the idea of “Pull Requests welcome” seriously. It’s not a cop-out, it’s an invitation for users to contribute patches and improvements they need that I don’t. I want what’s best for my projects, but I don’t have time to build features for strangers on the internet that I don’t have sufficient domain knowledge or personal interest in. However, if someone is willing to contribute code, I will bend over backwards to review their code and get it merged in expediently and effectively. I feel that I owe them that much as a member of the developer community, not as a project maintainer.

Again, it’s similar to the wiki model. The beauty of it is that anyone can improve the product, and people who would prefer to stew about a project not meeting their needs only have themselves to blame. Open source projects belong to the entire community, not an individual or group. Open source projects are different from wikis in that there is a maintainer (or a group of maintainers) with ultimate power to accept or reject contributions. But, as they say, with great power comes great responsibility.

Open source is about building better software, faster

Open source is better because it empowers the developer community. If you don’t like how a developer manages a project, you have to power to fork and take the project in another direction. If the original maintainer is cooperative and willing to work with you and merge your changes into their fork, awesome. If not, then you are still able to make progress. As a user of software that you didn’t pay for, it’s important to recognize that open source developers have limited resources to implement features that are not relevant to them personally. Open source is not charity work. Open source is a software development model that enables the community to build what one person cannot.

Stop Animating With Code

When I first saw Bret Victor’s Inventing on Principle talk in 2012, it left a lasting impression on me. Throughout the nearly hour-long presentation, I found myself nodding in agreement with all of his ideas. The notion that a creator should have a seamless feedback loop during the experimental phase of making an animation, game, or any other digital creative work made total sense to me. He articulated what I wanted to do with my own projects better than I could ever do.

It was around this time that I started development on Stylie, a CSS animation tool that aims to put a number of Bret’s concepts into practice. My dream is to build an animation tool that isn’t painful to use, one that fosters experimentation and, ultimately, produces an end result. I feel that Stylie has gone a long way towards achieving this, and there’s still lots more to come. I have personally learned a lot from Stylie. Not just from an application development or programming perspective, but also as a user of the tool. Direct manipulation of whatever you are trying to build is far more effective than indirect manipulation, and Stylie enables direct manipulation for animations in a way that few other tools do. At the very least, I want to show that there is a better way to create animations than the way web developers traditionally do it.

Programming an animation is like using poetry to paint

The problem with using code to create animations is that you are describing what you want an animation to do. You can go to great lengths to articulate the various intricacies of how an animation behaves, but ultimately the input (code) is very far removed from the output (how it looks and feels). Effective animating requires this gap to be as narrow as possible in order to make the tweaking process manageable. Animation requires lots of tweaking to get it just right. This is clear to anyone that has made an animation that is anything more than a simple transition. While it is entirely possible to make a beautiful animation with code alone, the tweak-test-tweak cycle is painful and time consuming. Text is just not optimized for visualizing natural motion curves and timing. It isn’t the right tool for the job.

Specialized tasks call for specialized tools. Thankfully, there are a myriad of tools available for animating content on the web. When Flash ruled the web, the Flash authoring environment was the de facto standard tool for animation. So far, the HTML5 community has failed to settle on such a tool. Here are a few of the options:

These are some of the industrial-strength tools. There are also simpler options of all shapes and sizes all over the web, but developers and designers are largely left to just figure out a tool set and workflow on their own. These larger tools offer a lot of power, but also create a barrier to entry. Being a do-everything tool for animation tends to invite a lot of complexity, which makes it hard for newcomers, but also for experienced users who just want to quickly create something simple. The tools to do anything you can imagine are there, but they don’t feel natural or intuitive, in my opinion. Good animations feel natural, and so should the tools that create them. In my time playing with the myriad of “kitchen sink” tools out there, making an animation never felt natural. Rigging up and tweaking an animation should be as intuitive as using a paintbrush on a canvas.

Stylie is my attempt at making a natural-feeling animation paintbrush. It isn’t perfect, nor is it the solution to all animation challenges, but it is way more enjoyable to use than everything else currently available. Code is very clearly one of the worst ways to animate something and we need to move away from that workflow. I hope to see more animation tools that forgo established UI paradigms, because none of them take into account the revolutionary concepts put forth by Bret Victor’s landmark presentation. Additionally, I hope to see more open source animation tools so that they remain accessible to everyone. It’s time to rethink how we approach digital animation.

Of Engineers and Entrepreneurs

There’s a lot of people in the tech industry that I respect and use as role models for my own career. One thing I’ve noticed among all of them is that they tend to be engineers or entrepreneurs. For some time, I saw these two types of people as being completely detached from each other. To me, engineers were the creative people who built products and entrepreneurs were the socially savvy people who sold those products. I did not see the skill sets of these two groups to be complementary. However, after a few years of industry experience, I see successful entrepreneurs and engineers as being almost the same thing. In fact, their only distinguishing characteristics are the specific skills set that were acquired through focused training.

It’s all about solving problems

To be a strong contributor to any organization, you only have to do one thing: Provide value. How you do this entirely depends on your role within that organization — some people just need to be available to do a menial or repetitive task, while others provide more specialized services. In any case, it takes all kinds. Something that good engineers and entrepreneurs both do is solve problems. That’s actually all it takes. Engineers solve technical problems, whereas entrepreneurs solve people and global problems. I think pigeonholing entrepreneurs as business people and engineers as technicians is far too simplistic a way to look at things.

Another common trait of any good entrepreneur or engineer is proactiveness. A-players don’t wait for problems to fall into their lap. A good engineer is always seeking out a bug to fix or an algorithm to optimize. Likewise, a good entrepreneur is always looking for the next service or product to fulfill a market need, and a strategy to provide it. Good entrepreneurs and engineers are also effective leaders; they seek out deficiencies within an organization and solve them. Top performers are not reactive.

People first

The entrepreneurs I respect the most put people before profits. After all, it’s the people that define a company and make it tick; money is just what keeps the lights on and sustains the business. I feel that very few companies actually understand and operate by this concept.

The best engineers write code to be read by other engineers, and they do so in the pursuit of making a purposeful product. After all, what’s the point of writing code that doesn’t do something useful for another person, or isn’t maintainable? One of the biggest rookie mistakes that a programmer can make is to focus too much on code. Code is more superficial to engineering than you might think; it’s the means to an end for the higher purpose of making something that is useful to other people.

Empathy and pragmatism

Empathy are pragmatism are the most important traits of any good entrepreneur or engineer. Engineers need to do this on both a technical and human level. Being able to think like a computer is invaluable for solving bugs and writing efficient code, but being able to think like another person is necessary for building a system that can be maintained for years. In fact, an engineer’s empathy is a direct result of pragmatism; it’s impractical to write slow or unmaintainable code.

Entrepreneurs don’t have to worry about the technical side of things as much, but they have even more to consider on the human side of things. Simply put, you can only sell what people are willing to buy. To know what people are willing to buy, you need to understand what problems they have that you can solve. To do any of this in a sustainable manner, you need to play the long game — scale at a manageable pace, hire only the right people and focus only on the products and services that actually matter to the success of the business.

We’re not that different, you and I

I don’t consider myself an entrepreneur. I’m not business savvy, and I’m allergic to meetings. I’m an engineer, and I hope that I always will be. However, I’ve come to find that having an entrepreneurial spirit has benefited me tremendously as an engineer. Learning what makes respectable entrepreneurs tick and emulating that in the context of a development team has helped me focus on solving the right problems the right way. I’ve been fortunate to learn from some of the best engineers and entrepreneurs in the industry. No matter where you fit within an organization, you need to stand on the shoulders of giants in order to truly make an impact.

The Fear of 1.0.0

Lately I’ve been working to bring some of my JavaScript libraries to version 1.0.0. This is an important step in the life of an open source project. According to Semver, 1.0.0 defines the public API and therefore communicates to users that the project is stable. Additionally, it states that the API will not change in an incompatible way until version 2.0.0. And from 2.0.0, the API will not change until 3.0.0, and so on.

Semver is a logical and straightforward versioning specification designed to prevent “dependency hell.” The good news is that many projects do adhere to Semver, or at least something pretty close to it. While being generally beneficial, it inadvertently creates a new problem: Developers are hesitant to increment their projects to 1.0.0 and stay in 0.x.x for a very long time, and possibly forever. Many open source projects languish in the 0.x.x state because the developer lost interest and stopped working on it. This stifles community adoption because it means that a stable public API was never defined.

Commitment issues

Why do so many projects fail to reach 1.0.0? According to rule 4 of the Semver spec:

Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.

This means that the developer isn’t obligated to follow any rules with regard to the changes they make to a codebase. They are free to add, remove and completely change functionality with breathless enthusiasm. As a developer, I can tell you that this is quite a bit of fun. 0.x.x allows you to experiment and try new ideas. Once you hit 1.0.0, though, the fun is over and you need to follow the rules (of Semver). All changes must be carefully considered, justified and documented. Any incompatible API changes require a major version bump, which increases the potential for user base fragmentation. Version 1.0.0 is where a project grows up and discovery and experimentation tend to subside. It’s not hard to see the appeal of staying in 0.x.x forever.

What, then, is the drawback of 0.x.x? It means that a project cannot be trusted. It would be unwise for a business-critical application to have a dependency that is young and prone to significant changes at any time. It also indicates that the dependency project simply isn’t done and might not be ready for use. Part of getting people to use your work is getting them to trust you as a developer, and the version number plays a part in gaining that trust.

When to move to 1.0.0

Knowing when a project is ready for its first stable release is difficult and depends on the project. Small projects may be worth stabilizing after a few iterations, and larger projects may take a few years. Backbone.js, for example, took about 2.5 years. My own project, Shifty, took about that long as well.

Determining when a project should be considered stable isn’t a matter of time, it’s a matter of maturity. Most projects eventually reach a point where significant changes become less frequent and the development direction becomes more clear. If not, that might be a sign that the project needs a clearer focus. In any case, it’s the point where the code becomes less volatile that 1.0.0 should be considered. However, tagging the 1.0.0 release too early is even more harmful than waiting too long.

One way to guage when a project is stable is by monitoring how others use your code. If you’re lucky, users will tweet or email you questions about your project, or blog posts will be written about it. More likely, you’ll have to find alternative approaches to learning how others use your work. In my case, I do Github code searches for projects that use my libraries. It’s not glamorous, but it gives me insight into how my projects get used in practice and how I can tailor my APIs to suit real users’ needs.

A case study: Kapi

Kapi is an older JavaScript animation library I wrote. Kapi was the precursor to Rekapi (“Rekapi” is short for “Rewritten Kapi”). I was committed to getting Kapi to 1.0.0 and worked feverishly to build the feature set that I had envisioned for that release. After a few months, I finally got it to that point and released 1.0.0. I was still working on Kapi quite a bit at that time and wanted to keep adding features. However, it became apparent that adding the features that I wanted to would involve changing the API in incompatible ways, necessitating rapid major version bumps (2.0.0, 3.0.0, etc.). I realized that I had made a mistake by releasing 1.0.0 too early, but it was too late to go back.

My biggest failure with Kapi is that I didn’t wait for real user feedback. I built what seemed like an ideal design in my head, but it was never validated by actual users.

I ended up scrapping Kapi and went on to build Rekapi, which is designed to provide similar functionality to Kapi, but with a better development process. Currently, after over two years in development, Rekapi is still 0.x.x (though I will be focusing on wrapping up the 1.0.0 release in the near future).

Misconceptions about 1.0.0

For me, a 1.0.0 release has some unnecessary baggage associated with it. I tend to associate 1.0.0 with a finished project, including tests, documentation, a nice landing page, and a lot of sample code. While all of that is certainly important in its own right, these extra components of a project actually have nothing to do with the version number. The version number is a reference to the state of the API, not the state of the project. Semver doesn’t state any requirements for the quality of the documentation, it simply requires that it exists. It also doesn’t have any rules for tests, sample code, demos, a logo, IRC channel availability, or any other nice-to-haves that open source projects often provide. 1.0.0 is just a statement about the stability of the API — you are free to put off creating the extra content until whenever you get around to doing it.

This isn’t to say you shouldn’t writes tests and tutorials, they are invaluable for guiding your API decisions. Just don’t let that be what prevents your 1.0.0 release from ever happening.

Importantly, it is completely reasonable to increment the major version number. Emacs is currently at version 24, and Chrome is in the 30’s. You are allowed to make public API changes after 1.0.0, just do it judiciously and adhere to the rules of Semver.

Don’t forget to ship

With all things in software development, shipping is key. In open source, tagging the 1.0.0 release is comparable to shipping a final product. It’s natural to want to iterate on something endlessly, working towards that state of perfection that’s just out of reach. But every so often, we as developers need to take a step back and consider if what we have in front of us is as good as it needs to be. If it is, then it’s time for 1.0.0.

Software and Amplification

Programmers exist to automate work. This isn’t a new idea, but it took me a while to understand this simple concept. Programming with automation in mind has subtly caused me to make smarter, clearer decisions when designing a solution. This idea of automation has also helped me make better UX decisions. Even as a strictly non-designing developer, I have to do some degree of UX design in my work — sometimes a mockup takes a UX detail for granted, or I’m just working on a personal project without the help of a designer. In any case, keeping my automation imperative in mind has resulted in more effective results.

It’s extraordinarily useful to have a guiding motivation or philosophy. This is the single most valuable lesson I’ve learned from Bret Victor. I realized recently that, as a software developer, I have the potential to not just automate work with machines, but to amplify my efforts though other people.

Amplification, in a general sense, means to take a signal and increase its strength. Lots of tools allow us to amplify ourselves. Amplifiers in the context of music create a greater sound signal, but this is just a literal way of interpreting the concept. The printing press allowed Johannes Gutenberg to amplify the message of the bible in the 1400s, and radio amplified the reach of popular music in the 1900s. In either case, technology amplified a message in such a way that many more people were able to receive it than was previously possible. To me, the amplification potential of the web is what makes it the most interesting technology in human history.

There is more to amplify than ideas, though. Software, thanks to trivially easy digital reproduction, allows us to amplify processes. If I find a solution to weird CSS bug, I can make a Github Gist and share it with the world about as quickly as I can type it. If my solution becomes ubiquitously known, nobody ever has to spend the time to solve that problem ever again. This is why you don’t ever have to worry about CSS resets. A software solution can be reused an infinite number of times. As a mortal, I think that’s pretty cool.

While this is all nice and idealistic, things get a little more complicated when you consider that quality is amplified as well. High-quality software solutions can make the world a much better place. Linux, Firefox, and jQuery come to mind. These projects aren’t perfect, but their positive impact on how the world works is undeniable. On the other hand, low-quality solutions can create significant problems that last for decades.

At Jellyvision, I build JavaScript frameworks all day. This is a dream job for me, but it’s also a huge responsibility. I develop tools that the rest of my team depends on to work and be effective. If I do a good job, everybody is happy and productive. I do a poor job, everyone is slowed down and my code is quickly considered “legacy software.” Because of this, I work very carefully. I spend as much time writing documentation as I do code. I iterate on my ideas and don’t ever consider something “done.” I also make sure to share my work frequently and get feedback from the people who will be depending on my code. This works out nicely, as it doesn’t just result in better work, it makes my job easier and more enjoyable by providing clarification and direction.

If you build tools, you are amplifying your solutions through others. Lots of people using a high-quality tool results in high-quality collective output, but the inverse is also true. There’s a growing sentiment in the software world of ”just ship it.” Shipping is important, but it must not preclude quality. The code you write may be used by millions or even billions of people, and it may happen faster than you think. When you consider how much collective human time your work may cost or save, it isn’t unreasonable to take a breath, reconsider your ideas, and get the job done right the first time. I’m not advocating that we all spend an inordinate amount of time tweaking and perfecting. With all things, balance is key. Ship, but don’t ship shit. And remember that finding out who introduced a bug or made an ill-considered design decision is just a git blame away.

Creating CSS Animations With Just Your Mouse

Animation is an inherently visual art, and I believe that there need to be visual tools to assist us in creating them. Not unlike Bret Victor, I think that the gap between the input and the output of the creative process should be minimal, and iteration should be painless. I’m also incredibly lazy and believe that making animations (or anything, for that matter) should be quick and easy. I develop an app called Stylie in my free time, a tool that tries to satisfy these ideals. Among other things, Stylie lets me stretch my creative legs with regard to UI/UX design. I’m not a designer by any means, but I can generally identify UI elements that obviously do or don’t work.

All of the UI decisions I make with Stylie are deliberate and carefully considered. I like the current UI, and I’m careful about cluttering it up with unnecessary or awkward features. In other words, I don’t want it to become The Homer. At the same time, I want to automate as much of the process of scaffolding an animation as I can, because I use Stylie quite a bit and get annoyed with repeating certain actions over and over again. Ironically for an adamant Vim user, I’ve found that using my mouse to work with the UI is far easier than using the keyboard to tweak an animation, so I’ve worked to optimize that workflow. In doing so, I inadvertently developed a way to develop complex CSS animations without using the keyboard at all.

My Stylie workflow

While Stylie is a web app and will work on any modern browser on any desktop platform, I develop it on OS X. Therefore, Stylie has an even more optimized mousing experience on late-model Apple laptops and desktops with a Magic Trackpad. If you are on OS X, you can enable three-finger dragging:

This feels weird at first, but once you get used to it, you’ll have no idea how you got by without it. It makes the overall dragging experience feel more natural and gestural. When using it to select blocks of text, it feels like you are “drawing” around the text you want. Happily, three-finger drag works perfectly with Dragon, the jQuery dragging plugin that powers Stylie. It’s not magic, three-finger drag just invisibly inputs the initial click that would initiate a drag motion. This makes any interface that requires lots of cursor dragging much more elegant, so I highly recommended enabling the feature.

The first thing I’ll do is create however many keyframes I’ll need (by clicking the “+” button in the upper right of the Keyframes panel or hitting “K” on the keyboard) and drag them around with three fingers. However, the positioning of the points often needs some finessing, so I’ll usually have to tweak the corresponding values in the Keyframe panel. There are several ways to interact with Stylie’s number fields, all of which are designed to be similar to Chrome Dev Tools:

  • Re-type the value
  • Hit “up” or “down” on the keyboard to tweak the values
  • Hover the text input with the mouse and scroll up or down to tweak the values

The last method is the most useful for me, as it’s both quicker and more fun than switching to the keyboard to change the values. Personally, I wish I could scroll the mouse to increment any number input on the web, so I built it into Stylie.

So, rather than clicking around and re-focusing the various number fields (which there are a lot of), I’ll just hover my mouse and “scroll” the values. This feels like a much more efficient and natural way to tweak numbers, to me. This is particularly useful when modifying rotation values (RX, RY, and RZ for each keyframe).

Next, I’ll tweak the easing formulas. Stylie supports all of the “classic” Robert Penner formulas, but you can also create your own with the curve tool.

To use a custom easing curve, just link it on a per-property basis in the Keyframes panel. The drag handles on the easing tool work the same as the keyframe crosshairs, so you can three-finger drag those as well, or just scroll the number fields.

A lot of animations also call for some kind of rotation. While you can achieve full three-axis rotation by tweaking the keyframe number fields as I explained earlier, it’s easier to hold the Shift key on the keyboard (I know, I’m going against the title of this post) to bring up the rotation Cubelets. You can just click and drag (or three-finger drag!) the Cubelets until they face the way you want for the various points in the animation.

Once I’m done with tweaking an animation, I’ll grab the generated code from the CSS panel and I’m done. With this workflow, I’ve found that using Stylie is a fluid and somewhat gestural way to quickly create and tweak an animation. Rapid prototyping and iteration is a key component of making animations that work well within a game or application, and I hope to keep developing Stylie to explore what other methods are effective for simplifying what is normally a pretty painful process.

Open Source and Respect for the User

As I’ve noted in the past, open source is as much of a moral issue for me as it is anything else. I feel morally obligated to write and distribute open source code. I’m a bit of an idealist, but I also realize that this principle can be at odds with modes of business, and, by extension, basic survival.

You need money to survive in this world. Freely distributing software is generally not directly profitable, but it is possible to profit from it by offering support and other services around the free software. This isn’t a silver bullet, though. Not every developer wants to provide services for a living, as it may not fit well with their skill set, interests, or other constraints. For instance, an open source developer might not feel comfortable directly working with or for others, and instead prefer to focus on product development or other solitary means of income. There needs to be another way of making money with open source software, one that is not at odds with respecting the freedoms of users and sharing useful tools with the community.

Let’s say that I want make my living by starting and running a website. For argument’s sake, let’s say I’m building a social network for coffee shop enthusiasts (yes, I am writing this in a coffee shop). To make this website, I need a server and a UI. I own and control the server, but the UI code runs in users’ browsers. It wouldn’t make much business sense to freely distribute all of the code I write, as I would be giving away any competitive edge I might make for myself. At the same time, I don’t want to opaquely control users’ machines without making it clear what my code does. In other words, users should have free access to the source code of the HTML/CSS/JavaScript that they are downloading and running in order to use the website I’ve built.

I feel that a reasonable compromise in this situation is to share the UI code, but not the server code. Computer users have the right to know everything that their machine is doing. It’s their property, it should not be made arbitrarily mysterious to them. While most users are not technical enough to understand what a piece of software is doing and will probably never care, there should never be a limitation that prevents them from doing so. However, users do not control or own the server of a web service. I do not feel as obligated to share that code with them. It would certainly be nice to do so, and in some cases it is feasible, but sharing remote server code (in this example) would jeopardize my income and livelihood.

Free software, as defined by the FSF, feels ideologically pure to me. I want to live in that world. But we live in a world where competitive edge matters, and giving away the entirety of your product is not a viable business model in a lot of cases. A more realistic compromise is to open source the code that a users’ machine will execute, but not the code that runs on a remote server that a service provider controls.

A potential gray area with this approach is service provider trust. If I as a user can’t see what the developer’s server is doing, then my data is at risk of being used in ways that I do not consent to. While there is no failsafe way to guard against this, it is the responsibility of a service provider to provide a Terms of Service document explaining what they will and will not do with users’ data. It is the responsibility of a user to read and agree to that document before using the service. Users should always be able to opt-out of a service if they don’t feel that it provides what they want, or if using it is not in their best interest.

As a programmer who loves what he does, I want to share as much code as I can. I also don’t want to starve. Dogmatically adhering to the principles of all-open or all-closed software is divisive and bad for the software development ecosystem. I think there is a better way to develop software that respects the interests of both users and developers: Compromise.

60 FPS or Bust: Dynamically Prerendering CSS Animations

Creating better animations for the web has been something I’ve been working on for a few years, and I’ve just figured out a new method that offers more flexibility and animation fidelity than was previously available. I call it “CSS prerendering,” and it’s easier than you think.

CSS vs. JavaScript animations

In the beginning, there was JavaScript. For years, JavaScript was the only way to add animation to a web page. As web standards matured, CSS become more featureful and offered transitions and animations. These browser-native CSS features are capable of delivering much smoother animation than JavaScript, because the browser seems to be able to optimize native animation. However, CSS animations and transitions are not terribly flexible, leaving developers to choose between a smooth, 60 frames per second animation, or an animation that can adapt to the needs of an application on the fly.

CSS animations (@keyframes) are inflexible because they must be hard-coded. Transitions are a little easier to work with, as they can gracefully respond to any CSS changes performed by JavaScript. However, the complexity that CSS transitions can give you is pretty limited — an animation with multiple steps is difficult to achieve. This is a problem that CSS @keyframe animations are meant to solve, but they don’t offer the level of dynamic responsiveness that transitions do.

CSS @keyframe animations are also limited by the native easing formulae available — there are only six. This is not enough to meet the needs of all designs. Joe Lambert came up with a way around this with Morf; a tool that generates a @-webkit-keyframe animation with many tiny steps. This opens the door to an unlimited selection of easing formulae. I decided to build on top of this idea with Rekapi’s Rekapi.DOMRenderer.toString feature, which uses a straightforward keyframe API to generate cross-browser compatible CSS code. I then used that functionality to create Stylie, which provides a UI to create animations and exports it to CSS code.

CSS prerendering

The idea behind CSS prerendering is pretty straightforward — you create a CSS @keyframe string at runtime with JavaScript, inject it into a dynamically-created <style> element, and then insert that element into the DOM. When the animation is complete, you simply remove the <style> element from the DOM. This approach works surprisingly well, particularly in WebKit-based browsers (other rendering engines still need to catch up).

Until now, there haven’t been any tools that I could find that can do this, so I decided to fill this void with Rekapi’s DOMRenderer module. Rekapi’s goal is to provide a usable and flexible API for creating keyframe animations, and historically it only performed JavaScript-based animations. With the DOMRenderer, you can use the same API to create a CSS @keyframe animation, making for magically smoother animations that don’t block the JavaScript thread. But don’t take my word for it, you can see the difference for yourself. The difference in quality is far more pronounced on mobile devices, especially iOS.

Creating a CSS animation with Rekapi

To create a CSS @keyframe animation that works in every browser, you need something like this (generated by Stylie):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.stylie {
  -moz-animation-name: stylie-transform-keyframes;
  -moz-animation-duration: 2000ms;
  -moz-animation-delay: 0ms;
  -moz-animation-fill-mode: forwards;
  -moz-animation-iteration-count: infinite;
  -ms-animation-name: stylie-transform-keyframes;
  -ms-animation-duration: 2000ms;
  -ms-animation-delay: 0ms;
  -ms-animation-fill-mode: forwards;
  -ms-animation-iteration-count: infinite;
  -o-animation-name: stylie-transform-keyframes;
  -o-animation-duration: 2000ms;
  -o-animation-delay: 0ms;
  -o-animation-fill-mode: forwards;
  -o-animation-iteration-count: infinite;
  -webkit-animation-name: stylie-transform-keyframes;
  -webkit-animation-duration: 2000ms;
  -webkit-animation-delay: 0ms;
  -webkit-animation-fill-mode: forwards;
  -webkit-animation-iteration-count: infinite;
  animation-name: stylie-transform-keyframes;
  animation-duration: 2000ms;
  animation-delay: 0ms;
  animation-fill-mode: forwards;
  animation-iteration-count: infinite;
}
@-moz-keyframes stylie-transform-keyframes {
  0% {-moz-transform:translateX(0px) translateY(0px);}
  100% {-moz-transform:translateX(400px) translateY(0px);}
}
@-ms-keyframes stylie-transform-keyframes {
  0% {-ms-transform:translateX(0px) translateY(0px);}
  100% {-ms-transform:translateX(400px) translateY(0px);}
}
@-o-keyframes stylie-transform-keyframes {
  0% {-o-transform:translateX(0px) translateY(0px);}
  100% {-o-transform:translateX(400px) translateY(0px);}
}
@-webkit-keyframes stylie-transform-keyframes {
  0% {-webkit-transform:translateX(0px) translateY(0px);}
  100% {-webkit-transform:translateX(400px) translateY(0px);}
}
@keyframes stylie-transform-keyframes {
  0% {transform:translateX(0px) translateY(0px);}
  100% {transform:translateX(400px) translateY(0px);}
}

…And then paste that into your CSS code. That’s just for one, very simple animation. Here’s how that same animation might be set up with Rekapi’s DOMRenderer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var rekapi = new Rekapi(document.body);
var actor = new Rekapi.Actor(
    document.getElementsByClass('stylie')[0]);

rekapi.addActor(actor);
actor
  .keyframe(0, {
      transform: 'translateX(0px) translateY(0px)'});
  .keyframe(2000, {
      transform: 'translateX(400px) translateY(0px)'});

// Feature detect for @keyframe support
 if (rekapi.renderer.canAnimateWithCSS()) {
   rekapi.renderer.play();
 } else {
   rekapi.play();
 }

Rekapi handles all of the vendor prefixing for you, so you only need to write an animation once. And if the browser doesn’t support CSS animations, Rekapi will gracefully fall back to an old-fashioned JavaScript animation, which it has always supported. To see what kinds of complex animations Rekapi can handle, I encourage you to check out Stylie, which is simply a graphical front end for Rekapi.

Better animations

CSS lets developers and designers create fluid, efficient animations that don’t block the JavaScript thread. However, we have lacked the tools to make them easy to work with. I really want to solve this problem, and I think that Rekapi and its DOMRenderer significantly narrow the gap between performance and flexibility. I hope that CSS prerendering becomes more widely used, as it enables a much smoother web experience. I’d love to know how CSS prerendering works for you, and if you find any bugs, please report them. Happy animating!

Update: Rekapi has reached 1.0.0 after this post was originally published, and the API for CSS prerendering has changed somewhat. The article has been updated for accuracy.

Open Source as a Civic Duty

I occasionally get asked why I spend so much of my free time writing software and giving it away for free. There are a number of reasons for this — I like to build things and I use it as an excuse to practice and improve my skills — but one of the most driving motivators for me is that I see open source contributions as a civic duty, a moral obligation to the rest of the world.

Considering that I am an employed programmer living in Silicon Valley that is generally thought to not be incompetent, you could deduce that I’m not worried about how I’m going to pay for my next meal. I’m not rich by any stretch, but I have a reasonably comfortable lifestyle, and that’s all I’d ever really want. After all, does a programmer need much more than a laptop and a cup of coffee to be content? Given that I’m not stressing about whether or not I’ll have a place to live and food to eat next month, I’m among the most fortunate people in the world. And if you have access to the technology needed to read this, you probably are too.

Morality is a touchy subject that varies widely among individuals and cultures, and this post is not meant to imply that my sense of morality is necessarily correct. However, I feel that people who are fortunate enough to survive on their own means have an obligation to give back to their community. I believe that some degree of self-sacrifice and civic duty is necessary to build and maintain a community that we all want to live in. This can come in many forms — giving to charity, doing volunteer work, or in my case, writing free software. It doesn’t really matter how you try to contribute to your community, it just matters that you are doing it.

Granted, I’m not writing software that will deliver clean water to poor countries in Africa or help cure Malaria. I tend to focus on web animation tools and other UI utilities. However, I’m doing work so that others don’t have to. My goal is to save time at scale so that other people can solve different problems that don’t yet have solutions. To take an extreme example, consider the GNU Project. As a whole, GNU has saved humanity man-centuries worth of work. There’s very little time spent developing operating systems and basic utilities anymore, because that is mostly a solved problem. Instead, we use GNU tools that others have spent the time to build, freeing us up to pursue other challenges like statistical modeling and AIDS research. If you have doubts about the value of free software, just look at GNU.

Altruism is, unfortunately, not a terribly common value in Silicon Valley. At best, larger companies will have a branch dedicated to positive social impact, and smaller companies may have the occasional charity fundraiser. But it seems that a large portion of Silicon Valley tech companies are focused on some self-serving vision or niche problem that only the founders and their friends have. I don’t want a culture where the only problems being solved are the ones that tech people have. I feel that writing free software on my own time is a tiny step in the right direction, even if indirectly. My dream is that someday, a free tool I’ve written will be used to help do something truly valuable. Anyone can do this, it doesn’t require much money or time — just a sense of the bigger picture.