CoursePad.me Design Notes (I)
Behind-the-Scene Stories from CoursePad.me’s First Two Weeks
On Oct 30, 2014, I released CoursePad.me to Cornell’s Computer Science Facebook Group. Since the project was still in its infancy, I thought beta testing in a small and tech-savvy community would be beneficial. However, I did not anticipate the overwhelming response: almost two thousand students visited the site within 24 hours. Now, two weeks later, there are more than 15,000 users.
Now, the pre-enroll season is winding down, and I'm privileged to witness this biannual craze from a unique vantage point. Here, I would like to share with you some of my design and observations, and hopefully can answer some questions you may have raised.
As I continue with the development, there will, inevitably, be more interesting challenges, technical and nontechnical. I hope to write more about the journey in this series.
A (Not So Brief) History
I have been a loyal user of chequerd. It has a very intuitive interface where one drag-and-drop between different alternative time slots. Data update was very fast, and it is not missing any major features. The design was as beautiful as you can get for a class scheduling software. It served my three semesters at Cornell very well.
A lot of friends swear by schedulizer, chequerd’s archrival. It was an amazing idea when you hear about it: add all your courses, give it some preferences (I want to have lunch break, for example), and it would magically generate a schedule that fits your taste. However it comes with a fatal flaw: you have few way to manipulate the schedule yourself. When technologies break and there’s no escape hatch, it is better to have no technology at all. Sometimes, schedulizer would simply generate too many schedules and overwhelm me. Sometimes I just want that one single section (or avoid it), and schedulizer makes it unnecessarily hard. Plus the website is slow and poorly designed, which exacerbates those problems.
As a regular user, I’d be very content about my workflow with chequerd. Add courses I want, permute them to my liking, pre-enroll, rinse-and-repeat next semester. But being a software engineer, I think while it’s 95% there, the last 5% should be finished. Every semester during and right before pre-enroll, chequerd would crash. Schedules are not automatically saved to the server, and there’s no save button — only “Save As.” Also, there are so many social features that can be added: classes my friends are taking, advice from former students, lecture quality rating, etc. There’s no sign any of these improvements may come to chequerd.
I was thinking about contributing to (or taking over) chequerd. However, it does not belong to any student organization or entrepreneurship program, and no owner details were listed on the website, which made my plan very hard. My well-connected friend, Adam Wang, offered to help, but although he managed to track down the LinkedIn details of the founder, the InMails he sent went to nowhere.
I decided to build my own.
But then I would face formidable competition. While users have little cost-to-switch when it comes to class scheduling software, I still need to present some compelling reasons to overcome inertia. I’ve come up with some killer features, one of which would be class sniping, i.e. running a script on our server to get you in the class you want. I'm pretty sure I'd gain a lot of users, and the only downside is I'd be expelled (and deported).
I thought the duopoly would last a while. However, while I contemplate the competition strategy, the scene of schedule planning drastically changed, beginning that summer. Schedulizer died without warning. Several other pre-alpha rivals were posted in the Computer Science group. Most were traditional web-based solution, but CUAgenda stands out as a native iPhone application.
Besides that, CUAgenda caught my attention for one other reason: it was the most heavily marketed among those, and even has a Cornell Daily Sun article dedicated to it. Also I realized it is probably the only one with a plausible revenue model: ad-supported freemium. I downloaded and tried it with excitement in the lunch queue, and was, however, a bit disappointed.
CUAgenda heavily employs skeuomorphic design, which Jony Ives famously killed from Apple. While people still debate its merits, both parties agree that its major purpose is to elicit a feeling of familiarity. Therefore, having iCal look like a personal organizer is probably fine, but making the menu of a semester planning software look like an apple tree is not. Neither is making the calendar look like a bookshelf. Besides graphic design, the UX is poor: navigation hierarchy is a mess (but is getting better each version), and the buttons can be very confusing. Plus, I'm not convinced that people want to schedule their classes on a phone. At the very least, you cannot copy-paste class numbers into student center.
(On a side note to all aspiring iOS developers: please make sure you read Apple’s iOS Human Interface Guideline)
Sensing that competition will only get worse, I decided to start the heavy-lifting work. I spent several days redesigning the logo (a previous one I did was horrible), then a week designing the interface and drawing a mockup. It took about two weeks of coding to achieve basic feature parity with chequerd. I originally hoped to launch it for Spring 2015 pre-enroll, but seeing that I'm unlikely to finish the server components before then, I decided to postpone launch to Winter Break, so everyone can use it in the first few weeks of the semester.

