App configuration and startup
Configure Aurelia applications, register global resources, and choose the startup pattern that fits your project.
Application Startup
Aurelia provides two main approaches for application startup: a quick setup using static methods with sensible defaults, and a verbose setup that gives you complete control over configuration.
Before you start: If you have not already chosen a project scaffold, walk through the section overview for context on how this guide fits with enhancement, routing, and composition topics.
Quick startup
The quick startup approach uses static methods on the Aurelia class and is the most common choice for new applications.
import Aurelia from 'aurelia';
import { RouterConfiguration } from '@aurelia/router';
import { MyRootComponent } from './my-root-component';
// Simplest startup - hosts to <my-root-component> element, or <body> if not found
Aurelia.app(MyRootComponent).start();
// Register additional features before startup
Aurelia
.register(
RouterConfiguration.customize({ useUrlFragmentHash: false })
)
.app(MyRootComponent)
.start();
// Specify a custom host element
Aurelia
.register(
RouterConfiguration.customize({ useUrlFragmentHash: false })
)
.app({
component: MyRootComponent,
host: document.querySelector('my-start-tag')
})
.start();
// Async startup pattern (recommended)
const app = Aurelia
.register(
RouterConfiguration.customize({ useUrlFragmentHash: false })
)
.app(MyRootComponent);
await app.start();
Verbose Startup
The verbose approach gives you complete control over the DI container and configuration. Use this when integrating Aurelia into existing applications or when you need fine-grained control.
import { Aurelia, StandardConfiguration } from '@aurelia/runtime-html';
import { RouterConfiguration } from '@aurelia/router';
import { LoggerConfiguration, LogLevel } from '@aurelia/kernel';
import { ShellComponent } from './shell';
// Create Aurelia instance with explicit configuration
const au = new Aurelia();
au.register(
StandardConfiguration, // Essential runtime configuration
RouterConfiguration.customize({ useUrlFragmentHash: false }),
LoggerConfiguration.create({ level: LogLevel.debug })
);
au.app({
host: document.querySelector('body'),
component: ShellComponent
});
// Always await start() for proper error handling
await au.start();
When to use verbose startup:
Integrating Aurelia into existing applications
Custom DI container configuration needed
Multiple Aurelia apps in one page
Advanced debugging or testing scenarios
StandardConfiguration includes essential services like:
Template compiler and renderer
Binding engine and observers
Custom element/attribute support
Built-in value converters and binding behaviors
DOM event handling and delegation
Shadow DOM and CSS module support
Registering Global Resources
Registering a single custom element
To make a custom element globally available throughout your application, register it before calling app()
.
import Aurelia from 'aurelia';
import { CardCustomElement } from './components/card';
// Quick startup
Aurelia
.register(CardCustomElement) // No type casting needed
.app(MyRootComponent)
.start();
// Verbose startup
const au = new Aurelia();
au.register(
StandardConfiguration,
CardCustomElement
);
au.app({ host: document.body, component: MyRootComponent });
await au.start();
Registering multiple resources
Group related components into resource modules for better organization.
src/components/index.ts:
export { CardCustomElement } from './card';
export { CollapseCustomElement } from './collapse';
export { ModalCustomElement } from './modal';
src/main.ts:
import Aurelia from 'aurelia';
import * as GlobalComponents from './components';
// Register all exported components at once
Aurelia
.register(GlobalComponents)
.app(MyRootComponent)
.start();
Registering other resource types
import Aurelia from 'aurelia';
import { MyValueConverter } from './converters/my-value-converter';
import { MyBindingBehavior } from './behaviors/my-binding-behavior';
import { MyCustomAttribute } from './attributes/my-custom-attribute';
Aurelia
.register(
MyValueConverter,
MyBindingBehavior,
MyCustomAttribute
)
.app(MyRootComponent)
.start();
Advanced Configuration
Custom DI registrations
import { Registration } from '@aurelia/kernel';
import { MyService, IMyService } from './services/my-service';
Aurelia
.register(
Registration.singleton(IMyService, MyService)
)
.app(MyRootComponent)
.start();
Environment-specific configuration
import Aurelia, { LoggerConfiguration, LogLevel } from 'aurelia';
const isProduction = process.env.NODE_ENV === 'production';
Aurelia
.register(
LoggerConfiguration.create({
level: isProduction ? LogLevel.warn : LogLevel.debug
})
)
.app(MyRootComponent)
.start();
Enhancement Mode
Sometimes you need Aurelia to light up markup that already exists in the DOM. Instead of calling app()
, reach for Aurelia.enhance
:
const enhanceRoot = await Aurelia.enhance({
host: document.querySelector('#existing-content'),
component: { message: 'Hello from enhanced content!' }
});
Enhancement is ideal for progressive hydration, CMS integrations, or widgets embedded in non-Aurelia pages. You can register resources before enhancing, provide a custom DI container, and tear down the enhanced view by calling enhanceRoot.deactivate()
when you’re done.
For a full guide, including cleanup patterns, lifecycle hooks, and advanced recipes, see the dedicated Enhance article.
Next steps
Continue with Enhance for progressive integration scenarios.
Wire services using dependency injection once your shell is running.
Explore choosing a router to add navigation after the app is bootstrapped.
Last updated
Was this helpful?