npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@graphcore/frontend

v0.3.3

Published

GraphCore React frontend — EntityRenderer, WebSocket plumbing, and view registry for building GraphCore-powered applications.

Readme

@graphcore/frontend

React 19 GraphCore frontend package with:

  • GraphCoreProvider for auth + GraphCore bridge wiring
  • EntityRenderer for rendering any GraphCore entity
  • self-hosted view widgets like AgentChatView, AgentBuilder, and CanvasView
  • strategy request helpers for all writes
  • entity graph hooks for new custom UI code
  • a stable entity graph read API for package-owned frontend code

Install

npm install @graphcore/frontend

Import the shared stylesheet once:

import '@graphcore/frontend/dist/style.css';

Peer dependencies:

  • react >= 19
  • react-dom >= 19

You do not need to install recoil.

How It Works

The package now uses a lightweight internal entity store.

  • The backend remains the source of truth.
  • Entity updates arrive over GraphCore WebSocket messages and are merged into the store.
  • Custom components should treat the entity store as read-only.
  • All mutations should go through strategy requests.

In practice, there are two recommended ways to build with the package:

  1. Render entities and views using the built-in rendering flow.
  2. Build custom UI on top of the exported entity graph hooks and strategy helpers.

Provider Setup

Wrap your app with GraphCoreProvider:

import { GraphCoreProvider } from '@graphcore/frontend';
import '@graphcore/frontend/dist/style.css';

export function AppRoot() {
  return (
    <GraphCoreProvider
      apiUrl={process.env.GRAPHCORE_API_URL!}
      wsUrl={process.env.GRAPHCORE_WS_URL!}
    >
      <App />
    </GraphCoreProvider>
  );
}

GraphCoreProvider now sets up:

  • GraphCore bridge / WebSocket lifecycle
  • auth state

You should not add your own provider around package components to manage GraphCore transport state.

Props

| Prop | Type | Description | |------|------|-------------| | apiUrl | string | Full API base URL, for example https://api.example.com | | wsUrl | string | WebSocket host:port, for example localhost:8000 | | getToken | () => string \| null | Optional external token injector | | userEntityId | string | Required when using getToken |

Auth Flow

The default flow is:

import { AuthPage, EntityRenderer, useAuth } from '@graphcore/frontend';

export function Shell() {
  const { isAuthenticated, isLoading, userEntityId, logout } = useAuth();

  if (isLoading) return <div>Loading...</div>;
  if (!isAuthenticated) return <AuthPage />;

  return (
    <div className="h-screen">
      <header>
        <button onClick={logout}>Logout</button>
      </header>
      <main className="h-full">
        <EntityRenderer entityId={userEntityId} className="h-full" />
      </main>
    </div>
  );
}

useAuth() is still the main consumer auth API:

  • login(username, password)
  • logout()
  • isAuthenticated
  • isLoading
  • userEntityId

Token Injection

If your host application already owns auth, inject the token:

<GraphCoreProvider
  apiUrl={apiUrl}
  wsUrl={wsUrl}
  getToken={() => externalAuth.getGraphCoreJwt()}
  userEntityId={externalAuth.graphCoreUserEntityId}
>
  <EntityRenderer entityId={externalAuth.graphCoreUserEntityId} />
</GraphCoreProvider>

Flow 1: Render Entities

EntityRenderer is the highest-level rendering primitive.

import { EntityRenderer } from '@graphcore/frontend';

<EntityRenderer entityId={userEntityId} className="h-full" />;
<EntityRenderer entityId={agentId} />;
<EntityRenderer entityId={agentId} viewType="agentbuilder" />;
<EntityRenderer entityId={agentId} showBorder={false} />;

Use this when you want the package to:

  • fetch the entity graph on demand
  • resolve the active view entity
  • dispatch to the registered view component
  • auto-wire strategy requests into package components

Flow 2: Drop In Self-Hosted Views

Many built-in views are exported as self-hosted widgets. These components can be mounted directly with a parentEntityId, and the package will ensure the matching view entity exists.

import { AgentChatView, AgentBuilder, CanvasView } from '@graphcore/frontend';

<AgentChatView parentEntityId={agentId} className="h-full" />
<AgentBuilder parentEntityId={agentId} className="h-full" />
<CanvasView parentEntityId={workspaceId} className="h-full" />

Available pre-wrapped views:

| Export | View type key | |--------|---------------| | AgentChatView | agentchatview | | AgentBuilder | agentbuilder | | ConversationView | conversationview | | KanbanBoardView | kanban_board_view | | KanbanCardView | kanban_card_view | | CanvasView | canvas | | AdvancedDocumentEditor | advanced_document_editor | | AgentWorkspaceView | agentworkspaceview |

Multiple slots under the same parent are supported:

<AgentChatView parentEntityId={agentId} selfHostedSlotKey="primary" />
<AgentChatView parentEntityId={agentId} selfHostedSlotKey="research" />

Build Custom Views

Use withAutoViewEntity when you want the same self-hosted pattern for your own component:

import { withAutoViewEntity } from '@graphcore/frontend';

function MyView(props: { viewEntityId?: string }) {
  return <div>My custom GraphCore view</div>;
}

export const MySelfHostedView = withAutoViewEntity(MyView, 'my_view_type');

Then mount it with either:

  • parentEntityId for self-hosted mode
  • viewEntityId for direct render mode

If you need GraphCore to use your component in normal entity rendering, also register it:

import { registerViewComponent } from '@graphcore/frontend';
import { MyView } from './MyView';

