Socket
Book a DemoInstallSign in
Socket

@anansi/core

Package Overview
Dependencies
Maintainers
1
Versions
204
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@anansi/core

React 19 Framework

latest
npmnpm
Version
0.22.3
Version published
Weekly downloads
163
-60.91%
Maintainers
1
Weekly downloads
 
Created
Source

@anansi/core

npm downloads bundle size npm version PRs Welcome

The itsy bitsy spider crawled up the water spout. Down came the rain, and washed the spider out. Out came the sun, and dried up all the rain, and the itsy bitsy spider went up the spout again

React 19 framework with streaming SSR support, built on a composable "spouts" architecture.

Installation

yarn add @anansi/core

Quick Start

Anansi uses a dual-entry pattern for SSR: one entry for the server and one for the client.

yarn start-anansi ./src/index.tsx

This automatically uses ./src/index.tsx for the client and ./src/index.server.tsx for the server.

Concepts

Spouts

Spouts are composable middleware for building React applications. They handle concerns like routing, data fetching, document structure, and more.

  • Server: laySpouts() - Lays out the spouts for SSR, streaming React to the response
  • Client: floodSpouts() - Hydrates the application on the client

The spout pattern allows you to compose functionality in a declarative, nested structure where each spout can:

  • Inject props to downstream spouts
  • Wrap the rendered application with providers
  • Serialize data for hydration

Entry Points

Client Entry (index.tsx)

import { useController } from '@data-client/react';
import {
  floodSpouts,
  documentSpout,
  dataClientSpout,
  routerSpout,
  JSONSpout,
  appSpout,
  navigatorSpout,
} from '@anansi/core';

import App from './App';
import { createRouter } from './routing';

const spouts = documentSpout({ title: 'My App' })(
  JSONSpout()(
    navigatorSpout()(
      dataClientSpout()(
        routerSpout({ useResolveWith: useController, createRouter })(
          appSpout(<App />),
        ),
      ),
    ),
  ),
);

floodSpouts(spouts);

Server Entry (index.server.tsx)

import { useController } from '@data-client/react';
import {
  laySpouts,
  documentSpout,
  dataClientSpout,
  prefetchSpout,
  routerSpout,
  JSONSpout,
  appSpout,
  navigatorSpout,
} from '@anansi/core/server';

import App from './App';
import { createRouter } from './routing';

const spouts = prefetchSpout('controller')(
  documentSpout({ title: 'My App' })(
    JSONSpout()(
      navigatorSpout()(
        dataClientSpout()(
          routerSpout({ useResolveWith: useController, createRouter })(
            appSpout(<App />),
          ),
        ),
      ),
    ),
  ),
);

export default laySpouts(spouts);

Spouts Reference

appSpout

The innermost spout that wraps your React application.

import { appSpout } from '@anansi/core';

appSpout(<App />)

documentSpout

Generates the HTML document structure with proper asset loading.

import { documentSpout } from '@anansi/core';

documentSpout({
  title: 'My App',           // Page title
  head?: ReactNode,          // Additional head elements
  lang?: string,             // HTML lang attribute (default: undefined)
  rootId?: string,           // Root element ID (default: 'anansi-root')
  charSet?: string,          // Character set (default: 'utf-8')
  csPolicy?: CSPolicy,       // Content Security Policy
})

Content Security Policy

The csPolicy option configures CSP headers. In production, it sets Content-Security-Policy; in development, it uses Content-Security-Policy-Report-Only.

const csPolicy = {
  'base-uri': "'self'",
  'object-src': "'none'",
  'script-src': ["'self'", "'unsafe-inline'"],
  'style-src': ["'unsafe-inline'", "'self'"],
};

documentSpout({ title: 'My App', csPolicy })

Nonces are automatically injected into script-src for inline scripts.

routerSpout

Integrates @anansi/router for client-side navigation.

import { routerSpout } from '@anansi/core';

routerSpout({
  useResolveWith: () => any,  // Hook returning data passed to route resolvers
  createRouter: (history) => RouteController,  // Router factory function
  onChange?: (update, callback) => void,  // Client-only: navigation callback
})

Provides to downstream spouts:

  • matchedRoutes - Array of matched route objects
  • router - RouteController instance
  • searchParams - URLSearchParams from the current URL

dataClientSpout

Integrates @data-client/react for data fetching with automatic SSR hydration.

import { dataClientSpout } from '@anansi/core';

dataClientSpout({
  getManagers?: () => Manager[],  // Custom managers (default: [NetworkManager])
})

