Jeremy Kahn's Dev Blog

There's always a method to my madness.

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.

Setting Up a Local Development Environment in Chrome OS

Cloud-only operating systems are a great option for most people. Web apps are slowly replacing native apps, and that trend is likely to continue. However, one type of user that will have a hard time migrating to the cloud is software developers. So many of our tools are local command line utlities, and they don’t really work in the context of a web application. I tend to treat UNIX as an IDE, and this methodology is at odds with the concept of cloud-only operating systems. I can’t see myself ever giving up tools like Vim or Git, or the simple elegance of piping the GNU Coreutils. Cloud-based IDEs like Cloud9 are cool, but they don’t give me the control that I get from a UNIX-like environment.

The common workaround for this is to SSH into a remote server via the browser, but I feel that this is a fundamentally flawed way to develop software. This approach requires you to buy and maintain two machines instead of one. More importantly, your productivity is limited by the quality of your internet connection. If you are in a coffee shop with spotty wifi or just enjoying a nice day in the park with your laptop, you won’t have easy access to your tools, if any at all.

I got a Chromebook over the holidays, and one of my concerns was that I wouldn’t be able to code on it effectively. I don’t really have much use for a laptop I can’t code with, so I started looking into ways to get Ubuntu loaded so I could enjoy my Linux tools unencumbered. I tried installing a Chromebook-optimized version of Ubuntu, but it was kind of buggy and I felt like I was missing the point of the Chromebook. I removed Ubuntu and instead tried Crouton, an awesome little tool written by David Schneider. Crouton makes it painless to install a chroot Ubuntu environment on Chrome OS. In other words, it creates an Ubuntu file system inside of Chrome OS’s file system and logs you in. When logged into the chroot, you are effectively running Ubuntu. It’s not virtualization, as Ubuntu has full access to your hardware resources, which can be a bad thing if you’re not careful. If you are careful, it works amazingly well. You can even run a Unity environment (or whatever GUI you want, Crouton lets you choose) and graphical applications. You can easily toggle between the Chrome OS and Ubuntu environments with a keyboard combination. What really matters is that you can run OpenSSH and easily interact with it from Chrome, even when you are offline.

This post serves as a guide for two things: Setting up the basic chroot environment with Crouton, and some setup I needed to perform in order to get some development tools running. There were a few issues that needed to be worked out because this is admittedly a backwards way to do things, and the Ubuntu environment installed by Crouton is a little bare-bones.

Getting started with Crouton

The first thing to do is boot the Chromebook into Developer Mode. Doing this will wipe the device, but that doesn’t really matter because everything is backed up to the cloud and gets synced back down when you log in. This is the process I had to follow for my model, and yours may be a little different - just Google for it. You don’t need to worry about setting up the firmware to boot from USB. Once you are in Developer Mode, sign in and hit Ctrl + Alt + T to fire up the shell. Type shell to be dropped into a BASH environment. At this point you need to follow the directions in Crouton’s README, but here’s a quick rundown of what you need to do in the shell we just opened:

1
sudo sh -e ~/Downloads/crouton -t unity

Go for a walk at this point - this will download about 700 MB of files. Once the process is complete, you will be prompted for the root user name password. Enter that, a few other bits of user info, and you’re done! Since we installed Unity, we can fire that up with:

1
2
# The `-b` backgrounds the process.  You can omit it.
sudo startunity -b

You can switch between the Chrome OS and Ubuntu environments with ctrl + alt + shift + F1 (the “back” button) and ctrl + alt + shift + F2 (forward), respectively.

That’s it! Now you can run Ubuntu apps inside of Chrome OS.

Setting up a development environment

The previous section was for setting up an Ubuntu chroot, this section is for setting up some tools that are useful for web development.

Git

You need Git. ‘Nuff said.

1
sudo apt-get install git

Vim with Ruby support

Command-T, a Vim plugin I use, depends on Ruby support. Because of this, I needed to compile Vim with Ruby support enabled. The Ubuntu chroot that Crouton installed lacks a few of the dependencies that a Ruby-enabled Vim requires, so I had to install those myself:

1
sudo apt-get install libncurses5-dev ruby-dev

From here I followed this guide written by Krešimir Bojčić , but here’s the part that actually gets and compiles the source code into an executable:

1
2
3
4
5
6
7
8
9
10
11
12
# Vim is in a Mercurial repository.
sudo apt-get install mercurial

hg clone https://vim.googlecode.com/hg/ ~/vim
cd ~/vim
hg update -C v7-3-154
./configure --with-features=huge  --disable-largefile \
            --enable-perlinterp   --enable-pythoninterp \
            --enable-rubyinterp   --enable-gui=gtk2 \

make
sudo make install

Now your Vim has Ruby support!

OpenSSH

Another critical tool for me is OpenSSH, because I like to SSH into my Ubuntu environment from Chrome and not deal with Unity any more than I have to. The easiest way to do this is to install tasksel and install OpenSSH from there:

1
2
sudo apt-get install tasksel
sudo tasksel

tasksel gives you a UI to select a number of packages you’d like to install, including OpenSSH. You can also easily install a LAMP stack from this UI, if you’d like.

Node

Yup, you can run NodeJS from Chrome OS. It’s as simple as:

1
sudo apt-get install nodejs npm

Full-stack development for $250

