Skip to main content

Function Signature

async function createApp<E extends ExposeSchema = Record<string, never>>(
  options: AppOptions<E>
): Promise<App<InferExpose<E>>>
Creates and initializes a new Resolid application instance with the specified configuration, extensions, and providers.

Type Parameters

E
ExposeSchema
default:"Record<string, never>"
An object schema mapping property names to dependency injection tokens. The exposed schema determines which services are available on the app.$ object.Type definition: Record<string, Token>

Parameters

options
AppOptions<E>
required
Configuration options for the application.
options.name
string
required
The name of the application.
options.debug
boolean
default:"false"
Enable debug mode for the application.
options.timezone
string
default:"UTC"
The timezone for the application. Sets process.env.timezone.
options.extensions
(Extension | ExtensionCreator)[]
Array of extensions or extension creator functions to register with the application.
options.providers
Provider[]
Array of dependency injection providers to register with the application container.
options.expose
E
Schema defining which services to expose on the app.$ object. Keys are property names, values are DI tokens.

Return Type

Promise<App<InferExpose<E>>>
Promise
Returns a Promise that resolves to an initialized App instance. The generic type InferExpose<E> infers the types of exposed services from the schema.The InferExpose utility type transforms the expose schema:
type InferExpose<E extends ExposeSchema> = {
  [K in keyof E]: E[K] extends Token<infer T> ? T : never;
};

Usage Examples

Basic Application

import { createApp } from '@resolid/core';

const app = await createApp({
  name: 'MyApp',
  debug: true,
  timezone: 'America/New_York'
});

await app.run();

With Extensions and Exposed Services

import { createApp, type Token } from '@resolid/core';

const LOGGER = Symbol('LOGGER') as Token<{ log: (msg: string) => void }>;
const DATABASE = Symbol('DATABASE') as Token<{ query: (sql: string) => Promise<any> }>;

const app = await createApp({
  name: 'MyApp',
  extensions: [
    {
      name: 'logging',
      providers: [
        {
          token: LOGGER,
          factory: () => ({ log: (msg) => console.log(msg) })
        }
      ]
    }
  ],
  providers: [
    {
      token: DATABASE,
      factory: () => ({ query: async (sql) => { /* ... */ } })
    }
  ],
  expose: {
    logger: LOGGER,
    db: DATABASE
  }
});

// Access exposed services with full type safety
app.$.logger.log('Application started');
const results = await app.$.db.query('SELECT * FROM users');

await app.run();

With Extension Creator Functions

import { createApp, type ExtensionCreator } from '@resolid/core';

const createMailExtension = (config: { from: string }): ExtensionCreator => {
  return (context) => ({
    name: 'mail-extension',
    providers: [
      {
        token: MAIL_SERVICE,
        factory: () => ({
          send: (to: string, body: string) => {
            console.log(`Sending mail from ${config.from} to ${to}`);
          }
        })
      }
    ],
    bootstrap: async (ctx) => {
      ctx.emitter.on('user:created', (user) => {
        // Send welcome email
      });
    }
  });
};

const app = await createApp({
  name: 'MyApp',
  extensions: [
    createMailExtension({ from: '[email protected]' })
  ]
});

await app.run();

See Also

  • App - The App class returned by createApp
  • Extension - Extension interface and creator types
  • AppContext - Context object passed to extensions

Build docs developers (and LLMs) love