Server-side, it creates a persisted store and serializes state for hydration. Client-side, it hydrates from the serialized state.

JSONSpout

Serializes data from upstream spouts into <script type="application/json"> tags for hydration.

import { JSONSpout } from '@anansi/core';

JSONSpout({
  id?: string,  // Base ID for script tags (default: 'anansi-json')
})

navigatorSpout

Provides browser navigator-like properties (language preferences) that work on both server and client.

import { navigatorSpout, useNavigator } from '@anansi/core';

// In spouts config
navigatorSpout()

// In components
function MyComponent() {
  const { language, languages } = useNavigator();
  // language: string - Primary language (e.g., 'en-US')
  // languages: readonly string[] - All accepted languages by preference
}

prefetchSpout (Server Only)

Prefetches route data before rendering. Must wrap routerSpout.

import { prefetchSpout } from '@anansi/core/server';

// 'controller' is the field name from dataClientSpout to use for resolving routes
prefetchSpout('controller')(
  // ... other spouts including routerSpout
)

This calls route.resolveData() and route.component.preload() for all matched routes before SSR.

antdSpout (Ant Design)

Integrates Ant Design's CSS-in-JS with SSR support.

// Client
import { antdSpout } from '@anansi/core/antd';

// Server  
import { antdSpout } from '@anansi/core/antd/server';

antdSpout()

Core Functions

laySpouts (Server)

Wraps spouts for server-side rendering with streaming support.

import { laySpouts } from '@anansi/core/server';

export default laySpouts(spouts, {
  timeoutMS?: number,  // SSR timeout (default: 10000)
  onError?: (error) => void,  // Error callback
});

Returns a render function compatible with Express: (clientManifest, req, res) => Promise<void>

floodSpouts (Client)

Hydrates the application on the client.

import { floodSpouts } from '@anansi/core';

floodSpouts(spouts, {
  rootId?: string,  // Root element ID (default: 'anansi-root')
});

CLI Commands

start-anansi

Development server with hot module replacement for both client and server.

yarn start-anansi ./src/index.tsx

Features:

  • Dual webpack compilation (client + server)
  • In-memory filesystem for fast rebuilds
  • Hot reloading for both bundles
  • Automatic SSR on all non-asset routes
  • Proxy support from webpack devServer config

serve-anansi

Production server for pre-built applications.

yarn serve-anansi ./dist-server/App.js

Scripts API

For programmatic usage:

import { serve, devServe } from '@anansi/core/scripts';

serve(entry, options?)

Starts a production server.

serve('./dist-server/App.js', {
  serveAssets?: boolean,  // Serve static assets (default: false)
  serveProxy?: boolean,   // Enable proxy from webpack config (default: false)
});

Environment Variables:

  • PORT - Server port (default: 8080)
  • WEBPACK_PUBLIC_PATH - Public path for assets

Options

OptionTypeDescription
serveAssetsbooleanServe static assets from the build output. Useful for local validation; use a dedicated HTTP server in production.
serveProxybooleanEnable proxying based on webpack devServer config. Useful for local validation; use a reverse proxy in production.

devServe(entry, env?)

Starts a development server with HMR.

devServe('./src/index.tsx', {
  // Additional env variables passed to webpack config
});

Types

ServerProps

Props available to server-side spouts:

interface ServerProps {
  req: Request | IncomingMessage;
  res: Response | ServerResponse;
  clientManifest: StatsCompilation;
  nonce: string;
}

Spout Types

import type { Spout, ServerProps, NavigatorProperties } from '@anansi/core';

CSPolicy

Content Security Policy configuration:

interface CSPolicy {
  [directive: string]: string | string[];
}

Exports

@anansi/core

Client-side exports:

  • floodSpouts - Hydrate the application
  • documentSpout - Document structure
  • dataClientSpout - Data Client integration
  • routerSpout - Router integration
  • JSONSpout - JSON serialization for hydration
  • appSpout - Application wrapper
  • navigatorSpout - Navigator properties
  • useNavigator - Hook for navigator properties

@anansi/core/server

Server-side exports (all client exports plus):

  • laySpouts - SSR render function
  • prefetchSpout - Route data prefetching
  • CSPolicy - CSP type

@anansi/core/scripts

Build/dev scripts:

  • serve - Production server
  • devServe - Development server

@anansi/core/antd

Ant Design integration (client-side).

@anansi/core/antd/server

Ant Design integration (server-side).

Keywords

ssr

FAQs

Package last updated on 02 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts