Project Structure

app/, config/, tests/ — One Folder Per Concern

Project Structure

Every Ember app shares the same layout — app/ for code, config/ for environment, tests/ for specs. Knowing the map makes any codebase readable.

4 min read Level 1/5 #ember#structure#conventions
What you'll learn
  • Identify app/routes, app/components, app/services, and app/templates
  • Find router.js and the resolver
  • Read config/environment.js for per-environment settings

Ember’s directory layout is prescribed, not suggested. Once you learn it, you can navigate any Ember codebase without a tour.

The app/ Folder

app/
├── components/      # Glimmer components (.js + .hbs)
├── routes/          # route classes with hooks
├── services/        # singletons (auth, cart, store)
├── models/          # Ember Data models
├── controllers/     # query-param and template state
├── templates/       # route templates (.hbs)
├── helpers/         # template helpers
├── modifiers/       # element modifiers
├── router.js        # URL map
├── app.js           # boot file
└── styles/          # CSS / SCSS

The resolver maps a name like component:my-button to app/components/my-button.js. You never write imports for templates, routes, or services discovered by the resolver.

config/

// config/environment.js
module.exports = function (environment) {
  const ENV = {
    modulePrefix: 'my-app',
    environment,
    rootURL: '/',
    locationType: 'history',
  };
  if (environment === 'production') {
    ENV.apiHost = 'https://api.example.com';
  }
  return ENV;
};

Environment-specific values live here, branched by environment === 'development' | 'test' | 'production'.

tests/

tests/
├── unit/            # plain function / class tests
├── integration/     # component tests with a renderer
├── acceptance/      # full app + router tests
└── helpers/         # shared test setup

Every generator creates a matching test in the right subfolder.

The Application →