This reference summarizes the supported package exports, runtime contracts, and deployment-facing conventions that back the canonical FaceTheory docs set.
Package:
@theory-cloud/facetheoryfrom the versioned GitHub release asset shown below
Runtime:
- Node.js
>=24
Primary package exports are defined in ts/package.json. The repository also includes a local SSG CLI entrypoint used by npm run ssg.
Install the exact release asset before wiring one of the adapter surfaces into your application:
export FACETHEORY_VERSION=0.3.1 # x-release-please-version
npm install --save-exact \
"https://github.com/theory-cloud/FaceTheory/releases/download/v${FACETHEORY_VERSION}/theory-cloud-facetheory-${FACETHEORY_VERSION}.tgz"Adapter peers:
- React routes require
reactandreact-dom - React + AntD/Emotion integrations additionally require
antd,@emotion/react,@emotion/cache, and@emotion/server - Vue routes require
vueand@vue/server-renderer - Svelte routes require
svelte
Use this table as the public entrypoint map for package consumers. It reflects the exports declared in ts/package.json and the corresponding source modules.
| Export | Surface | Primary interfaces |
|---|---|---|
@theory-cloud/facetheory |
Core runtime | createFaceApp, FaceApp, FaceModule, FaceMode, FaceRequest, FaceResponse, FaceRenderResult, buildSsgSite, createLambdaUrlStreamingHandler, S3HtmlStore, InMemoryHtmlStore, InMemoryIsrMetaStore, blockingIsrCacheControl, viteAssetsForEntry, viteHydrationForEntry, createCspNonce, readFaceHydrationData, parseFaceNavigationSnapshot, fetchFaceNavigationSnapshot, applyFaceNavigationSnapshot, loadFaceNavigationModule, startFaceNavigation |
@theory-cloud/facetheory/apptheory |
AppTheory adapter | createAppTheoryFaceHandler, appTheoryContextToFaceRequest, faceResponseToAppTheoryResponse |
@theory-cloud/facetheory/aws-s3 |
AWS SDK S3 adapter | createAwsSdkS3HtmlStoreClient |
@theory-cloud/facetheory/react |
React adapter | renderReact, renderReactStream, createReactFace, createReactStreamFace |
@theory-cloud/facetheory/react/antd |
Ant Design integration | createAntdIntegration |
@theory-cloud/facetheory/react/emotion |
Emotion integration | createEmotionIntegration |
@theory-cloud/facetheory/react/antd-emotion |
AntD token bridge | createAntdEmotionTokenIntegration |
@theory-cloud/facetheory/vue |
Vue adapter | renderVue, createVueFace, h |
@theory-cloud/facetheory/svelte |
Svelte adapter | renderSvelte, createSvelteFace |
@theory-cloud/facetheory/tabletheory |
TableTheory ISR adapter | TableTheoryIsrMetaStoreAdapter, createTableTheoryIsrMetaStore |
These contracts shape every adapter and delivery mode. If you change one of these interfaces, update the canonical docs in the same change.
| Interface | Purpose | Notes |
|---|---|---|
FaceModule |
Route definition | Uses route, mode, optional load, optional generateStaticParams, and render. |
FaceMode |
Rendering mode | One of ssr, ssg, or isr. |
FaceRequest |
Normalized request input | Supports headers, cookies, query, body, base64 marker, and optional cspNonce. |
FaceResponse |
Runtime response | Includes normalized headers, cookies array, status, body, and isBase64. |
FaceRenderResult |
Render output before HTTP conversion | Supports document-shell attrs (lang, htmlAttrs, bodyAttrs), head, headTags, styleTags, html, cookies, headers, and hydration payload. |
FaceContext |
Per-request context | Exposes normalized request, route params, and proxy match. |
FaceAppOptions |
App constructor options | Accepts faces, optional ISR config, and optional observability hooks. |
FaceIsrOptions |
ISR runtime tuning | Configures HTML store, metadata store, lease timing, contention policy, cache key, tenant key, and cache-control generation. |
These examples show the shortest supported path from route definitions to a deployable handler.
import { createFaceApp, type FaceModule } from "@theory-cloud/facetheory";
const faces: FaceModule[] = [
{
route: "/",
mode: "ssr",
render: async () => ({ html: "<h1>Hello FaceTheory</h1>" }),
},
];
const app = createFaceApp({ faces });import {
createFaceApp,
createLambdaUrlStreamingHandler,
} from "@theory-cloud/facetheory";
const app = createFaceApp({ faces });
export const handler = createLambdaUrlStreamingHandler({ app });Runtime note:
createLambdaUrlStreamingHandler()expects Lambda'sawslambda.streamifyResponseglobal unless you pass the optionalawslambdaadapter explicitly- Local tests can call
handleLambdaUrlEvent(app, event)without the Lambda global
import {
createApp,
createLambdaFunctionURLStreamingHandler,
} from "@theory-cloud/apptheory";
import { createFaceApp } from "@theory-cloud/facetheory";
import { createAppTheoryFaceHandler } from "@theory-cloud/facetheory/apptheory";
const app = createApp();
const faceApp = createFaceApp({ faces });
const faceHandler = createAppTheoryFaceHandler({ app: faceApp });
app.get("/", faceHandler);
app.get("/{proxy+}", faceHandler);
export const handler = createLambdaFunctionURLStreamingHandler(app);Each adapter keeps the same FaceModule contract while translating framework-specific rendering details into a shared runtime output.
React:
createReactFace()for buffered SSRcreateReactStreamFace()for streaming SSRrenderReactStream(..., { styleStrategy: 'all-ready' | 'shell' })- Integrations compose through
wrapTree,contribute, andfinalize
Vue:
createVueFace()wraps aVNoderender function into aFaceModulerenderVue()supports integration hooks pluswrapApp
Svelte:
createSvelteFace()wraps aSvelteRenderInputrenderSvelte()supports legacyComponent.render()and Svelte 5 server rendering- Packaged Svelte libraries should import their CSS from the client entry and use
viteAssetsForEntry()+viteHydrationForEntry()to keep SSR asset tags and hydration aligned
Blocking ISR separates HTML object storage from metadata and lease coordination. Keep both sides configured explicitly in production.
HTML storage:
InMemoryHtmlStoreS3HtmlStorecreateAwsSdkS3HtmlStoreClient({ s3 })
Metadata and lease storage:
InMemoryIsrMetaStorecreateTableTheoryIsrMetaStore({ config })TableTheoryIsrMetaStoreAdapter
Relevant helpers:
defaultIsrCacheKey(input)blockingIsrCacheControl(input)isFresh(record, nowMs)
Important deployment note:
S3HtmlStore.keyPrefixis a physical S3 prefixhtmlPointerPrefixinFaceIsrOptionsis a logical prefix embedded in stored pointers- Do not set both to the same non-empty value unless you intentionally want duplicated path segments
Use these helpers when a Vite SSR build needs deterministic asset tags and a matching hydration bootstrap module.
| Helper | Purpose |
|---|---|
viteAssetsForEntry(manifest, entry, options) |
Produces deterministic modulepreload, stylesheet, and optional asset hint tags. |
viteHydrationForEntry(manifest, entry, data, options) |
Produces a FaceHydration payload using the manifest bootstrap module. |
viteDynamicImportPolicy() |
Returns the current dynamic import policy, which is ignore. |
Current behavior:
dynamicImportsfrom Vite manifests are intentionally ignoredincludeAssets: trueadds preload or prefetch hints for manifest asset files
FaceTheory now exposes browser-side helpers for SPA-style navigation between FaceModule routes without a full document reload.
Core helpers:
readFaceHydrationData(document?)reads the__FACETHEORY_DATA__payload from the current documentparseFaceNavigationSnapshot(html, options)converts a rendered FaceTheory document into a structured navigation snapshotfetchFaceNavigationSnapshot(url, options)fetches and parses the next route as HTMLapplyFaceNavigationSnapshot(snapshot, options)syncs document attrs, non-executable head tags, and either the configured view container or the full bodyloadFaceNavigationModule(snapshot, options)invokes an exportedhydrateFaceNavigation(...)hook when present, or reloads the bootstrap module when the hook is absentstartFaceNavigation(options)intercepts same-origin links, fetches the next FaceTheory document, applies it, and triggers hydration
Recommended host pattern:
- wrap route content in a stable shell with a view container such as
data-facetheory-view - export
hydrateFaceNavigation(context)from the client bootstrap module when you need persistent app state across navigations - rely on the default module reload only as a compatibility fallback for existing entry modules that hydrate by top-level side effect
FaceRenderResult can set document-level attrs directly:
return {
lang: "ar",
htmlAttrs: { dir: "rtl", "data-theme": "midnight" },
bodyAttrs: { class: "app-shell", "data-density": "compact" },
html: '<div id="root">...</div>',
};Semantics:
langwrites the emitted<html lang="...">valuehtmlAttrsandbodyAttrsare escaped and serialized like head attrs- attrs are emitted in sorted key order for deterministic output
- explicit
langoverrideshtmlAttrs.lang - if neither surface sets
lang, FaceTheory still emitslang="en" - buffered and streaming document paths use the same merge rules
Observability is optional, but the hook surface is part of the public runtime contract for request timing and correlation.
createFaceApp({ observability }) supports:
observability.log(record)forfacetheory.request.completedobservability.metric(record)for request and render timing metricsobservability.now()to override the clock used for durations
React streaming also exposes onReadiness for shell and all-ready timing events.
The repository-local CLI is the supported way to exercise SSG from this workspace. Published package consumers should use buildSsgSite() directly unless a separate CLI is introduced later.
The package does not publish ssg-cli.ts as a package export. In this repository, use:
cd ts
npm run ssg -- --entry ./examples/ssg-basic/faces.ts --out ./tmp-ssgSupported flags:
--entry <module>--out <dir>--trailing-slash always|never--allow-network--emit-hydration-data
buildSsgSite() uses the same contract programmatically.
These variables come from the reference AWS stacks and describe the expected runtime wiring around assets and ISR storage. They are conventions for the documented deployment shape, not mandatory inputs for every local app.
The recommended CloudFront and CDK examples use these runtime conventions:
| Variable | Purpose |
|---|---|
APPTHEORY_ASSETS_BUCKET |
S3 bucket containing static assets |
APPTHEORY_ASSETS_PREFIX |
Asset prefix under that bucket |
APPTHEORY_ASSETS_MANIFEST_KEY |
Vite manifest object key |
FACETHEORY_ISR_BUCKET |
S3 bucket used for ISR HTML objects |
FACETHEORY_ISR_PREFIX |
S3 prefix for ISR HTML objects |
APPTHEORY_CACHE_TABLE_NAME |
AppTheory-wired cache metadata table alias |
FACETHEORY_CACHE_TABLE_NAME |
FaceTheory cache metadata table alias |
CACHE_TABLE_NAME |
Compatibility alias for metadata table |
CACHE_TABLE |
Compatibility alias for metadata table |
These are deployment conventions from the reference stacks, not required inputs for every local runtime.
Use the surrounding docs set for task-oriented setup, verification, and deployment guidance.