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

@filekit-studio/sketch

v1.5.1

Published

Local-first, embeddable whiteboard & diagramming SDK for React and Next.js

Readme

@filekit-studio/sketch

Local-first, interactive whiteboard and architecture diagramming SDK for React and Next.js.

npm version License: MIT

Documentation • Live Playground • Tech Stencils Catalog • FileKit Studio


Features

  • Local-First Privacy: Zero server calls, zero database overhead, and zero telemetry. Diagrams run and persist entirely in the client.
  • Database Schema & ER Modeling: Typed 2-column database tables (tableStyle: 'database') with PK/FK icons, automatic type coloring, dynamic row addition/deletion, auto-widening text boxes, and full keyboard navigation (Enter, Shift+Enter, Backspace row removal, arrow traversal). Press M to activate.
  • Live Animated Data Flow Connectors: Real-time particle pulse and flow simulation across curved, elbow, and straight magnetic connectors with configurable speed, trigger modes, and glow colors.
  • Shift-Constrained 15° Angle Snapping: Hold Shift while drawing straight lines or arrows to lock to 15° angular increments (0° horizontal, 90° vertical, 45° diagonal, 30°/60° isometric) with floating degree badges.
  • Arrow Badges & Harmonized Palettes: In-place double-click label editing with multi-line wrap (\n), compact auto-sizing, and single-color tone palettes with dark/light mode optimization.
  • Magnetic Connection Anchor Suggestions: Real-time 12-point perimeter anchor suggestions on diagram and database table border hover for effortless connector snapping.
  • Frame Containment & Anti-Stealing Duplication: Structural frames (type: 'frame') that act as isolated slide decks or component boundaries. Duplicating or moving a frame clones and shifts all enclosed shapes atomically.
  • Steganographic Lossless PNG Export: Export raster PNGs with deflated vector scene metadata embedded inside PNG tEXt chunks (embedScene: true). Re-importing into Sketch restores 100% of editable vectors.
  • React 18 & 19 / Next.js Ready: Native App Router and Pages Router support with zero SSR hydration mismatches.
  • 675+ Production Stencils: Official cloud logos and microservice primitives (AWS, GCP, Azure, Docker, Kubernetes, Next.js, PostgreSQL, Redis, Supabase).
  • Obstacle-Avoiding Routing: Hanan Grid $A^*$ orthogonal and curved arrow routing with Minkowski Sum obstacle inflation, corner fillets, and highway lane offsets.
  • Presentation Deck Mode: Convert canvas frames into presentation slide decks (Alt+P) with laser pointer and spotlight focus tools.
  • Headless Exporters: Serverless and headless export to vector PDF (multi-page auto-paginated), crisp PNG, and standalone SVG.
  • Embedded Viewer: Lightweight <SketchViewer /> component for rendering interactive or static diagrams in docs and blogs.
  • Unified .sketch File Format: Fast, portable JSON file format protected by a prototype-pollution and XSS security purifier.

Installation

npm install @filekit-studio/sketch
# or
pnpm add @filekit-studio/sketch
# or
bun add @filekit-studio/sketch

Peer Dependencies

  • react >= 18.0.0
  • react-dom >= 18.0.0

Required Stylesheet Import

Import the stylesheet in your root layout (app/layout.tsx or pages/_app.tsx):

// Universal modern Tailwind CSS v4 styling (Default)
import '@filekit-studio/sketch/styles.css'

// Or pick an aesthetic variant:
// import '@filekit-studio/sketch/classic.css'     // Classic clean wireframe styling
// import '@filekit-studio/sketch/neumorphic.css'  // Soft extruded 3D neumorphic styling

Zero CSS Pollution (Strict Scope Isolation):
All styles are strictly scoped under .fk-sketch-root. Importing this stylesheet will never conflict with your app's global CSS, markdown fonts, or Tailwind config.


Quick Start

Import <SketchEditor /> inside a Client Component ('use client'):

'use client'

import React from 'react'
import { SketchEditor } from '@filekit-studio/sketch'
import '@filekit-studio/sketch/styles.css'

export default function WhiteboardPage() {
  return (
    <main className="w-screen h-screen overflow-hidden">
      <SketchEditor
        boardName="System Architecture"
        storageKey="my_app_whiteboard"
        onChange={(doc) => {
          console.log('Updated:', doc.elements.length, 'elements')
        }}
        onSave={(doc) => {
          console.log('Saved:', doc)
        }}
        showGuideButton={true}
        guideHref="/docs"
      />
    </main>
  )
}

Read-Only Diagram Viewer (<SketchViewer />)

Use <SketchViewer /> to embed diagrams in documentation, blog posts, and dashboards with zero editor chrome:

'use client'

import { SketchViewer } from '@filekit-studio/sketch'
import '@filekit-studio/sketch/styles.css'

export function ArchitectureDiagram({ document }) {
  return (
    <div className="w-full h-[420px] rounded-xl overflow-hidden border">
      <SketchViewer
        value={document}
        theme="system"
        autoFit={true}
        interactive={true}
        showCopyButton={true}
        showZoomControls={true}
      />
    </div>
  )
}

