Skip to content

defineUtility

defineUtility allows you to create type-safe utility functions that work with specific Astro integration hooks. It uses currying to provide proper TypeScript types based on the hook you’re targeting.

defineUtility uses a curried function pattern:

package/src/utilities/inject-dev-route.ts
import type { InjectedRoute } from "astro";
import { defineUtility } from "astro-integration-kit";
export const injectDevRoute = defineUtility("astro:config:setup")(
({ command, injectRoute }, injectedRoute: InjectedRoute) => {
if (command === "dev") {
injectRoute(injectedRoute);
}
},
);
  • First call: Takes the hook name (e.g., "astro:config:setup") to establish TypeScript types
  • Second call: Takes your implementation function that receives:
    • Hook parameters as the first argument (fully typed based on the hook)
    • Any additional custom parameters you define
  • Result: A type-safe utility function ready to use in integrations

Use defineUtility when you want to:

  • Ensure type safety: Get proper TypeScript types for Astro hook parameters without manual typing
  • Abstract common patterns: Simplify repetitive integration tasks into easy-to-use functions
  • Create focused utilities: Build specific utility functions for your integration’s needs

Even though the syntax looks a bit scary, it’s actually very simple!

  1. Call defineUtility with a hook name. That will be used to type the next steps:

    import { defineUtility } from "astro-integration-kit";
    export const injectDevRoute = defineUtility("astro:config:setup")
  2. Using currying, call the returned function with the typed params:

    import { defineUtility } from "astro-integration-kit";
    export const injectDevRoute = defineUtility("astro:config:setup")(
    // Typed as HookParameters<"astro:config:setup">
    (params) => {}
    )
  3. (Optional) Add your own parameters:

    import type { InjectedRoute } from "astro";
    import { defineUtility } from "astro-integration-kit";
    export const injectDevRoute = defineUtility("astro:config:setup")(
    (params, injectedRoute: InjectedRoute) => {}
    )
  4. Implement the actual logic:

    import type { InjectedRoute } from "astro";
    import { defineUtility } from "astro-integration-kit";
    export const injectDevRoute = defineUtility("astro:config:setup")(
    ({ command, injectRoute }, injectedRoute: InjectedRoute) => {
    if (command === "dev") {
    injectRoute(injectedRoute);
    }
    },
    );
  5. Use the utility in your integration:

    import { defineIntegration, createResolver, injectDevRoute } from "astro-integration-kit"
    export const integration = defineIntegration({
    name: "my-integration",
    setup() {
    const { resolve } = createResolver(import.meta.url)
    return {
    hooks: {
    "astro:config:setup": (params) => {
    injectDevRoute(params, {
    pattern: "/",
    entrypoint: resolve("./pages/index.astro")
    })
    }
    }
    }
    }
    })