Skip to content

Factory

The Factory pattern encapsulates complex object creation logic behind simple functions. Callers provide minimal configuration and receive ready-to-use instances without knowing initialization details.

This is the dominant pattern in granit-front — every package exposes at least one factory.

graph LR
    Config["Config object"] --> Factory["createXxx()"]
    Factory --> Instance["Ready-to-use instance"]
FactoryPackageCreates
createLogger(prefix, options?)@granit/loggerLogger with configured transports
createApiClient(config)@granit/api-clientAxios instance with Bearer interceptor
createAuthContext<T>()@granit/react-authenticationGeneric, type-safe auth context + hook
createLocalization(config?)@granit/localizationIsolated i18next instance
createReactLocalization(config?)@granit/react-localizationi18next with initReactI18next plugin
createSignalRTransport(config)@granit/notifications-signalrSignalR notification transport
createSseTransport(config)@granit/notifications-sseSSE notification transport
createKlaroCookieConsentProvider(options)@granit/cookies-klaroKlaro CMP adapter
createStorage<T>(key, options?)@granit/storageTyped localStorage/sessionStorage accessor
createMockProvider<T>()@granit/react-authenticationTest provider using same context

Factory functions keep the public API surface minimal while hiding initialization complexity (transport wiring, plugin injection, default configuration). They also enable tree-shaking — unused factories are eliminated at build time.

import { createLogger } from '@granit/logger';
import { createApiClient } from '@granit/api-client';
import { createAuthContext } from '@granit/react-authentication';
import type { BaseAuthContextType } from '@granit/authentication';
// Logger with console transport
const logger = createLogger('app');
// HTTP client with automatic Bearer injection
const api = createApiClient({ baseURL: import.meta.env.VITE_API_URL });
// Typed auth context for the application
interface AuthContextType extends BaseAuthContextType {
register: () => void;
}
export const { AuthContext, useAuth } = createAuthContext<AuthContextType>();