Obstacle-Avoiding Arrow Routing

Route collision-free orthogonal or curved arrows around diagram nodes programmatically:

import { computeNonCollisionRoute, generateFilletSvgPath } from '@filekit-studio/sketch'

const route = computeNonCollisionRoute(
  { x: 100, y: 150 }, // Start point
  { x: 500, y: 350 }, // End point
  'right',            // Start anchor orientation ('top' | 'right' | 'bottom' | 'left')
  'left',             // End anchor orientation
  obstacles,          // Array of { x, y, width, height }
  {
    margin: 24,       // Minkowski Sum obstacle padding
    bendPenalty: 40,  // Penalize unnecessary turns
    filletRadius: 10, // Rounded 90° arc fillets
    smoothCurves: false,
  }
)

// Generate SVG path string for rendering:
const svgPath = generateFilletSvgPath(route.waypoints, 10)

Headless Export Utilities

Export diagrams without mounting the canvas component via @filekit-studio/sketch/export:

import {
  exportToPng,
  exportToSvg,
  exportWhiteboardToPdf,
} from '@filekit-studio/sketch/export'
import { extractSceneFromPng } from '@filekit-studio/sketch'

// PNG with optional steganographic lossless scene embedding
const pngDataUrl = await exportToPng(elements, {
  scale: 2,
  backgroundColor: '#ffffff',
  embedScene: true, // Injects compressed scene into PNG tEXt chunk
})

// Extract 100% editable vector scene from a FileKit PNG
const recoveredDoc = await extractSceneFromPng(pngFileBlob)

// Vector SVG string
const svgMarkup = exportToSvg(elements, {
  includeBackground: true,
})

// Multi-page Vector PDF Blob
const pdfBlob = await exportWhiteboardToPdf(elements, {
  title: 'Architecture Specification',
  author: 'FileKit Studio',
})

Database Schema & ER Entity Tables

Render typed 2-column database tables with primary keys, datatypes, and automatic palette synchronization:

import { SketchEditor, type SketchBoardElement } from '@filekit-studio/sketch'

const usersTable: SketchBoardElement = {
  id: 'table_users',
  type: 'table',
  tableStyle: 'database', // Activates Database Entity mode
  x: 100,
  y: 100,
  width: 280,
  height: 180,
  strokeColor: '#3b82f6',
  strokeWidth: 2,
  strokeStyle: 'solid',
  fillColor: '#1e293b',
  fillStyle: 'solid',
  opacity: 1,
  zIndex: 1,
  rows: 4,
  cols: 2,
  colWidths: [150, 130],
  rowHeights: [36, 32, 32, 32],
  hasHeaderRow: true,
  cells: {
    '0,0': { text: 'users', bold: true, align: 'left' },
    '1,0': { text: 'id', align: 'left' },            // Auto-displays yellow PK key icon
    '1,1': { text: 'uuid', align: 'right' },
    '2,0': { text: 'name', align: 'left' },
    '2,1': { text: 'varchar(100)', align: 'right' },
    '3,0': { text: 'email', align: 'left' },
    '3,1': { text: 'varchar(255)', align: 'right' },
  },
}
  • Keyboard Navigation in Cells:
    • Enter: Inserts a clean newline without shifting cells. Row height dynamically expands.
    • Shift + Enter or Tab: Confirms cell edit and jumps to the next row/column.
    • Backspace (when row is empty): Deletes the entire empty row and contracts table height automatically.
    • ↑ ↓ → ←: Navigate between adjacent cells.
    • Shortcut: Press M to activate the Database Schema Table tool.

Live Animated Data Flow Connectors

Simulate data streaming across connectors in real time:

const animatedStream: SketchBoardElement = {
  id: 'stream_1',
  type: 'arrow',
  arrowType: 'elbow',
  x: 280,
  y: 150,
  width: 140,
  height: 80,
  strokeColor: '#3b82f6',
  strokeWidth: 2,
  strokeStyle: 'solid',
  fillColor: 'transparent',
  fillStyle: 'solid',
  opacity: 1,
  zIndex: 2,
  endArrowhead: 'arrow',
  // Live Connector Simulation:
  flowAnimation: 'packet-pulse', // 'none' | 'marching-ants' | 'packet-pulse' | 'error-backoff'
  flowSpeed: 'normal',           // 'slow' (2.4s) | 'normal' (1.4s) | 'fast' (0.7s)
  flowTrigger: 'continuous',     // 'continuous' | 'hover' | 'click' | 'step'
  flowColor: '#60a5fa',          // Custom packet glow color
}

Programmatic Controller (SketchController)

Attach a controllerRef to imperatively control the whiteboard canvas:

import React, { useRef } from 'react'
import { SketchEditor, type SketchController } from '@filekit-studio/sketch'

export function ControlledCanvas() {
  const controllerRef = useRef<SketchController | null>(null)

  const handleAddNote = () => {
    controllerRef.current?.addElement({
      type: 'sticky',
      x: 200,
      y: 200,
      width: 180,
      height: 180,
      text: 'Production Note',
      fillColor: '#fef08a',
    })
  }

  return (
    <div className="w-full h-full relative">
      <button onClick={handleAddNote}>+ Add Note</button>
      <SketchEditor controllerRef={controllerRef} />
    </div>
  )
}

