Quick start

This walkthrough creates one shared dependency, one transient service, and one lazy singleton accessor.

1. Register the build plugin

For Vite, add the Compdi plugin before writing any macros:

vite.config.ts
import { defineConfig } from "vite";
import compdi from "compdi/plugin/vite";

export default defineConfig({
  plugins: [compdi()],
});

2. Define dependencies

src/dependencies.ts
import {
  createSingleton,
  createTransient,
  defineSingleton,
} from "compdi/macros";

class Database {
  query(sql: string) {
    return `Result for: ${sql}`;
  }
}

class UserService {
  constructor(private readonly database: Database) {}

  findAll() {
    return this.database.query("SELECT * FROM users");
  }
}

class Analytics {
  constructor(private readonly database: Database) {}
}

// Constructed once during module evaluation.
export const database = createSingleton({ target: Database });

// A new service is constructed on every call.
export const createUserService = createTransient({
  target: UserService,
  deps: [database],
});

// Constructed on the first accessor call, then shared.
export const useAnalytics = defineSingleton({
  target: Analytics,
  deps: [database],
  lazy: true,
});

3. Use the graph

src/main.ts
import { createUserService, useAnalytics } from "./dependencies";

const users = createUserService();
const analytics = useAnalytics();

There is no container to initialize or query. The plugin replaces these macros with the corresponding constructors, factories, cached values, and accessors.

If a Compdi macro reaches runtime, it throws. This normally means the build plugin is missing or its include option excludes the source file.

Next steps