@slop-ai/tanstack-start
@slop-ai/tanstack-start bridges a server-owned provider and a browser-owned UI provider into one public SLOP surface.
bun add @slop-ai/server @slop-ai/tanstack-startClient-side exports
Section titled “Client-side exports”useSlopUI()
Section titled “useSlopUI()”Call this once in your root layout to bootstrap the browser-side UI provider and route metadata.
useSlop(path, descriptor)
Section titled “useSlop(path, descriptor)”Use this inside route components to expose page-local UI state under the mounted ui subtree.
createSlopMiddleware(id?)
Section titled “createSlopMiddleware(id?)”Use this in TanStack Start server functions to refresh the provider automatically after mutations.
Server-side exports
Section titled “Server-side exports”Import these from @slop-ai/tanstack-start/server:
createSlopServer()— singleton-safe server instance (survives Vite module env duplication)sharedState()— development-time state that survives Vite module reloadscreateSlopRefreshFn()— middleware callback that refreshes the tree and mounted UI after mutationscreateWebSocketHandler()— h3/CrossWS handler for both consumer and provider connectionsslopVitePlugin()— Vite plugin that attaches the WebSocket endpointWebSocketServer— re-exported fromwsfor convenience
UI mount internals
Section titled “UI mount internals”These are used by createWebSocketHandler internally but can be imported for advanced use cases:
registerUiMountSession(slop, mountPath, session)— register a mount session, replacing any existing one at the same pathunregisterUiMountSession(slop, mountPath, session)— remove a mount sessionrefreshMountedUi(slop, options?)— invoke__adapter.refreshon all mounted browser sessions. Pass{ skipPath }to skip sessions whose mount path matches the invoke source (prevents circular refresh)
Architecture
Section titled “Architecture”- the public provider stays on the server
- browser UI state connects back over a hidden socket
- the server mounts that UI tree under
ui - consumers only need to connect to one provider