I had a vacation planned. The day before my flight left, I saw a post about the new Class Roster. My only question was, will the XML still be there? Luckily, yes (though not for long, with a new API taking its place)
I was wandering on the street of Florence when my friend Xinxin Wu pinged me on Facebook. Apparently, chequerd has not updated its data for Spring 2015. I felt really bad because my vacation was ill-timed so I missed the optimal launch window. So the first thing I did when I flew back was to check if chequerd was updated, and it seemed that it was. Then there’s no need to rush, and I casually modified my horribly-written scraping script to import the new XML, wrote the functionality to switch semester (the hardest part turned out to be writing the drop down menu), and called it the day, when Xinxin informed me that chequerd’s data is empty. For the first time Cornell students have nothing to use (CUAgenda wasn't updated either). I need to launch it despite not being 100% finished, otherwise I'd be doing my fellow students a disservice.
Launching the project is no easy task. I need to make sure there are no security bugs (thankfully, there are few thing you can do to a static website), add monitoring and analytics function, and do some housekeeping to the external-facing code.
Luckily, those didn’t take that long. The next day, the product was launched.
Marketing and Growth
Originally, my plan was to launch small-scale in Computer Science Group and gather feedback, while I add features crucial to non-technical users, like onboarding and browser version detection. Once it is stable enough, I'd start a Facebook Ads campaign, to attract mass adoption.
The reality is, the small-scale beta test attracted two thousand users before the Facebook Ads campaign started — hardly small anymore. Meanwhile, the campaign only contributed to 3.8% of all new users throughout its lifetime. The most effective channel seems to be word-of-mouth. Direct access, i.e. putting coursepad.me into browser, account fors 73% of all new users. About 14% user came from Facebook, while 6% came from Google.
Google traffic is definitely lower than I would expect, and it is an important lesson: choose your name wisely. One of my biggest complaint of chequerd was its name — I couldn't spell it correctly until sophomore year. Therefore, I deliberately chose a simple one. However, I forgot about the SEO consequence. It wasn't until two months after I purchased the domain did I realize there are two startups named CoursePad. To remedy this, I always refer to the product as CoursePad.me. But the damage is visible. Search term “coursepad” didn't bring any traffic. “coursepad cornell” didn't perform much better, accounting for only three users.
Traffic wise, the data is consistent with what one may expect. Nobody’s planning their semester around 4am. A small surge would occur at 7am on pre-enroll day. That surge, however, is less than you would imagine. Number of sessions per hour peaked at ~1,000. This suggests that chequerd probably simply needs a modest caching tier.

Cornellian’s favorite class for Spring 2015? You probably have guessed it, HD 3620: Human Bonding. And yes, I got in☺. Before sophomores and freshmen began worrying about their schedules, the second place goes to the famous HADM 4300: Introduction to Wines. However, seeing they're ineligible, the underclassmen rushed into ECON 1110 and CS 2110 instead, making them second and third, respectively, and the poor HADM 4300 is nowhere to be found in top 10:
- HD 3620
- ECON 1110
- CS 2110
- AEM 1200
- BIOG 1440
- ECON 1120
- DSOC 1101
- CHEM 2080
- ILRST 2100
- AEM 2210
Technical Choices
CoursePad.me was started to address the shortcomings of chequerd, and the foremost issue is scaling. However, how chequerd had its problem is perplexing. Built on Heroku and served behind CloudFlare CDN, it employs modern technologies that powers many high-profile websites. Apparently, either they didn't architect the software to support horizontal scaling, or they didn't have the resources to provision more instances, or both.
Instagram provided me with an invaluable lesson here. Up to their acquisition by Facebook, they have 35M users with no dedicated backend engineer. They did this by shifting as much logic to the clients as possible. This also made their product butter-smooth.
I didn't intend to launch a mobile app though, but my experience at Google told me this is doable on Web as well. I saw prototype crunching millions of rows of data, in browser, in vanilla JavaScript, with acceptable performance, on a Chromebook.
Therefore, to minimize cost and increase availability, the best way is to build a Rich Internet Application that preferably can function without a server present, or even Internet connection. While the second goal has not been achieved yet (HTML5 App Cache has certain drawbacks, and GitHub Pages is stable enough), CoursePad.me is proven to work without server quite well.
The next question is which front-end framework to use. I tend to use frameworks as sparingly as possible. For creating UIs though, which is inherently a declarative task, a nice framework is essential to reduce boilerplate. The top two choices are Angular.js and React, developed by Google and Facebook, respectively. I worked with Angular at Google, and a core contributor of React was a co-worker of mine (and a Cornell alum) while at Instagram.
Angular.js and React represent very different philosophy. Angular.js implements two-way data binding between model and UI elements, while React embraces a one-way data flow model. Angular diffs the model, and changes detected would triggers relevant views to re-render, and they will be consistent again. React, however, diffs the view, i.e. the DOM tree, by calculating a shadow DOM tree each time the state of the view is changed and mutate the DOM to match it. Angular.js is a full-featured library featuring M, V, and C, while React has V only.
There are two reasons I settled on React. The practical reason is, Angular.js is too framework-y. The characteristics of frameworks are they dictate how you structure your app, and in return, they would put pieces together magically. However, with the carrot comes with the stick: if you decide on a whim (or legitimately need) to do things a bit differently, you will end up wrestling with the framework. Plus, when the magic doesn't work as intended, you spend a long time figuring it out. The philosophical reason is I tend to bias towards multiple small libraries as opposed to one giant framework (which is why I prefer Flask to Django). This is more of a long-term thinking: what if you outgrow your framework? Early day Twitter suffered from huge performance problem, partly because the ORM layer in Rails is not very good.
Developing large-scale JavaScript requires a module system, and the top contenders are AMD and CommonJS, before ES6 modules gains foothold. Gladly, from my experience, it mostly boils down to personal preference. Most third-party libraries support both (or neither). Before, whether you prefer require.js, which loads AMD modules on-demand asynchronously, or browserify, which combines CommonJS modules in one blob, may influence your choice, but now we have webpack. CoursePad.me uses CommonJS modules, simply because I like the syntax better.
Asynchronous code is a giant mess in JavaScript, and I refuse to fall into callback hell. CoursePad.me uses Promises, which landed natively in Chrome and Firefox not too long ago. They made the code a lot more readable, but is still painful to write. In retrospect, I should have used generators, which have not landed yet but can be compiled to ES5 with Facebook’s regenerator, or even async/await, proposed for ES7.
There are some obvious choices, like Sass over Less and Gulp over Grunt, that I would not list here.
To summarize, here’s a non-exhaustive list of technologies CoursePad.me has used:
- React
- jQuery
- jQuery UI
- Drop.js
- webpack
- Gulp
- Sass
Future Directions
There are a lot of things to be done on CoursePad.me, and the journey may never finish. Multiple schedule support and auto-scheduling (a la schedulizer) are being worked on right now. Then a server component will be built, which would enable syncing. With that in place, sharing can be built. Then comes exploration functions, including friending, reviews, etc.
CoursePad.me is not a startup. It is a product. Startups are one of many vehicles to bring products to users. In the case of CoursePad.me, it’s a risky one, as both chequerd and schedulizer failed to find a business model (I actually liked chequerd’s book-selling idea a lot, although apparently it never took off)
As a developer, I am not very happy with the path Silicon Valley led us to. Software development is costly, so is operations. Yet, the marginal cost is seemingly zero, which made it popular to give software/services away. In fact, thinking about business model from day one is frowned upon. This effectively segregates companies into those who can afford to burn money because someone else is footing the bill (mostly enterprise customers), and those who can’t. Ultimately the market becomes “winner takes all”, leaving little room for niche products.
This is why low operating expense is an explicit design goal of CoursePad.me. So far, I only paid for the domain. Hosting and DNS are generously provided by “those who can afford to burn money”, namely GitHub and CloudFlare, free of charge. In the future, when this becomes unsustainable, I may request assistance from school (the cost of one student event would be enough to cover CoursePad.me for a year) or companies (they usually love student organizations). The exact details, however, still need to be worked out.
I would like to say thank you to every user of CoursePad.me. Extra kudos to those who have sent me feedback. Together, we can build the best scheduling website of all universities in America.
[Correction: a previous version of this article misspelled the Apple executive’s name. It should be Jony Ives, not Johnny Ives. Thank you Anthony and Victor for pointing this out]