v0.01 — stardate

Job stories instead
of User stories.

At Pixelpillow, we've been working with User stories for years, known to most readers as a way of defining - from the user's perspective - what functionality software should contain: 'as [user], I want [action] so I want [outcome].'
At Pixelpillow, we increasingly noticed that this method was inadequate. We therefore switched to writing Job Stories.

Why don't User Stories work?

User stories have been standard practice in product development for decades. But we systematically ran into the following problems:

  • User stories assume a 'type' of user. They are often based on predetermined 'personas (John, 42 years old, installer, 3 children, etc)'. But personas are not 'real' people, and so in establishing them we make all sorts of assumptions about users. And as great philosopher Steven Seagal once said, 'assumption is the mother of all f*ckups'.
  • Although never conceived for that purpose, personas have become an easy excuse for many organizations to avoid talking to real users.
  • The user story describes what the user wants, but not why the user wants it. So the UX designer has very little context to determine which solution will help the user the most.
  • Data analysis (e.g. at facebook) showed that the behavior of different types of user was often more similar than different. So the [user] piece of a user story doesn't matter that much.

In short: a user story makes too many assumptions about the user and gives too little information about "why" a user wants to perform a task.

The Job Story as a better alternative

Since User Stories didn't work, we switched to Job stories. Job stories were developed by Intercom, and stem from the "Jobs To Be Done" philosophy, which assumes that users don't want features or products, but that they want a problem solved. Job stories are then a way of identifying these "problems" and describing them as user tasks.

Intercom itself describes it as follows:

If we understood the situation in which people encounter a problem to solve, understand the motivation for solving it, and understand what a great outcome looks like, we were confident that we would be building valuable product for our customers.

Intercom

