Normally I don’t write much about server and security issues. I’m certainly no expert. But if I can prevent the birth of even a single captcha, then I’ll sleep well tonight.
Every website you can sign up for eventually will need to ask themselves the question,
how do you prevent a malicious person from running a script 100s of times a second that acts like a sign up form submission to spam or DDOS your service?
At the very minimum your server should be rate limiting requests from the same IP address. But because IPs can be faked, additional protection is needed.
The different solutions to this puzzle each strike a different balance between security and convenience:
Captchas: use these if you hate your users
Sign-in with Facebook/Google/etc.: causes support issues, ties critical infrastructure to untrustworthy megacorps
User must verify their email before account is created: not too bad, but having to open email is noticeable friction – especially if you have other unread messages yearning for your attention
I was looking more user-friendly alternatives to these systems when I came across the idea of temporary tokens on the W3C wiki,
Assign a temporary token to the users at the start of their sessions. The token will be associated with the submitted form. When the session is terminated, the token expires.
Color me intrigued.
Putting Yourself In a Hacker’s Shoes
As intimidating as the term is, cybersecurity can be a fun mental exercise. While I build server routes, controllers, etc. a little voice in the back of mind asks “If I knew these api endpoints, how could I exploit them?”
So let’s take a step back to the original scenario to create some assumptions:
To make 100s of accounts a second, you’ll most likely be running a script from the command line.
There’s a relationship between benefit and effort. The less moral or financial incentive there is to break a service, the less effort you want to spend customizing your script.
Validating Sign Up with Session Tokens
Based on our assumption, a weak point of scripted sign ups is that the script isn’t running on the page itself. So instead of proving humanity (i.e. solve this puzzle), we really only need to prove presence (i.e. were you here? did you sign up on this website?).
Here’s how we can do that using temporary tokens:
When you load Kinopio and open the sign up form, a randomly generated session token is created by the client and saved to the server database.
When you submit the sign up form, the session token is included and the server first checks to see if that session token exists. If it does, then the token is removed from the database, and the sign up process continues. If it doesn’t, than the server responds with an error instead.
Periodically, old unused tokens are purged from the database
This is definitely more towards the convenience end of the security spectrum, but no single solution here is perfect and the advantage of session tokens is that they can stack nicely on top of other measures down the line if needed.
So over the last couple weeks, I’ve been talking to VCs and founders who have and haven’t taken VC to learn whether it makes sense for Kinopio. I don’t think it does.
I’m open to the idea of selling ~5-10% equity in Kinopio for 💰 to live a smoother life right now. But the relatively-easy money of VCs has a cost – once you get on the VC ferris wheel 🎡, the primary goal of a business changes:
Before “lets make a great product and sell it to people who love it”
After 🎡 “we need fast growth to raise ever-higher rounds of investment until the company gets acquired, so I never have to work again”
This really clicked for me during a chat with someone who recently took VC:
I like what I’m building, and if it dies it’ll be a shame. But it won’t kill me like it’s killing my baby that I would’ve loved to work on for the next 10+ yrs.
Maybe that’s the healthy approach, almost certainly the smart one – but it’s not mine. I want to work on Kinopio for at least a lifetime.
Built to Die, and Secretive About It
Funding models explain why it’s so hard to rely on software services long-term. Not because of technical problems like crashes, but because they’re often built to die.
Interesting, cool, and nice-to-use tools and platforms come out all the time. But it’s annoying to invest the time in learning and relying on something new only for it to get acquired and sunset, or become crappy in the 🎡 pursuit of growth-at-all-costs.
I’ve found that the best way to predict whether software is made to die is to look at how it’s funded. What’s the company’s business model? How will they make money?
It seems like more and more people are explicitly or intuitively becoming more aware of this. But it’s still rare for businesses to share how they’re funded. Advice I got from multiple founders is that if you raise VC, wait 2-3 years to announce it.
On the other-hand, it’s also not that common for self-sufficient businesses to share their business model either. Maybe they’re afraid of looking small, or maybe they think that people don’t care.
Kind of Like Farming
Two different kinds of farms can grow vegetables. One is a factory farm built for scale, and the other takes the time to grow more expensive but healthier plants without pesticides.
Will everyone appreciate the difference? Of course not, but the latter plants are labelled ‘organic’ to give us the information and the choice, so that those of us who do care can make better decisions.
So maybe we should have ‘organic’ software as well, made by companies that:
Are not funded in such a way where the primary obligation of the company is to 🎡 chase funding rounds or get acquired (so bootstrapping, crowdfunding, grants, and angel investment are okay)
Have a clear pricing page
Disclose their sources of funding and sources of revenue
And, if you are making organic software, please proudly tell the world because we want to know you’re making something we can rely on.
p.s. I know that software terms like bootstrapped and indie also exist. But these are vaguely defined (is angel investment okay? is having staff okay?), and predominantly speak to founders, instead of to why regular people should care.
p.p.s Thanks to everyone who graciously took the time to talk to me about funding. And special thanks to Aneesha for editing this.
Futureland is a journaling platform that helps you build habits or learn new skills through daily posting and activity streaks.
This is the tale of my redesign of the Futureland (FL) web app over the last year – how I started, what I did, and what I learned.
How I got Involved
I chanced upon FL when looking for a place to write rough thoughts and development diaries that I wanted to share. Creating journals and posting was straight-forward, and I liked it’s light-weight feel, simple aesthetic and tight-knit community,
But while trying it out, I kept giving myself paper cuts on confusing parts of the interface,
The sidebar grouped journals under ‘All’,’Daily’, and ‘Shadows’, but it was never explained what these meant
When opening a journal, the sidebar that listed your journals would slide away, with no obvious way to get it back
The cumulative result of these paper cuts was an interface that appeared minimalist but required regular pauses in workflow to remember how to use.
I posted about these issues, in case it was helpful, with no expectation of anything more coming of it. But the founder and lead developer, Vin and Lucas replied, and later on asked if I’d like to help make FL more usable.
My goal has always been to work on Kinopio full-time. But especially back then, the extra money would be very much welcome, to stay alive and occasionally buy nice things.
Step 1, Fixing the Floor
Making mockups is easy, communicating is hard. So the first thing to do was establish a shared foundation and vision. I started by asking questions to understand the thinking behind the existing design, and by collecting feedback from the community.
FL already had vocal power-users who’d climbed it pretty high up the pyramid by being manually 1:1 onboarded by Vin, but basic usability issues still slowed them down and were a barrier for newcomers.
🕊 The first way to make an interface feel intuitive is by grouping together related controls.
It made sense to do this by making the sidebar the ‘home’ of the interface with new responsibilities,
Primary: Organizing and navigating journals, teaching tips
Secondary: Creating journals, user profile, search, discovery
I started by proposing little adjustments and drawing new icons and controls for basic journal creation and navigation. By necessity, I was already updating the visual appearance of controls to fit inside the sidebar
Now that the fundamentals were set, this was a good time to step back and shape an aesthetic unique to FL.
I started with Vin’s original inspirations which I described as sleek, graphic, minimalist
We then added new images and commented on what we liked about them,
One of the themes that resonated were bright spot colors,
This gave me the idea for tying color to function. Users wouldn’t need this to explicitly explained – they would naturally form associations between like colored controls which would help them parse and learn the interface.
Writing a New Post
I used this system to design self-documenting components that were easy to develop against, and allowed the rest of the team to build new and consistent UI without needing me. Broadly speaking, these include,
Filter results by the selected option
Presents item info or editing controls, inherits function color
Short text entry in dialogs
Some Stuff I Did
I was only contracting 1-2 days a week. To make the most of that time, Vin would summarize the community, product, and business problems or aspirations of the week, and I’d tackle these in public in the Futureland.design journal.
We managed to touch almost every part of FL – here are some highlights,
Organizing Journals, Onboarding, and Grouping
On FL, journals are separated by posting frequency. Journals you post to regularly are Today journals, and everything else is Not Today. Today journals are listed first and show activity streak counts to encourage frequent updates.
The Today, Not Today concept is a little hard to explain though, so dismiss-able inline tips are meant to gently guide new users towards that use, without being dogmatic about it.
Additionally, a welcome journal was added for new users with more in-depth explanations,
Once people started creating dozens of journals, they wanted more ways to organize them so we added custom groups
Streak History and Scheduling
Posting everyday to a journal increments an activity streak count that is publicly shared.
As people grew ever-higher streak counts, they got more anxious about losing them. Requests started coming in for ways to conditionally forgive missing a streak. In response, others raised concerns about diluting the meaning of a streak.
Public streaks – which therefore have social value – are potentially toxic. But we softened the preciousness and anxiety associated with streaks through:
Streak History, so if you lose a streak you’ll still have a record of it that is publicly visible
Scheduled Journals, that let you customize streak frequency. This flexibility makes growing streaks easier, reducing their rarity and public value
Posting to your journals is the most important interaction on FL. Most posts on FL are short breezy updates, but occasionally someone will publish a couple paragraphs. You’re also able to publish private posts in a public journal.
Building features out as responsive components allows this same interface and code to be reused in other contexts, like quick-posting from in the sidebar,
Interactions ‘Assume Success’ and Complete Immediately
Sometimes feeling fast, is more important than actually being fast. This is especially the case when publishing a new post or comment.
When publishing content on FL, you had to wait until the server successfully responded before you were allowed to do something else. Whether consciously or not, these sorts of penalties for interaction naturally discourage future interactions.
The work here was describing how to eliminate these delays using a principle I like to call assume success,
In the rare case that the server responds with an error, FL asynchronously notifies you of the issue and lets you handle it in your own time
I’m particularly happy with how this turned out IRL, Lucas did a great job implementing this.
The Web App is the Best App
The sum of all these changes and others means that every feature of Futureland is now completely usable on Android and iOS. Having less platform specific code to maintain helps a small team do more with less – hopefully for years to come.
Ending on Some Thoughts on Contracting
I stopped working on FL a couple months ago to refocus on Kinopio full-time.
Looking back, this was my first time working as a contractor. I used a simple time tracking space to track my billable hours, which I’d compile into an invoice at the end of each month or so.
The main thing I wish I did differently was charge by the day instead of hourly to give myself a bit more breathing room to think long-term without the feeling that I had to make every second count.
So would I do it again? I’m not sure.
On one hand, it was pretty stressful working on two products at the same time. On the other, the perspective from being placed inside the beating heart of another community helped inspire Kinopio features like notifications, and weekly review emails.
It’s not so often in life that you get to help grow a new and promising community. I’ve been lucky (or unlucky) enough to have been here a couple times. The only constant is that it’s different every time.
Working with Futureland was a unique and interesting experience that I’m happy to have been a part of.
People seemed to really like the busy week, I should do this more often…
Deciding What to Make
My biggest source of ideas is people’s problems or requests on the forums, on discord, or IRL. These take the form of either:
“I need X”, which is straight-forward and just a matter of priority
”I want to do Y”, which doesn’t make sense initially, but finding out the why behind the request leads to something new
”I wish I could do Z”, sometimes I wish I could do Z too, but I need to swirl the idea around in the back of my brain for a couple months before I figure out how to build it in a way that’s performant and works with the Kinopio interface
Equally important are my own dreams – Kinopio is nowhere near complete in my eyes. Maybe it won’t ever be.
So I continually ask myself:
”How can spaces be more expressive?”, more personal, and more fun to use. My goal is for the tool to feel like an extension of your mind
”How can the tool be more usable?”, the more reasons people have to use Kinopio, the more reasons they have to share and invite others to their spaces
I benefit from these in my own spaces. Especially in Life Tasks, where I figure out what I’m doing next, and jot down errands and random ideas and observations,
Designing, Coding, Sometimes in That Order
In 2014, I wrote about my belief that design and engineering are best when tightly woven together. That’s truer now than ever.
If I’m feeling confident, I’ll jump right into my text editor and write something like this to create a new controls,
From here, more functionality is added and the code is tweaked until the feature looks and feels right to me. Whether it’s something simple like this, or prototyping a new interaction like multi-connect, there’s no substitute for designing with real code.
In rare cases when I have ideas or plans that I’m less confident about, it’s time to break out the paper, pens, and markers,
Because the Kinopio interface elements and aesthetic are full-grown, I almost never use traditional design software anymore.
Ship It to the World
I keep the review and release process simple – commits are linted, PRs are code-reviewed, branch merges auto-deploy to production.
While coding, I create a list of interactions to manually QA test afterwards. If the change is risky or risqué, I’ll release sneak-peek videos for feedback, and ask beta testers to try it out in a staging environment beforehand.
Everything I know about marketing I learned by osmosis in previous jobs. Most software marketing messages are variations on a theme,
“We exist! We can help! We’re really popular! Trust us!”
After a new feature is shipped, I post and tweet about it. With practice, weaving marketing into design and development is starting to feel like a natural part of the cycle.
There’s no shortage of articles with silver bullets like how to double your audience with one cool trick™. But once you strip away the artifice and wipe off the sludge, marketing is just communication – and the best communication informs, inspires, and entertains.
In the case of Kinopio, I hope to convey,
Function, how Kinopio helps you make sense of information in a more engaging way
Beauty, create expressive and interesting spaces that you’ll want to share
Aspiration, using Kinopio helps you turn your problems into solutions, and your ideas into actions
It’s a long road to travel. Like the Oregon Trail, but instead of losing people to dysentery, new friends are jumping on the caravan everyday.