The Chromebook is an amazing little device. By running an Ubuntu chroot, you have all the tools you need to build a web project from scratch, and probably a lot more. Keep in mind that it has an ARM instruction set, so some programs may not work (or at least need to be compiled from source). I haven’t had any hangups that I couldn’t fix, however. Why is this worth the trouble? Personally, I just like little computers. It’s also great to have a SSD-powered laptop that has no moving parts - not even a fan. A soft benefit of having such an inexpensive device is the peace of mind of not lugging around a $2000+ laptop with you to the coffee shop. The 11-inch screen is reasonably comfortable to code on and the battery life is great. The Chromebook feels like a poor man’s MacBook Air, and with a full-featured local development environment, I can safely depend on it wherever I go.

In Response to Oscar Godson

My WebKit monoculture post garnered quite a reaction in the community. I figured my opinion would not be particularly popular on this subject, but I stand by what I said. If nothing else it sparked a few really interesting conversations. Oscar Godson wrote a well-reasoned response blog post with some strong counterpoints, which I’d like to address.

Just because something is open source doesn’t mean the downstream browser vendors implement it the same or don’t add to it. If it were true that WebKit was used the exact same away across browsers why are there so many Safari and Chrome differences?

This is true. There is inherent fragmentation in open source, and I don’t know how to solve that problem. However, I would argue that less fragmentation is better than more. Even if a single project gets forked many times and each is heavily modified, there is still a common base from which each fork descends. As I originally said, a world without browser rendering discrepancies is unrealistic. I just think we can somewhat diminish the problem by unifying on a common codebase and branching from it.

All that this does is creates browsers with different versions of WebKit where some have features A, B, C, and some X, Y, Z and some that mix and match and some that implement B differently because they felt that B was implemented in a bad way.

Yes, but this is the nature of open source. This is what happened with Linux, but eventually leading distributions emerged (Ubuntu and Android are examples of market-chosen leaders). Because it’s all Linux it’s not impossible for different versions to cross-pollinate. Ubuntu for Android is a great example of this happening with a degree of success. If either OS was built on top of a different kernel, such a frankenstein would be impossible (or a lot less elegant, anyways).

Also, Gecko is open source, so why WebKit over Gecko?

This much is my own personal opinion. To be clear, the original post reflects my opinion, so take it with a grain of salt. I prefer WebKit to Gecko for a number of reasons. Anecdotally I experience less frustration when developing with WebKit, but (also anecdotally) I am finding WebKit in more places than you can find Gecko. It’s already in two mainstream desktop browsers (Chrome and Safari), it is the (enforced) only option on iOS, and many less-popular browsers already use it or are switching to it. WebKit’s overwhelming market acceptance is why there’s even talk of a WebKit monoculture to begin with. The market is speaking: People want WebKit.

All three of the top browsers will be rapid release soon, so this makes WebKit no different.

True. The update problem will eventually solve itself. I mainly brought up the rapid release cycle to demonstrate how this is not IE6 all over again. My bigger concern is that Web Developers still need to support multiple rendering engines (-webkit, -ms, etc.), which makes us less productive. I feel that the prefix situation is ridiculous and needs to be fixed. The Web Developer community needs to decide which direction to move forward with - I think WebKit is the way to go because it is already winning.

What’s wrong with Gecko and/or Firebug?

Again, this much is my opinion. I feel that Chrome offers more powerful tools than the competition, but developers are of course free to make their own decisions.

And, the fact of the matter is, each WebKit browser has it’s own implementation of the dev tools (see point #1 again). I can’t stand Safari’s. So, you must just mean Chrome’s or do you mean Safari’s? Which is the “right” dev tools for WebKit that are the most “developer-friendly”?

My argument is that WebKit itself is a development tool because it can be scripted for automated tests. I’d bet Gecko has such capabilities, but I haven’t seen a PhantomJS equivalent for Gecko. The community does not seem to support Gecko as strongly as it does WebKit, and I favor options with the best community endorsement when selecting my toolset.

How is Gecko more buggy than WebKit? Are there stats on how many bugs and their severity? Are there more security bugs? Which is safer? I notice more bugs too in Gecko, however, I work in WebKit all day.

I actually agree with this entire part of the counterargument. And no, I don’t have metrics. I was referring to the bugs that a developer experiences during testing, not internal bugs or security issues. Bugginess favors the platform you didn’t start with. I build with WebKit first, and anecdotally I find that a lot of other developers do too. Surely there is a reason for this trend. I would postulate that it’s because a lot of developers have found WebKit and its associated tools to be a better choice in day-to-day development.

In the land of unicorns and rainbows WebKit would be the only browser, innovation would continue, every fork would be a vanilla fork and would somehow work the same on Windows, OS X, Linux, iOS, WP8, and Android. Unfortunately, in the real world that’s not how competition or technology works.

The community need ideals to pursue - this is how we unify. Perfect harmony is unrealistic, but why can’t web development be easier and faster than it is today? I think that it can, and agreeing on a core component such as a rendering engine will get us a little closer to a better ecosystem.

Footnote

I’m not trying to start a revolution. In all likelihood, I’m way off-base with some of my theories, but it is interesting to think about. The WebKit monoculture is something of an elephant in the room for the Web Development community, and I think it’s worth exposing and considering its implications rather than adhering to cultural dogma.