Before we get into all the things that make up elementary OS apps, there is a clarification that needs to be made. We need to understand what exactly design is about, but more importantly we want to smash two major myths:
Whether you realize it or not, you are constantly designing anything you build. It is an intrinsic part of creating something. Design is not just what something looks like. It's not just the colors and fonts. Design is how it works. When you decide to add a button that does a thing, that is design. You made a decision to add a button with an icon or a label and where that button went and the size and color of that button. Decisions are designs.
See also: Design Is Not Veneer by Aral Balkan
Design is testable. One design will meet a specific goal better than another design. Consider different types of bicycles. A folding bicycle has a different set of design goals than a mountain bicycle. Things like weight, size, and tire tread are important factors in helping the intended user reach their goals. Because we understand that design is about solving specific problems, we must also understand that we can objectively compare the effectiveness of two designs at solving those problems.
See also: Design is Not Subjective by Jeff Law
Providing settings can be a way to make sure an app is accessible to a wider set of users with special needs, but it can also be an easy way out of making design decisions about an app's behavior. Just like with problems of feature bloat, settings mean more code, more bugs, more testing, more documentation, and more complexity. When considering adding options to your app, try to strike a balance of making your app more accessible without pushing design work onto your users.
Design with sane defaults in mind. elementary OS apps put strong emphasis on the out of the box experience. If your app has to be configured before a user is comfortable using it, they may not take the time to configure it at all and simply use another app instead.
Get as much information automatically as possible. Instead of asking a user for their name or their location, ask the system for this information. This cuts down on the amount of things a user has to do and makes your app feel more intelligent and integrated.
Ask yourself if the configuration option you are adding is really necessary to make your app more accessible or if it makes sense to have a user make this decision. Don't ever ask users to make uninformed engineering or design decisions.
Keep things contextual. Instead of tucking away preferences in a configuration dialog, think about displaying them in context with the objects they affect (much like how shuffle and repeat options appear near your music library).
If your app needs to be configured before it can be used (like a mail client), present this configuration inside the main window much like a Welcome Screen. Once again, make sure this is really necessary set-up. Adding unnecessary configuration screens stops users from doing what they wanted to do when they opened your app in the first place.
See also:
Checkboxes That Kill Your Product by Alex Limi
Don't Give Your Users Shit Work by Zach Holman
The Wizard Anti-Pattern by Stef Walter
Most users don't want to read through help docs before they can use your app. Instead, they expect that your app will be intuitive and simple for them to understand without assistance.
Avoid technical jargon and assume little-to-no technical knowledge. This lets your app be “self-documenting.”
Provide non-technical explanations instead of cryptic error messages. If something goes wrong, a simplified explanation of what happened and how to fix it should be presented.
For more information, see Writing Style.
All about the guiding philosophies we employ
The elementary OS HIG isn't just about a set of concrete rules; it's meant to be flexible and extensible. As such, this very first portion of the guideline is all about the guiding philosophies we employ.
For a quick design crash course, we like "The User is Drunk" on YouTube:
Read on for our four guiding philosophies.
Always work to make your app instantly understandable. The main function of your app should be immediately apparent. You can do this in a number of ways, but one of the best ways is by sticking to a principal of concision.
It's often very tempting to continue adding more and more features into your app. However, it is important to recognize that every new feature has a price. Specifically, every time you add a new feature:
Your app gets slower, consumes more resources, and takes up more disk space.
Your app's interface becomes more cluttered and thus harder to use.
More time is spent implementing this new feature, rather than perfecting an old feature.
More code can often mean a greater possibility for bugs.
More features means more work on documentation, translations, etc.
Build small, modular apps that communicate well. elementary OS apps avoid feature overlap and make their functions available to other apps either through Contractor or over D-Bus. This both saves you time as a developer (by other apps making their functions available to you), and is a courteous gesture towards other developers (by making your app's functions available to them).