workleap-squide
SKILL.md
Squide Framework
Squide is a React modular application shell. Use only documented APIs.
Core Concepts
Runtime
The FireflyRuntime instance is the backbone of a Squide application. Never instantiate directly - use initializeFirefly().
Modular Registration
Modules register routes, navigation items, and MSW handlers via a registration function. Each module contributes its own configuration, assembled by the host at bootstrapping.
Public vs Protected Routes
- Routes default to
protected(rendered underProtectedRoutesplaceholder) - Use
registerPublicRoute()for public routes (rendered underPublicRoutesplaceholder) - Public routes only fetch public global data; protected routes fetch both public and protected data
Deferred Registrations
Navigation items dependent on remote data or feature flags use two-phase registration:
- First phase: Register static routes and navigation items
- Second phase: Return a function from registration to defer navigation items
Quick Reference
Host Application Setup
// host/src/index.tsx
import { createRoot } from "react-dom/client";
import { FireflyProvider, initializeFirefly } from "@squide/firefly";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { App } from "./App.tsx";
import { registerHost } from "./register.tsx";
const runtime = initializeFirefly({
localModules: [registerHost]
});
const queryClient = new QueryClient();
const root = createRoot(document.getElementById("root")!);
root.render(
<FireflyProvider runtime={runtime}>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</FireflyProvider>
);
// host/src/App.tsx
import { AppRouter, useIsBootstrapping } from "@squide/firefly";
import { createBrowserRouter, Outlet } from "react-router";
import { RouterProvider } from "react-router/dom";
function BootstrappingRoute() {
if (useIsBootstrapping()) {
return <div>Loading...</div>;
}
return <Outlet />;
}
export function App() {
return (
<AppRouter>
{({ rootRoute, registeredRoutes, routerProviderProps }) => (
<RouterProvider
router={createBrowserRouter([{
element: rootRoute,
children: [{
element: <BootstrappingRoute />,
children: registeredRoutes
}]
}])}
{...routerProviderProps}
/>
)}
</AppRouter>
);
}
// host/src/register.tsx
import { PublicRoutes, ProtectedRoutes, type ModuleRegisterFunction, type FireflyRuntime } from "@squide/firefly";
import { RootLayout } from "./RootLayout.tsx";
export const registerHost: ModuleRegisterFunction<FireflyRuntime> = runtime => {
runtime.registerRoute({
element: <RootLayout />,
children: [PublicRoutes, ProtectedRoutes]
}, { hoist: true });
runtime.registerRoute({ index: true, element: <HomePage /> });
runtime.registerPublicRoute({ path: "*", element: <NotFoundPage /> });
};
Local Module Setup
// local-module/src/register.tsx
import type { ModuleRegisterFunction, FireflyRuntime } from "@squide/firefly";
import { Page } from "./Page.tsx";
export const register: ModuleRegisterFunction<FireflyRuntime> = runtime => {
runtime.registerRoute({
path: "/page",
element: <Page />
});
runtime.registerNavigationItem({
$id: "page",
$label: "Page",
to: "/page"
});
};
Navigation Rendering
import { Link, Outlet } from "react-router";
import {
useNavigationItems, useRenderedNavigationItems, isNavigationLink,
type RenderItemFunction, type RenderSectionFunction
} from "@squide/firefly";
const renderItem: RenderItemFunction = (item, key) => {
if (!isNavigationLink(item)) return null;
const { label, linkProps, additionalProps } = item;
return (
<li key={key}>
<Link {...linkProps} {...additionalProps}>{label}</Link>
</li>
);
};
const renderSection: RenderSectionFunction = (elements, key) => (
<ul key={key}>{elements}</ul>
);
export function RootLayout() {
const navigationItems = useNavigationItems();
const navigationElements = useRenderedNavigationItems(navigationItems, renderItem, renderSection);
return (
<>
<nav>{navigationElements}</nav>
<Outlet />
</>
);
}
Global Data Fetching
// Protected data
import { useProtectedDataQueries, useIsBootstrapping, AppRouter } from "@squide/firefly";
function BootstrappingRoute() {
const [session] = useProtectedDataQueries([{
queryKey: ["/api/session"],
queryFn: async () => {
const response = await fetch("/api/session");
if (!response.ok) throw new ApiError(response.status);
return response.json();
}
}], error => isApiError(error) && error.status === 401);
if (useIsBootstrapping()) return <div>Loading...</div>;
return (
<SessionContext.Provider value={session}>
<Outlet />
</SessionContext.Provider>
);
}
// In App component, set waitForProtectedData
<AppRouter waitForProtectedData>...</AppRouter>
// Public data
const [data] = usePublicDataQueries([{ queryKey: [...], queryFn: ... }]);
<AppRouter waitForPublicData>...</AppRouter>
Deferred Navigation Items
export const register: ModuleRegisterFunction<FireflyRuntime, unknown, DeferredRegistrationData> = runtime => {
// Always register routes
runtime.registerRoute({ path: "/feature", element: <FeaturePage /> });
// Return function for deferred navigation items
return (deferredRuntime, { userData }) => {
if (userData.isAdmin && deferredRuntime.getFeatureFlag("enable-feature")) {
deferredRuntime.registerNavigationItem({
$id: "feature",
$label: "Feature",
to: "/feature"
});
}
};
};
// Execute deferred registrations in BootstrappingRoute
const data = useMemo(() => ({ userData }), [userData]);
useDeferredRegistrations(data);
MSW Request Handlers
export const register: ModuleRegisterFunction<FireflyRuntime> = async runtime => {
if (runtime.isMswEnabled) {
const requestHandlers = (await import("../mocks/handlers.ts")).requestHandlers;
runtime.registerRequestHandlers(requestHandlers);
}
};
Event Bus
// Listen
import { useEventBusListener } from "@squide/firefly";
const handleEvent = useCallback((data, context) => { /* ... */ }, []);
useEventBusListener("event-name", handleEvent);
// Dispatch
import { useEventBusDispatcher } from "@squide/firefly";
const dispatch = useEventBusDispatcher();
dispatch("event-name", payload);
Environment Variables
// Register at initialization
const runtime = initializeFirefly({
environmentVariables: { apiBaseUrl: "https://api.example.com" }
});
// Or register in module
runtime.registerEnvironmentVariable("key", "value");
// Use
import { useEnvironmentVariable } from "@squide/firefly";
const apiUrl = useEnvironmentVariable("apiBaseUrl");
Feature Flags
// Initialize with LaunchDarkly
import { initialize as initializeLaunchDarkly } from "launchdarkly-js-client-sdk";
const ldClient = initializeLaunchDarkly("client-id", { kind: "user", anonymous: true }, { streaming: true });
await ldClient.waitForInitialization(5);
const runtime = initializeFirefly({ launchDarklyClient: ldClient });
// Use
import { useFeatureFlag } from "@squide/firefly";
const isEnabled = useFeatureFlag("feature-key", defaultValue);
Logging
import { useLogger } from "@squide/firefly";
const logger = useLogger();
logger.debug("Message");
Error Boundaries
// Root error boundary (wraps everything)
runtime.registerRoute({
errorElement: <RootErrorBoundary />,
children: [{
element: <RootLayout />,
children: [PublicRoutes, ProtectedRoutes]
}]
}, { hoist: true });
// Module error boundary (isolates module failures)
runtime.registerRoute({
element: <RootLayout />,
children: [{
errorElement: <ModuleErrorBoundary />,
children: [PublicRoutes, ProtectedRoutes]
}]
}, { hoist: true });
API Quick Reference
initializeFirefly Options
mode:"development"|"production"localModules: Array of registration functionscontext: Object passed to registration functionsuseMsw: Enable MSW supportstartMsw: Function to start MSWenvironmentVariables: Initial environment variableshoneycombInstrumentationClient: For tracinglaunchDarklyClient: For feature flagsloggers: Array of logger instancesplugins: Array of plugin factory functionsonError: Error handler for bootstrapping errors
Route Registration Options
hoist: Register at router root (bypasses layouts/auth)parentPath: Nest under route with matchingpathparentId: Nest under route with matching$id
Route Properties
$id: Identifier for nesting$visibility:"public"|"protected"(default)
Navigation Item Properties
$id: Unique identifier (recommended for stable keys)$label: Text or ReactNode$priority: Sorting priority (higher = first)$canRender: Conditional render function$additionalProps: Custom props for rendererto: Route path (supports dynamic segments like/user/:id)style: Inline styles for the navigation itemtarget: Link target (e.g.,"_blank"to open in new tab)
Navigation Registration Options
menuId: Target a specific menu (default:"root")sectionId: Nest under section with matching$id
AppRouter Props
waitForPublicData: Delay until public data readywaitForProtectedData: Delay until protected data ready
Hooks
useNavigationItems(options?): Get navigation itemsuseRenderedNavigationItems(items, renderItem, renderSection): Render nav itemsuseIsBootstrapping(): Check if bootstrappingusePublicDataQueries(queries): Fetch public global datausePublicDataHandler(handler): Execute handler when modules are readyuseProtectedDataQueries(queries, isUnauthorizedError): Fetch protected datauseProtectedDataHandler(handler): Execute handler when modules ready and route is protecteduseDeferredRegistrations(data?, options?): Execute deferred registrations (options:{ onError? })useEventBusListener(event, handler, options?): Listen to eventsuseEventBusDispatcher(): Get dispatch functionuseLogger(): Get logger instanceuseEnvironmentVariable(key): Get env variableuseEnvironmentVariables(): Get all env variablesuseFeatureFlag(key, defaultValue): Get feature flaguseFeatureFlags(): Get all feature flagsuseLaunchDarklyClient(): Get LaunchDarkly client instanceusePlugin(name): Get plugin instanceuseRuntime(): Get runtime instanceuseRuntimeMode(): Get runtime modeuseRoutes(): Get registered routesuseIsRouteProtected(route): Check if a route is protecteduseRouteMatch(locationArg, options?): Match route against location
Helper Functions
isNavigationLink(item): Type guard for navigation linksisGlobalDataQueriesError(error): Type guard for query errorsresolveRouteSegments(path, params): Resolve dynamic segmentsgetFeatureFlag(client, key, defaultValue): Get flag in non-React codemergeDeferredRegistrations(candidates): Merge multiple deferred registration functions
For detailed API documentation, see the references folder.
Weekly Installs
6
Repository
workleap/wl-squideFirst Seen
7 days ago
Installed on
claude-code5
opencode4
windsurf2
trae2
codex2
antigravity2