Controller Methods

| Method | Description | | :--- | :--- | | loadDocument(doc) | Replaces the active whiteboard document. | | getDocument() | Returns the serializable document state. | | clear() | Resets the whiteboard canvas to an empty state. | | addElement(element) | Programmatically inserts and selects an element. | | updateElement(id, patch) | Partially updates an existing element. | | deleteElements(ids) | Deletes elements by ID list. | | getElements() | Returns current elements array. | | undo() / redo() | Navigates the undo/redo history stack. | | zoomToFit() | Centers and zooms to fit all elements in viewport. | | zoomIn() / zoomOut() | Smooth incremental viewport zooming. | | resetZoom() | Resets zoom scale back to 100%. | | showToast(msg, options) | Triggers in-canvas notification toast banner. | | on(event, handler) | Subscribes to events ('change', 'select', 'clear', 'undo', 'redo', 'camera'). |


Component API Reference

<SketchEditor />

| Prop | Type | Default | Description | | :--- | :--- | :--- | :--- | | value | SketchDocument \| SketchBoardElement[] | undefined | Controlled document or elements. | | defaultValue | SketchDocument \| SketchBoardElement[] | Starter Doc | Initial uncontrolled document state. | | onChange | (doc: SketchDocument) => void | undefined | Callback fired on any element or title change. | | onSave | (doc: SketchDocument) => void | undefined | Callback fired on manual save (Ctrl+S). | | storageKey | string \| null | 'filekit_sketch_document_v1' | Key used to persist state to localStorage. Use dynamic keys (storageKey={'board_' + id}) to isolate multi-board workspaces. | | boardName | string | 'My Whiteboard' | Whiteboard title displayed in header. | | readOnly | boolean | false | Disables mutations and hides editing tools. | | theme | 'light' \| 'dark' \| 'system' | 'system' | Visual color theme mode. | | showThemeToggle | boolean | false | Independent sun/moon canvas theme button in top bar. | | onThemeChange | (theme: 'light' \| 'dark') => void | undefined | Callback fired when theme toggle is clicked. | | canvasBackground | string | '#f0f4f8' | Canvas background hex color. | | gridStyle | 'grid' \| 'dots' \| 'cross' \| 'none' | 'grid' | Background grid pattern. | | fontFamily | FontFamily | 'fuzzy' | Default canvas font family. | | panelVariant | 'classic' \| 'neumorphic' | 'classic' | Chrome styling variant: flat borders or soft 3D bevels. | | wheelPan | boolean | true | When false, mouse wheel scrolls the host webpage; Ctrl+wheel zooms. | | toastPosition | ToastPosition | 'bottom-center' | Toast banner position ('bottom-center', 'top-right', etc.). | | position | ToastPosition | 'bottom-center' | Direct alias for toastPosition. | | toastDuration | number | 2400 | Auto-dismiss duration in milliseconds for notification toasts. | | saveToastMessage | string \| null | 'Document saved successfully' | Custom save toast message (or null to suppress). | | templates | TemplateDefinition[] | undefined | Custom architecture starter templates array. | | controllerRef | React.Ref<SketchController> | undefined | Ref exposing programmatic imperative controls. | | onExit | () => void | undefined | Exit back button handler. If omitted with exitHref, exit button is hidden. | | exitHref | string | undefined | Route navigated to when clicking the exit button. | | onShare | () => void | undefined | Callback fired when user clicks the Share button in the top bar. Automatically mounts the Share button. | | showGuideButton | boolean | false | Mounts a guide help button in the header. | | guideHref | string | undefined | External or internal URL for the guide button. | | onOpenGuide | () => void | undefined | Intercepts click on guide button to trigger custom modal. | | uiConfig | SketchUIConfig | {} | Fine-grained visibility toggles for all 54 toolbars and panels. |

<SketchViewer />

| Prop | Type | Default | Description | | :--- | :--- | :--- | :--- | | value / elements | SketchDocument \| SketchBoardElement[] | undefined | Document or elements to render. | | theme | 'light' \| 'dark' \| 'system' | 'system' | Light/dark theme mode. | | autoFit | boolean | true | Centers and scales diagram to fit container. | | interactive | boolean | true | Allows panning and zooming. Set false for static display. | | showCopyButton | boolean | true | 1-click clipboard export button. | | copyFormat | 'elements' \| 'image' \| 'json' | 'elements' | Format written to the clipboard: 'elements' (paste directly with Ctrl+V into whiteboard), 'image' (2x PNG), or 'json'. | | showZoomControls | boolean | true | Minimal bottom zoom controls (- 100% + Fit). | | canvasBackground | string | '#f0f4f8' | Custom canvas background color hex. | | gridStyle | 'grid' \| 'dots' \| 'cross' \| 'none' | 'dots' | Background grid pattern. | | title | string | undefined | Optional title badge in top-left corner. |


License

MIT © FileKit Studio