Khan Engineering

Khan Engineering

We're the engineers behind Khan Academy. We're building a free, world-class education for anyone, anywhere.


Latest posts

Making Websites Work with Windows High Contrast Mode

Diedra Rater on March 21

Kotlin for Python developers

Aasmund Eldhuset on Nov 29, 2018

Using static analysis in Python, JavaScript and more to make your system safer

Kevin Dangoor on Jul 26, 2018

Kotlin on the server at Khan Academy

Colin Fuller on Jun 28, 2018

The Original Serverless Architecture is Still Here

Kevin Dangoor on May 31, 2018

What do software architects at Khan Academy do?

Kevin Dangoor on May 14, 2018

New data pipeline management platform at Khan Academy

Ragini Gupta on Apr 30, 2018

Untangling our Python Code

Carter J. Bastian on Apr 16, 2018

Slicker: A Tool for Moving Things in Python

Ben Kraft on Apr 2, 2018

The Great Python Refactor of 2017 And Also 2018

Craig Silverstein on Mar 19, 2018

Working Remotely

Scott Grant on Oct 2, 2017

Tips for giving your first code reviews

Hannah Blumberg on Sep 18, 2017

Let's Reduce! A Gentle Introduction to Javascript's Reduce Method

Josh Comeau on Jul 10, 2017

Creating Query Components with Apollo

Brian Genisio on Jun 12, 2017

Migrating to a Mobile Monorepo for React Native

Jared Forsyth on May 29, 2017

Memcached-Backed Content Infrastructure

Ben Kraft on May 15, 2017

Profiling App Engine Memcached

Ben Kraft on May 1, 2017

App Engine Flex Language Shootout

Amos Latteier on Apr 17, 2017

What's New in OSS at Khan Academy

Brian Genisio on Apr 3, 2017

Automating App Store Screenshots

Bryan Clark on Mar 27, 2017

It's Okay to Break Things: Reflections on Khan Academy's Healthy Hackathon

Kimerie Green on Mar 6, 2017

Interning at Khan Academy: from student to intern

Shadaj Laddad on Dec 12, 2016

Prototyping with Framer

Nick Breen on Oct 3, 2016

Evolving our content infrastructure

William Chargin on Sep 19, 2016

Building a Really, Really Small Android App

Charlie Marsh on Aug 22, 2016

A Case for Time Tracking: Data Driven Time-Management

Oliver Northwood on Aug 8, 2016

Time Management at Khan Academy

Several Authors on Jul 25, 2016

Hackathons Can Be Healthy

Tom Yedwab on Jul 11, 2016

Ensuring transaction-safety in Google App Engine

Craig Silverstein on Jun 27, 2016

The User Write Lock: an Alternative to Transactions for Google App Engine

Craig Silverstein on Jun 20, 2016

Khan Academy's Engineering Principles

Ben Kamens on Jun 6, 2016

Minimizing the length of regular expressions, in practice

Craig Silverstein on May 23, 2016

Introducing SwiftTweaks

Bryan Clark on May 9, 2016

The Autonomous Dumbledore

Evy Kassirer on Apr 25, 2016

Engineering career development at Khan Academy

Ben Eater on Apr 11, 2016

Inline CSS at Khan Academy: Aphrodite

Jamie Wong on Mar 29, 2016

Starting Android at Khan Academy

Ben Komalo on Feb 29, 2016

Automating Highly Similar Translations

Kevin Barabash on Feb 15, 2016

The weekly snippet-server: open-sourced

Craig Silverstein on Feb 1, 2016

Stories from our latest intern class

2015 Interns on Dec 21, 2015

Kanbanning the LearnStorm Dev Process

Kevin Dangoor on Dec 7, 2015

Forgo JS packaging? Not so fast

Craig Silverstein on Nov 23, 2015

Switching to Slack

Benjamin Pollack on Nov 9, 2015

Receiving feedback as an intern at Khan Academy

David Wang on Oct 26, 2015

Schrödinger's deploys no more: how we update translations

Chelsea Voss on Oct 12, 2015

i18nize-templates: Internationalization After the Fact

Craig Silverstein on Sep 28, 2015

Making thumbnails fast

William Chargin on Sep 14, 2015

Copy-pasting more than just text

Sam Lau on Aug 31, 2015

No cheating allowed!!

Phillip Lemons on Aug 17, 2015

Fun with slope fields, css and react

Marcos Ojeda on Aug 5, 2015

Khan Academy: a new employee's primer

Riley Shaw on Jul 20, 2015

How wooden puzzles can destroy dev teams

John Sullivan on Jul 6, 2015

Babel in Khan Academy's i18n Toolchain

Kevin Barabash on Jun 22, 2015

tota11y - an accessibility visualization toolkit

Jordan Scales on Jun 8, 2015


Prototyping with Framer

by Nick Breen on Oct 3, 2016

We strive to make all of Khan Academy’s new features & experiences easy to understand and valuable to our users. Watching our users interact and explore new features, which is often called user testing, helps us identify which designs & flows are non-intuitive and could use some improvement. Doing user testing as early as possible is useful because changing designs is significantly easier before the design is passed to the product team to implement and build.

In this blog post, you and I will explore how Khan Academy uses prototypes in our user testing and hopefully it will be a great primer for you to start prototyping!

Why do we prototype?

Prototyping allows our product teams to create a more immersive, often called higher fidelity, product walkthrough experience. Flipping through a set of static design mockups would be less interactive and an example of a lower fidelity experience. Both options are useful and can lead to valuable feedback. Lower fidelity user testing is done first and high fidelity prototypes are utilized later to provide a more immersive, less instructor guided interaction with the feature.

A prototype’s main purpose is to enable our users to interact with new designs which gives us feedback to improve our designs. Each prototype is only seen by the participants of our user test groups and the prototype has a set lifespan since it’s retired after user testing. This means our prototypes can have a much lower coding standards quality bar than anything we create for, which is commonly referred to as our production environment. This is a good thing, because we can take advantage of different tools to build faster.

What tools do we use and why did we pick them?

During the prototyping phase of a project the designs will regularly change thanks to all this great user feedback. Our goal with any prototyping is creating and editing new screens as quickly as possible because designs will be tweaked after every user interview. Instead of writing time-intensive, stable code and perfecting CSS styling on all browsers we want to utilize tools that help us create new features quickly with comparable levels of fidelity. There is a large list of prototyping tools that serve different fidelity needs, ranging from piecing together screenshots (ex: Marvel) to writing stateful prototypes that can integrate with backends (ex: Framer).

Our team has chosen Framer to do our prototyping work for a few reasons:

  • There are many folks at Khan Academy with Framer expertise
  • Framer has wonderful integration with Sketch, which is a design tool our friends in design use
  • Framer allows developers to play to their strengths (writing code) and has a lot of helpers to create functionality quickly.
Framer Icon

Below we’ll offer some great resources to getting started with Framer, but for now we’re going to keep exploring the philosophy of prototyping.

What should I prototype?

‘Do as little positioning and styling in the prototype as possible’ is a rule of thumb we’ve learned on our prototyping adventures. All the styles and positioning should be done in the design mockups instead of in our prototype’s code. One of Framer’s advantages is the ability to easily import Sketch files. This feature instantly imports the exact pixel-perfect position for all the elements, which are also styled exactly as they appear in the designs.

On the flip side, we can and should do all state changes in our prototype. The most common state changes in a prototype are:

  • changing text on a page
  • swapping images to denote a correct or incorrect selection
  • showing new content when clicking on a link (example: show me a hint for this question)

One of our most interesting issues we solved when learning how to prototype was creating a repeatable and reliable way to change text in your prototype. Our solution had two parts, first we swap the layer containing the text with a new layer which has the new text. Let’s pretend that second layer has less text on it so it’s shorter. The second step was to reposition and shrink or grow all the layers below the swapped layer and the parent layers. Since our swapped layer is shorter we’d reposition those layers higher and shrink them. For a in depth exploration into this problem please see appendix A.

What should I NOT prototype?

To reiterate, Framer should be used when the prototype needs state-management, like tracking points, or dynamically changing content.

We should not be doing substantial design work (Pixel pushing, style updates, etc) in Framer. Remember our mantra: Do design work in mockups instead of in code.

There are easier and faster tools if we just want to simply stitch design mockups together (our friends in design prefer Principle). Tabitha, one of our friends on the design team, said it best: “developer’s should only create stateful prototypes, everything else can be done faster and easier without custom code.”

I have questions

Great! Prototyping is all about moving fast and you might find yourself in a undiscovered land! The best place to ask questions is the Framer Facebook group or Stack Overflow FramerJS tag.

Closing thoughts

Give prototyping a shot and get your designs in front of users!

Special Thanks to Emily & Bryan for their help on this article.

Appendix A: How do I update sections & text fields that may grow dynamically?

As we noted above, one of Framer’s advantages is the ability to directly import sketch designs. The imported designs are pixel-perfect and each sketch layer is absolute positioned based on the layer’s x and y coordinates. However, this creates an issue when the prototype is required to dynamically change content and the layer grows or shrinks vertically.

Let’s explain this using an example. We have a prototype that is a question and answer prototype. The main page looks like:

Example app layout with questions and answers having dynamic height

We want to substitute the question text because each question is different. Also, let’s pretend our new question text is substantially shorter. Once we swap the text, they’ll be a new large space between the question text and answer prompt, which doesn’t match our designs. This makes the prototype’s user experience less authentic, which is bad.

We want our prototype’s user experience to be as authentic as possible. What do we do? We brainstormed and investigated three possible solutions. We’ve outlined them in great detail on Stack Overflow. We’ll now talk about our solution, which is to swap the layer and reposition all the layers below.

We wrote some code to:

  • Use TextLayer to create a new layer with the new question text
  • Measure the size difference between the original sketch question text layer and our new TextLayer
  • Resize the parent layers based on the difference calculated in #2
  • Remove the original sketch layer
  • Insert the new TextLayer in the same x and y coordinates as the original sketch layer

For more information on TextLayer, please take a look at it’s repository. Please note, the function / method I could not get convertToTextLayer to work properly.

Appendix B: Performance in Framer Studio

If your Framer prototype starts getting above ~1200-1500 lines of code, you'll likely run into performance issues with text-editing. If that happens, try this:

Head over to Terminal, and start a server on your local machine: cd myPrototype.framer/ python -m SimpleHTTPServer

Open up a browser window and go to localhost:8000 or whatever URL you got in Terminal. Use a different text editor (like Sublime or Atom or whatever else you have that's performant) and fire away!

Appendix C: Tips for creating a good Sketch document for importing into Framer

  • The layers/groups should be organized as they are displayed starting from the top going down
  • Unique names for every template and layer are helpful when importing the layers into Framer
  • Every growable text area (description, each answer, etc) should have it's own direct parent group