SuperAPI AI Directory

btst-build-config

Coding & development

View repository

Updated 10-16 05:01

About this skill

BTST Build Configuration

Adding a new export path

Two files must always be updated together:

1. packages/stack/build.config.ts — add to entries array

entries: [
  // existing entries...
  "./src/plugins/{name}/api/index.ts",
  "./src/plugins/{name}/client/index.ts",
  "./src/plugins/{name}/client/hooks/index.tsx",
  "./src/plugins/{name}/client/components/index.tsx",
  "./src/plugins/{name}/query-keys.ts",
]

2. packages/stack/package.json — add exports AND typesVersions

{
  "exports": {
    "./plugins/{name}/client/hooks": {
      "import": "./dist/plugins/{name}/client/hooks/index.mjs",
      "require": "./dist/plugins/{name}/client/hooks/index.cjs"
    }
  },
  "typesVersions": {
    "*": {
      "plugins/{name}/client/hooks": ["./dist/plugins/{name}/client/hooks/index.d.ts"]
    }
  }
}

Both entries are required — missing typesVersions breaks TypeScript consumers even when runtime works.

CSS exports

Plugins with UI components need two CSS files:

  1. src/plugins/{name}/client.css — client-side styles
  2. src/plugins/{name}/style.css — full styles with Tailwind source directives

The postbuild.cjs script auto-discovers and copies them — no manual registration needed. Only add the package.json export entry:

{
  "exports": {
    "./plugins/{name}/css": "./dist/plugins/{name}/client.css"
  }
}

Updating all three codegen projects

When adding a plugin, changing plugin config, or changing a framework entry point, update ALL three generated projects:

Next.js (codegen-projects/nextjs/)

  • lib/stack.ts — backend plugin registration
  • lib/stack-client.tsx — client plugin registration
  • app/pages/client-layout.tsx — shared client provider and overrides
  • app/(request)/pages/layout.tsx — trusted request-origin hydration
  • app/(static)/pages/layout.tsx — header-free SSG/ISR provider wrapper
  • app/globals.css — @import "@btst/stack/plugins/{name}/css";

React Router (codegen-projects/react-router/)

  • app/lib/stack.ts
  • app/lib/stack-client.tsx
  • app/routes/pages/_layout.tsx
  • app/app.css

TanStack (codegen-projects/tanstack/)

  • src/lib/stack.ts
  • src/lib/stack-client.tsx
  • src/routes/pages/route.tsx
  • src/styles.css

Keep generated framework routes on the v3 entry factories:

Framework API route Page route Provider router
Next.js toNextRouteHandlers createNextPage nextRouter()
React Router toReactRouterHandlers createReactRouterPage reactRouter()
TanStack Start toTanStackHandlers createTanStackPageOptions tanstackRouter()

Do not generate hand-written route resolution, loader/meta ordering, dehydration, or 404 plumbing. The entry factories own that behavior.

Generated layouts pass the resolved client stack to StackProvider:

<StackProvider
  stack={clientStack}
  router={frameworkRouter()}
  auth={authProvider}
  overrides={{
    blog: { uploadImage },
  }}
>
  {children}
</StackProvider>

Only plugin-specific values belong in overrides. Never generate Link, Image, navigate, refresh, API paths, identity, or login values inside a built-in plugin override. Configure api, site, and queryClient once in createClientStack(). Resolved client definitions such as Blog and AI Chat accept only plugin-specific options; their loaders and metadata receive shared runtime through the stack resolver.

Override type inference

Resolved definitions contribute their public override type automatically under their canonical programmatic ID (blog, aiChat). Register the definition in createClientStack({ plugins }) and pass that resolved stack to StackProvider; never recreate a manual application override map or provider generic. Do not restore removed framework, API, guard, or identity fields in local intersection types.

Adding shared UI components (@workspace/ui)

Components live in packages/ui/src/components/. Add via shadcn CLI:

cd packages/ui
pnpm dlx shadcn@latest add {component-name}

Import in plugins:

import { Button } from "@workspace/ui/button"
import { MarkdownContent } from "@workspace/ui/markdown-content"

After changes

pnpm build   # rebuild all packages
# If turbo cache is stale:
pnpm turbo clean && pnpm build

Gotchas

  • Missing typesVersions — always add alongside exports; TypeScript won't resolve the new path otherwise.
  • Build cache — run pnpm turbo clean if changes aren't reflected in codegen projects after pnpm build.
  • CSS not loading — ensure "./plugins/{name}/css" entry exists in package.json exports; postbuild.cjs handles the rest automatically.
  • @workspace/ui sub-path components — if a new component imports from a directory (not a single file), add it to EXTERNAL_REGISTRY_COMPONENTS in build-registry.ts.
  • Stale v2 templates — generated routes must use framework entry factories. Generated layouts configure api, site, and queryClient once in createClientStack(), then pass the resolved stack to StackProvider. Only provider-owned services such as router and auth remain alongside the stack prop.