registerViewComponent('my_view_type', MyView);

Writing New Custom Components

For new code, prefer the entity graph hooks exported by the package.

Read Entities

import { useEntity, useChildren, useEntities } from '@graphcore/frontend';

function AgentSummary({ entityId }: { entityId: string }) {
  const entity = useEntity(entityId);
  const children = useChildren(entityId, { types: ['entity_service.ViewEntity'] });
  const loadedChildren = useEntities(entity?.children_ids || []);

  return (
    <div>
      <div>Name: {entity?.name}</div>
      <div>View count: {children.length}</div>
      <div>Loaded child entities: {loadedChildren.filter(Boolean).length}</div>
    </div>
  );
}

Available read APIs:

  • useEntity(id)
  • useEntities(ids)
  • useChildren(parentId, { type, types, enabled })
  • useViewChildren(parentId)
  • useRecursiveChildren(parentId, { types, excludeTypes, includeRoot })
  • entityGraph.readEntity(id)
  • entityGraph.readChildren(parentId, { types, excludeTypes })
  • useBridgeStatus()
  • useGraphCoreBridge()

Send Mutations

All writes should go through strategy requests.

Use the strategy hook:

import { StrategyRequests, useStrategyRequest } from '@graphcore/frontend';

function RenameButton({ entityId }: { entityId: string }) {
  const sendStrategyRequest = useStrategyRequest();

  return (
    <button
      onClick={() =>
        sendStrategyRequest?.(
          StrategyRequests.setAttributes(entityId, { name: 'Updated Name' }),
        )
      }
    >
      Rename
    </button>
  );
}

Or use the compatibility wrapper:

import { useWebSocketConsumer } from '@graphcore/frontend';

const { sendStrategyRequest, isConnected } = useWebSocketConsumer();

useWebSocketConsumer() remains supported, but new code should generally prefer useStrategyRequest() unless you specifically need the compatibility shape.

Await Strategy Results

const sendStrategyRequest = useStrategyRequest();

await sendStrategyRequest?.(
  StrategyRequests.setAttributes(entityId, { name: 'Updated Name' }),
  { awaitResponse: true, timeout: 60000 },
);

Strategy Helpers

StrategyRequests is a static factory object with builders for all common backend operations:

Attributes

  • setAttributes(entityId, attributes, addToHistory?)
  • setFrameworkFields(entityId, frameworkFields, addToHistory?)
  • hideEntity(entityId, hide?)

Entities

  • createEntity(parentEntityId, entityTypeId, initialAttributes?, entityUuid?)
  • deleteEntity(entityId)
  • ensureChildView(parentEntityId, viewComponentType, initialAttributes?, slotKey?)

Children

  • mutateChildren(entityId, operations, addToHistory?)
  • addChildren(entityId, childIds, addToHistory?)
  • removeChildren(entityId, childIds, addToHistory?)
  • moveChildBefore(entityId, childId, beforeChildId, addToHistory?)
  • moveChildAfter(entityId, childId, afterChildId, addToHistory?)

Queries

  • queryEntities(entityId, filters, resultAttributeName, addToHistory?)
  • recurseEntities(targetEntityId, entityTypeIds?, rootEntityId?, addToHistory?)

List operations

  • listOperation(entityId, attributeName, operation, value?, index?, addToHistory?)

Pipeline

  • createNode(pipelineId, initialAttributes?, parentNodeId?)

Templates

  • serializeEntityGraph(targetEntityId, addToHistory?)
  • publishTemplate(targetEntityId, rootEntityId?, addToHistory?, allowMissingPublishedStructure?)
  • repairTemplateDraftFromLatestRelease(targetEntityId, addToHistory?)
  • instantiateSnapshot(targetEntityId, snapshotJson, isManaged?, addToHistory?)
  • applyTemplateUpgrade(targetEntityId, snapshotJson?, addToHistory?)
  • detachTemplateManagement(targetEntityId, addToHistory?)

Other

  • executeChildren(entityId)
  • updateStrategyRequest(entityId, updates, addToHistory?)
  • builder() — returns a raw StrategyRequestBuilder for custom requests

Example:

import { StrategyRequests } from '@graphcore/frontend';

const request = StrategyRequests.addChildren(parentId, childId);

Public API Summary

Main exports:

  • GraphCoreProvider
  • AuthPage
  • useAuth
  • EntityRenderer
  • withAutoViewEntity
  • registerViewComponent
  • AgentChatView
  • AgentBuilder
  • ConversationView
  • KanbanBoardView
  • KanbanCardView
  • CanvasView
  • AdvancedDocumentEditor
  • AgentWorkspaceView
  • useEntity
  • useEntities
  • useChildren
  • useViewChildren
  • useRecursiveChildren
  • entityGraph
  • useStrategyRequest
  • useGraphCoreBridge
  • useBridgeStatus
  • useWebSocketConsumer
  • StrategyRequests

Implementation Guidance

If you are integrating this library into a host app today:

  1. Mount a single GraphCoreProvider near the app root.
  2. Use AuthPage + useAuth, or inject your own token with getToken.
  3. Prefer EntityRenderer or the self-hosted view components for the fastest path.
  4. For new custom UI, read data with useEntity / useChildren / useEntities.
  5. Send all writes through useStrategyRequest or useWebSocketConsumer.
  6. Treat the entity store as read-only application state mirrored from the backend.

Notes

  • This package targets React 19.
  • Graph mutations are backend-authoritative.
  • Entity store writes are owned by the GraphCore bridge, not by host app code.