Application
An ARDOR application pairs a BaseArdorApplication inversion-of-control container with an <ArdorApplication /> React root component that mounts react-admin. To start the application, extend BaseArdorApplication, call await application.start(), and pass the container to <ArdorApplication />.
Create src/application.ts:
import 'reflect-metadata';
import AutoArtifacts from '@venizia/ignis-boot/auto';
import { BaseArdorApplication, type IApplicationInfo, type IArtifactIndex } from '@venizia/ardor';
// The decorated classes live in their own files and this module imports none of them: the build lists
// every one under src/ in `AutoArtifacts`, and importing it here keeps the list out of any shared kit.
export class Application extends BaseArdorApplication {
getAppInfo(): IApplicationInfo {
return { name: 'quickstart', version: '0.0.0', description: 'ARDOR 5-minute quickstart' };
}
override artifacts(): Array<IArtifactIndex> {
return [AutoArtifacts];
}
bindContext(): void {}
}Create src/main.tsx:
import 'reflect-metadata';
import { configureStore } from '@reduxjs/toolkit';
import { ArdorApplication } from '@venizia/ardor';
import { createRoot } from 'react-dom/client';
import { ListBase } from 'ra-core';
import { Application } from '@/application';
import { LoginPage } from '@/pages/login';
import { ProductList } from '@/pages/product-list';
const application = new Application();
const store = configureStore({
reducer: { quickstart: (state: { ready: boolean } = { ready: true }) => state },
});
// `resource.list` is what react-admin renders for `/products`; `ListBase` runs the data provider.
const ProductsPage = () => (
<ListBase resource="products" perPage={10}>
<ProductList />
</ListBase>
);
await application.start();
createRoot(document.getElementById('root')!).render(
<ArdorApplication
container={application}
reduxStore={store}
suspense={<p>Loading</p>}
loginPage={LoginPage}
resources={[{ name: 'products', list: ProductsPage }]}
/>,
);NOTE
For the complete API contract and method signatures, see the Application Reference.
BaseArdorApplication
BaseArdorApplication (in packages/kernel/src/base/applications/abstract.ts) extends AbstractArdorApplication, which extends the IGNIS Container. The application instance is the container; call this.bind(...) and this.get(...) directly on it.
Subclasses implement two abstract methods:
getAppInfo(): Returns anIApplicationInfoobject containingname,version, anddescription.preConfigure()binds this metadata underCoreBindings.APPLICATION_INFO. Return the object, or a promise of it:preConfigure()waits for a promise before it binds the rest.bindContext(): Hook for registering container bindings by hand (such asthis.service(),this.repository(),this.dataSource(),this.component(), orthis.bind()). Bindings placed here override any binding declared by a configuration class or stereotype decorator.
The start() Lifecycle
The start() method in packages/kernel/src/base/applications/abstract.ts awaits three steps in order:
resolveArtifactIndexes(): Evaluatesthis.artifacts(). Plain artifact indexes or pre-inlined groups (fromIgnisArtifactsPlugin) are kept as-is. Dynamic groups with aresolve()function (such asAutoArtifactsfrom@venizia/ignis-boot/auto) haveresolve()awaited to import modules and trigger decorators. Stored inthis.resolvedIndexesfor verification.preConfigure(): Directly bindsCoreBindings.APPLICATION_INSTANCE,CoreBindings.APPLICATION_INFO, andCoreBindings.FEATURES. It runs stereotypes and@providemethods, features,bindingList(), andbindContext(). For details, see The bind order.postConfigure(): Runs afterpreConfigure()andbindContext()complete. Defaults to an empty function inBaseArdorApplication; override it for post-startup logic like cache warmups or runtime checks.
ArdorApplication on Render
ArdorApplication (in packages/admin/src/components/application.tsx) connects the IGNIS container to React. When rendered, it executes the following steps:
- Reads features: When the
featuresprop is absent, callsFeatures.read({ container })to retrieve features bound underCoreBindings.FEATURES. The prop replaces that read. - Mounts resources and routes: Calls
Features.mount({ features, resources, routes })inpackages/admin/src/features/feature.ts. Application resources and routes mount first, then each feature's in order. Duplicate resource names throw[features] Resource '<name>' is mounted by both ... | A resource name is unique within an application. - Resolves default providers: Resolves framework providers from the container via
container.get():CoreBindings.DEFAULT_REST_DATA_PROVIDER: RequiredIDataProvider.CoreBindings.DEFAULT_AUTH_PROVIDER: OptionalIAuthProvider(isOptional: true). If unbound,ArdorApplicationomitsauthProvider, running react-admin without sign-in so every page is public.CoreBindings.DEFAULT_I18N_PROVIDER: RequiredI18nProvider.
- Verifies internationalization readiness: Calls
useFeatureMessagesReady. If a feature supplies lazy translation loaders for the active locale, triggersi18nProvider.changeLocale()and renders thesuspensefallback until ready. - Wraps the component hierarchy:
ApplicationContext.Providerwith{ container, logger }(theloggerprop, else a console logger named after the application).ReduxProviderwithreduxStore, only when the prop is passed.React.Suspensewithsuspense.
- Renders CoreAdmin: Passes providers and forwarded props, mounting resources as
<Resource key={resource.name} {...resource} />and routes inside<CustomRoutes>as<Route key={route.id ?? route.path} {...route} />.
Application Props
ArdorApplication accepts IApplication props (in packages/admin/src/common/types.ts), extending CoreAdminProps (omitting children). Each prop, with its type and whether it is required, is in the Application reference.
Next Steps
- Learn how configuration classes bind options and providers: Configuration
- Configure framework providers: Providers
- Register resource definitions and custom pages: Resources and Pages
- Explore dependency injection with hooks and services: Dependency Injection