My App
BoardKit

Getting Started

Install and set up BoardKit in your NestJS backend and React frontend

Prerequisites

  • Bun or Node.js 18+
  • A NestJS application (backend)
  • A React 18/19 application (frontend)

Installation

Core (shared types and logic)

bun add @hfu.digital/boardkit-core

The core package has zero runtime dependencies and is automatically installed as a dependency of both the backend and frontend packages.

Backend

bun add @hfu.digital/boardkit-nestjs

Peer dependencies:

bun add @nestjs/common @nestjs/core @nestjs/websockets @nestjs/platform-socket.io rxjs

Frontend

bun add @hfu.digital/boardkit-react

Peer dependencies:

bun add react react-dom socket.io-client  # React 18 or 19

Backend Setup

1. Implement Storage Adapters

BoardKit requires four adapter implementations. You can use the included Prisma adapter or write your own.

import { PrismaBoardAdapter } from '@hfu.digital/boardkit-nestjs';
import { PrismaService } from './prisma.service';

const prisma = new PrismaService();

const boardStorage = new PrismaBoardAdapter({
    board: prisma.board,
    page: prisma.page,
    element: prisma.element,
    boardMember: prisma.boardMember,
    shareLink: prisma.shareLink,
});

For AssetStorage and EventLogStorage, see the Storage Interface and Asset Storage docs.

2. Implement an Auth Guard

import { BoardAuthGuard, type AuthenticatedUser } from '@hfu.digital/boardkit-nestjs';

class MyAuthGuard extends BoardAuthGuard {
    async validateConnection(token: string): Promise<AuthenticatedUser | null> {
        // Validate WebSocket connection token
        const user = await verifyToken(token);
        return user ? { userId: user.id, displayName: user.name } : null;
    }

    async validateRequest(token: string): Promise<AuthenticatedUser | null> {
        // Validate HTTP request token
        const user = await verifyToken(token);
        return user ? { userId: user.id, displayName: user.name } : null;
    }
}

3. Register the Module

import { Module } from '@nestjs/common';
import { BoardModule } from '@hfu.digital/boardkit-nestjs';

@Module({
    imports: [
        BoardModule.register({
            storage: boardStorage,
            assetStorage: myAssetStorage,
            eventLogStorage: myEventLogStorage,
            authGuard: new MyAuthGuard(),
        }),
    ],
})
export class AppModule {}

This registers 5 REST controllers (boards, pages, assets, export, sharing) and a Socket.IO WebSocket gateway at the /board namespace.

Frontend Setup

1. Wrap Your App with the Provider

import { BoardKitProvider } from '@hfu.digital/boardkit-react';

function App() {
    return (
        <BoardKitProvider
            config={{
                apiUrl: '/api',
                wsUrl: 'ws://localhost:3000/board',
                authToken: 'your-jwt-token',
            }}
        >
            <WhiteboardPage />
        </BoardKitProvider>
    );
}

2. Use the Canvas and Hooks

import {
    BoardCanvas,
    Toolbar,
    useBoard,
    useCollaboration,
    useTool,
    useKeyboardShortcuts,
} from '@hfu.digital/boardkit-react';

function WhiteboardPage() {
    const { board, loading } = useBoard('board-id');
    const { connectionState } = useCollaboration('board-id');
    const { activeTool, setTool } = useTool();
    useKeyboardShortcuts();

    if (loading) return <p>Loading...</p>;

    return (
        <div style={{ width: '100vw', height: '100vh' }}>
            <Toolbar activeTool={activeTool} onToolChange={setTool} />
            <BoardCanvas />
            <p>Status: {connectionState}</p>
        </div>
    );
}

Next Steps

On this page