In the shape of a Job Story, this looks like this:

  • When [situation: what is the user's context]?
  • Do I want to [task: what does the user want to do?]
  • Because [motivation: and why?]
  • So that I [outcome: what does the customer want to achieve?]

A small difference with a big effect

At first glance, a "job story" looks pretty much like a "user story. So why does this small change make such a big difference? That's because Job stories shift the focus from customer-oriented to task-oriented. With that, we no longer focus on a - often fictional - user, but on the task the user has to do. This makes the story more objective, more concrete and - if we write it well! - much more context about why the user wants to perform this task.

Writing a good job story

Writing job stories is not easy. But if you do it right 1, it yields a useful, practical list of tasks that are easy to translate into concrete features and components.

1

Naming what goes wrong is easy. So don't ask users what they want, but what frustrates them in performing their task.

Don't write: What is the number one need when doing your tax return?

Instead write: What is your No. 1 frustration when doing your tax return?

01.Talk to your users

Always start with real people. Find out who you are developing the application or site for and find people you can interview or - even better - observe performing their tasks. It is crucial for your product or service to find out what problems your users are trying to solve, and why.

Ask your user two questions:

  • what task do you want to perform?
  • what is your biggest frustration in doing so?

02.Rewrite your users' input into Job stories

Here it is important that in addition to naming the task (do I want), you also clearly name the situation the user is in (where and when) and the motivation (why does the user want to perform this task?).

2

The Job story has no option for naming a type of user because we said it is not relevant. But what if there is a very clear distinction between types of users and more importantly, what if they have to perform clearly different tasks? For example, in a system with a backend (administrator) and a frontend (consumer)?

In that case, you are not actually talking about types of users, but about "roles," which you can think of as the situation in which the user finds himself. You can easily include these in the Job Story, in the following way:

When I [in my role] as content administrator can't finish my blog article right away, I want to be able to save it as a draft, so that I can finish it at a later time.

When writing user stories, we always tried to be as concise as possible, but that is precisely not the intention when writing Job Stories! After all, we want to give the UX designer as much context as possible about the situation the user is in at the moment he or she wants to perform the task.

So don't write: When I'm hungry, I want,
But instead write: When I am hungry, almost running late, and don't have time to make my own food, I want ...

03.Translate the Job Stories into design solutions

Because Job Stories are more concrete than User stories, they lead faster to the right (design) solution and it is easier to estimate in advance how much time it will take to realize them. This helps prioritize functionality (is it worth this effort to solve this problem for a user?) and makes the final product more user-friendly and valuable to the user.

Captains log

Date
Done
Learned
Hr
03-10-2021
Scribble animations & home onload
Debugged scribble animations.
Isolating timelines makes debugging way faster.
2
Added home onload animation.
Trigger after assets load, not just DOMContentLoaded.
1
26-07-2021
Reader page
Connected Airtable API to new 'reader' page.
Airtable paginates results — need to handle the offset or you'll miss records.
3
Designed and styled the page.
Design with a fixed dataset first, hook up the API after.
2
24-07-2021
Maker page resize
Added onResize event to maker page so titles stay centered.
GSAP breaks CSS positioning.
1
05-07-2021
Date script
Wrote script to automatically display stardate and copyright date.
JS months are zero-indexed. Classic.
2
24-06-2021
Photo selection & title animations
Photo selection and editing.
Less photos, more impact.
2
Title animations.
Conflict between CSS positioning and GSAP is still tricky.
1
23-06-2021
Draggable photos
Made photos draggable.
Went easier than expected.
1
19-06-2021
ScrollTrigger & responsive styling
Implemented ScrollTrigger on maker page.
scrub ties animation progress to scroll position — good for parallax stuff.
3
Responsive fluid styling.
Fluid sizing + CSS custom properties = much less breakpoint juggling.
2
13-06-2021
Stylesheet structure
Refactored stylesheet structure using @import (postcss-import plugin).
Split files are so much easier to navigate than one giant CSS file.
1
Base styling for maker page.
Layout first, cosmetics later. Saves a lot of rework.
2
12-06-2021
CSS & layout refactor
Structured style.css by separating layout, typography and cosmetics.
Separation of concerns in CSS makes debugging way faster.
2
Updated layout content wrapper for more flexibility and added utility classes.
Keep utility classes single-purpose or they get unpredictable fast.
1
10-06-2021
PostCSS & Git
Configured PostCSS to compile all CSS files. Updated config in package.json and eleventy.js.
A glob (*.css) in the build command saves having to list every file manually.
2
Added mixin support to PostCSS via postcss-mixins.
Works like Sass mixins. No need to switch preprocessors.
1
Figured out how to stage files individually and make separate commits in Git.
Cleaner commits, less chaos in the history.
1
30-05-2021
GSAP tooling
Added GSAP code hinting and linting to VS Code.
Autocomplete for GSAP methods saves a surprising amount of time.
1
29-05-2021
Animation & positioning
Researched animation layout, positioning and performance. Did Codepen experiments.
Differences between animating left/top/right/bottom vs translateX/translateY, and how this translates to GSAP values.
3
22-05-2021
Changelog layout and animation
Animated changelog width and position based on vw.
Use the same positioning system in GSAP as in your stylesheet, otherwise unexpected effects. Don't set left: 100vw in CSS and then use x: 300 in GSAP.
1
Fixed scrolling changelog layover (codepen) using GSAP DrawSVG plugin.
Using only opacity for a layover is a bad idea — the element stays clickable when invisible. Always place an actual DOM element on top.
2
Designed homepage scribbles.
Colors are hard.
1
27-03-2021
SVG animations homepage
Attempted to implement SVG animations in Eleventy.
Failed. Eleventy appears to modify SVG markup during build. To be continued.
2
Animated 'scribbles' SVGs (codepen) using GSAP DrawSVG plugin.
DrawSVG cannot animate external SVGs. Inline SVGs cannot be used as CSS backgrounds or pseudo-elements.
2
Designed homepage scribbles.
Colors are hard.
1
22-03-2021
CSS Grid
Styled changelog table using CSS Grid.
CSS Grid positioning.
2
Designed changelog table.
What looks simple in design is sometimes hard in practice.
1
11-03-2021
Templating
Implemented Nunjucks templates and partials for footer, header, content and changelog.
Terminal error messages save a lot of time — if you actually read them. Both .md and .html files work as a base. What frontmatter is.
3
Researched templating languages.
How Nunjucks and Liquid work and how to set up a basic structure.
1
25-02-2021
Motion!
Animated menu, changelog and links.
GSAP x:0 is not absolute 0 — it's 0 from the element's starting position in the DOM. If CSS sets left: 100px, GSAP x:0 animates to 100px.
4
22-02-2021
Link animations & stagger
Animated Captain's log link.
How to remove an event listener using removeEventListener.
2
Added stagger animation to changelog.
GSAP stagger animates a list in sequence with barely any code.
1
18-02-2021
Setting up typographic foundation
Implemented fonts and styling for responsive typography.
Nothing new.
2
Set up a fluid typography system. Worked on homepage text and styling.
How to use clamp() to scale type fluidly between a min and max.
4
17-02-2021
Setting up personal site framework
Set up Eleventy as static site generator.
How to configure Eleventy using the terminal.
4
Gitlab setup.
What an SSH key is and why you need one. How to commit directly from VS Code.
2