Having worked with Ember for four years now, it feels like a good time to take stock of all the lessons I've learned. Here are some good practices and bad habits that I'd share with myself if I could go back to when I was just starting out -- and that I still find useful to be reminded of on a regular basis.

Component design

Avoid the temptation to immediately start creating components before a static design is agreed upon. Instead, start with static HTML, then break that HTML up into components that fit neatly within your site's design.

Don't prematurely abstract by designing components for maximum re-use and flexibility, making every action and property configurable. Instead, design components with readable APIs that fit within your application's domain.

Understand all the states in which your components can exist. Don't display blank screens.

Don't {{yield this}}. Think carefully about how to yield as little as possible.

Compose components in your templates, and don't fetishize mixins.

Testing

Test the code you're responsible for. Avoid testing framework code.

Use component integration tests to test internal developer APIs and actions, and keep nearly all external user behavior, like clicking and filling in forms, in acceptance tests. Understand that your tests exist at different levels of abstraction, and consider the user -- another developer? the end customer? -- of the system under test.

Don't make excuses for not testing, and learn how to avoid writing brittle tests.

Community solutions

Don't try to solve every problem -- learn how and when to use addons.

Allocate part of your development time to continuously learning: attending meet-ups, going to conferences, chatting in slack, contributing to addons, reading blogs, listening to podcasts, or engaging on Twitter. It's easy to not make time for this, but the smallest bit of new knowledge can have a dramatic effect on your day-to-day work.

Put aside your favorite tool if doing so allows you to follow shared solutions. Ember is not just a tool, it's a community -- don't be somebody that refuses to budge.

Learn how the framework evolves and changes. Read RFCs, share your frustrations, and experiment with solutions. Don't feel entitled to the framework, and don't complain about changes you disagree with but did nothing to influence.

Routing

Return a single model or collection from model hooks on your routes — doing so enforces good domain modeling. Don't return RSVP.hash or RSVP.all.

Nest routes according to your UI designs; otherwise, loading data will be unnecessarily complicated.

Asynchronous code Take time to understand that JavaScript-rendered applications are not just another way to do what server-rendered applications already do. Consider that you are working in a stateful environment, and dealing with activities that are fundamentally concurrent.

Learn why managing asynchronous code is so difficult, and look for abstractions that can help. Ignore this, and your apps will be littered with extraneous imperative code and buggy state machines.

Write apps that are aware of when they're transitioning, running many activities, or offline. Don't write static apps.

HTTP APIs

Avoid writing hand-coded bespoke HTTP APIs. Understand the benefits of JSON:API, and be able to explain them to your team.

Learn how data is loaded and flows through your application. Learn about the various states of your data store, and avoid writing N+1 query bugs in your templates.

Take time to think about the one-to-one, one-to-many, and many-to-many relationships in your application. Don't treat these as a backend problem.

Perform CRUD operations on resources, including join records. Don't make new abstractions just to limit your frontend's exposure to the domain model.

Code and design

Always consider tradeoffs when applying design patterns. Don’t lock onto a small set of concepts and apply them to your entire codebase.

It's easy to get upset at Ember when your code doesn't work the way you expect. Lots of thought and consideration went into Ember -- take time to understand its conventions, and investigate the reasoning behind non-obvious design decisions that frustrate you.

Teammates

Don't complain when a co-worker makes a mistake. Instead, take time to discuss best practices. You'll both learn something new and exciting.

Don't avoid asking for feedback about your component APIs or complain about bikeshedding. API design, like documentation and styleguides, is another form of communication, and is critical to the long-term success of any application.