This week we're talking about Settings. There are many settings in CodePen, and we've been working on them a lot lately.
Common settings for a web app
The most common settings in a web app are the passwords and user names, and notifications. We'll probably do a whole show on notifications, but today we're going to dig into the user, editor and Pen settings.
2:21 The heart and soul of CodePen is the editor, so it was one of the very first things we worked on. There are options like syntax highlighting theme, so you can choose a dark or light background when editing code. Anytime you give users a code editor, it's safe to assume they'll want to customize it (and it's a good idea to have nice default settings).
Storing settings in JSON instead of MySQL
3:13 We set up the settings originally as columns in our database, but we backtracked to store the user's settings as a JSON blob instead (similar to how Sublime Text stores settings). That gives us the ability to make changes easily and add more configurations that users ask for.
4:38 The user is represented as a table in our database, so when the user chooses a theme, or font, or key bindings, their settings were saved as a value in that corresponding column.
6:15 If you have columns for all user settings, you could easily get up to 100 or 150 columns as you add options. That makes migrations more time consuming. Anytime you add a setting, you have to alter that table, which in MySQL is a pretty time expensive thing to do.
7:37 So we switched to using JSON blobs in columns. MySQL doesn't handle JSON in the best way, it just stores it as blob of data, which makes it difficult to index. We currently don't have the ability to query any of the data, but we are in the process of moving to Postgres, which will allow us to query JSON (even though we've never really needed to).
So why make the switch to storing settings in JSON?
10:61 The biggest reason we're making the switch is the ability to move forward quicker. We don't have to add a column to the database, run the migration, etc... (that's a time consuming process). Just today, we created a new table, so we had to run through the existing user settings and move them to the new table and store them as a blob. That process took 30-45 minutes (which felt pretty quick). Now, we can just have a discussion about the settings we want to add, and we can add a little bit of Ruby code, and we don't have to add a table for that. So it just becomes easier to move forward, and move a little faster.
You can't just throw anything in JSON
12:30 We have to keep track of what is in a JSON object, we have to treat that data like there's a schema for it. It's easy to screw up when you're talking about forms, since settings are often form controls on web apps; the name attribute in the HTML controls what data gets added. So we have to compare the form data against a default object to make sure it has the right key name and value.
14:37 If we had a bigger team, it would be challenging to make decisions about what settings to add, but because we're only 3 people right now, we'll have discussions about settings multiple times before adding them.
15:14 One of the editor settings we just added was tabs vs spaces. Another setting that we're working on is code folding, so we go into the user settings UI, and add a control for it. We set the default setting to "off", and that's it. There's no database migration.
16:52 The main reason we're doing this is to make our users happier. If you use a code editor like Sublime Text as an example, you can make a lot of customizations to it, which is really nice. If you use Vim, there are far more options for customizing. You can override almost anything.
The way that you change settings in Sublime Text is by making changes to a JSON file. We thought about doing something similar, but.... supporting that would probably be a nightmare. It works for Sublime, but we probably aren't going to go that route.
Design challenges for settings options
19:27 A UI interface for settings gets tricky when you start having a ton of options. There's a tight rope that you walk because you want to offer a lot of settings, but it's a design challenge, and everything that you offer has a development cost, a support cost, and a complexity cost for the users.
20:02 We try to balance it out by picking smart defaults for users. We're lucky that our user base are designers and developers, and we're glad we can offer smart defaults to them, but also let them customize their experience.
20:51 The thing we pushed today was a little tricky. So far, we've been talking about user settings like changing a password, updating your avatar, profile information, and so on. Those are all user settings; but we also have settings for pens.
Pen settings vs user settings
Whenever you open up a new Pen, there are default settings for things like Auto-save, Auto-update, and Preprocessors. If you visit someone else's Pen, you'll see their settings, because Pen settings take priority over user settings. We chose this because if you visit someone else's Pen and saw your defaults instead of theirs, you'd see something very different from the way they wrote the code.
27:15 One of the last times we dealt with settings was when we were working on the teams feature. A owner of a team gets a whole additional set of settings for their team profile, blog and notifications. So that about doubled the complexity of the UI for the team owner.
You have to be careful about how many settings you offer to users; if you give them a ton of options, they may just become overwhelmed and shut down.
We'd love to hear from those of you that run SaaS websites about how you handle settings; drop a comment in the podcast episode post on the CodePen blog!
If you have a job opening at your company, post it on the CodePen Job Board! It only takes a few minutes and you'll be reaching a huge community of potential candidates. If you're looking for a job, that's the place to go!
If you're enjoying this show, please take a minute to leave us a review in iTunes. We really appreciate it, and thanks to everyone who has already left a review!