Core API
createSurf
Create a new Surf instance
createSurf(config)#
Creates a new Surf instance. The config object defines your service name, commands, auth, events, and behavior.
import { createSurf } from '@surfjs/core' const surf = await createSurf({ name: 'My Service', description: 'A Surf-enabled API', version: '1.0.0', commands: { /* ... */ }, events: { /* ... */ }, authVerifier: myVerifier, rateLimit: { windowMs: 60_000, maxRequests: 100 }, strict: true,}) // Returns a SurfInstance with:surf.manifest() // Get the generated manifestsurf.manifestForToken(tok) // Get manifest for a specific auth token (shows hidden commands if valid)surf.manifestHandler() // HTTP handler for /.well-known/surf.jsonsurf.httpHandler() // HTTP handler for /surf/executesurf.middleware() // Combined HTTP middleware (manifest + execute + sessions + pipeline)surf.wsHandler(server) // Attach WebSocket transport (requires 'ws' package)surf.browserScript() // Generate a browser-injectable scriptsurf.browserBridge() // Generate a window bridge for browser executionsurf.emit(event, data) // Emit an event to connected clientssurf.use(middleware) // Add a middleware functionsurf.live // Surf Live API (setState, patchState, getState, emit)surf.events // Access the EventBussurf.sessions // Access the SessionStoresurf.commands // Access the CommandRegistrySurfConfig — Full options
| Option | Type | Description |
|--------|------|-------------|
| name | string | Service name (shown in manifest and badges) |
| description | string? | Short description |
| version | string? | Your API version string |
| commands | CommandGroup | Command definitions (nested groups supported) |
| events | Record<string, EventDefinition>? | Event definitions for Surf Live |
| channels | Record<string, ChannelDefinition>? | Channel definitions for Surf Live |
| about | string? | Longer context about your site for agents |
| baseUrl | string? | Base URL for the API (included in manifest) |
| auth | AuthConfig? | Auth type advertised in manifest (none, bearer, apiKey, oauth2) |
| authVerifier | AuthVerifier? | Function to verify tokens — called for required/optional/hidden commands |
| rateLimit | RateLimitConfig? | Global rate limiting |
| sessionRateLimit | RateLimitConfig? | Rate limit for session creation (POST /surf/session/start). Defaults to 10 req/60s per IP when rateLimit is set |
| cors | CorsConfig? | CORS configuration — origin string/array/function, credentials, custom headers. Omit or set origin: '*' for default wildcard |
| strictParams | boolean? | Reject requests that include params not defined in the command schema |
| strict | boolean? | Enable validateReturns, strictParams, and other strict checks |
| validateReturns | boolean? | Validate command return values against returns schema |
| debug | boolean? | Include internal error details in responses (dev only) |
| middleware | SurfMiddleware[]? | Global middleware applied to all commands |
| live | LiveConfig? | Surf Live config (WebSocket broadcast settings) |
Advanced Utilities#
InMemorySessionStore
The default session store — an in-memory map of sessionId → Session. For production or multi-replica deployments, implement the SessionStore interface:
import { InMemorySessionStore } from '@surfjs/core'import type { SessionStore, Session } from '@surfjs/core' // The SessionStore interface:interface SessionStore { create(): Promise<Session> get(id: string): Promise<Session | undefined> update(id: string, state: Record<string, unknown>): Promise<void> destroy(id: string): Promise<void>} // InMemorySessionStore is the built-in default — works for single-process dev.// For production, implement SessionStore backed by Redis, a database, etc.generateManifest
Generate a manifest JSON object from a config without creating a full SurfInstance. Useful for testing, CI validation, or manifest pre-generation:
import { generateManifest } from '@surfjs/core' const manifest = await generateManifest({ name: 'My Store', version: '1.0.0', baseUrl: 'https://shop.example.com', commands: { search: { description: 'Search', run: async () => ({}) } },}) // Write to disk, validate schema, publish to CDN, etc.fs.writeFileSync('surf.json', JSON.stringify(manifest, null, 2))generateManifest is async (it computes a SHA-256 checksum via Web Crypto). It accepts the same config shape as createSurf plus optional ManifestOptions (authenticated, updatedAt).
RateLimiter
The built-in sliding window rate limiter. Instantiate it directly for custom rate limiting logic:
import { RateLimiter } from '@surfjs/core' const limiter = new RateLimiter() // In a custom middleware or handler:limiter.check( { windowMs: 60_000, maxRequests: 10, keyBy: 'ip' }, RateLimiter.buildKey('search', config, { ip: ctx.ip }),)// Throws SurfError { code: 'RATE_LIMITED' } if limit exceededSurf uses RateLimiter internally when you set rateLimit on a command or config. Use it directly to share a limiter across multiple services or to apply rate limiting outside of a Surf handler.
EventBus
The event broadcast system backing surf.emit(). Access via surf.events:
// Emit from anywhere in your appsurf.events.emit('cart.updated', { cartId: '123', items: [...] }) // Subscribe to events (useful for server-side consumers)surf.events.on('cart.updated', (data) => { metrics.increment('cart.updates')})The EventBus supports scoped events via channels — see Surf Live for the full broadcast API.