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

aakasha-excalidraw

v0.2.0-test

Published

Excalidraw as a React component

Readme

Excalidraw

Excalidraw exported as a component to directly embed in your projects

Installation

You can use npm

npm install react react-dom @excalidraw/excalidraw

or via yarn

yarn add react react-dom @excalidraw/excalidraw

After installation you will see a folder excalidraw-assets in dist directory which contains the assets needed for this app.

Move the folder excalidraw-assets to the path where your assets are served. In the example its served from public/excalidraw-assets

Demo

Try here.

Usage

import React, { useEffect, useState, createRef } from "react";
import Excalidraw from "@excalidraw/excalidraw";
import InitialData from "./initialData";

import "@excalidraw/excalidraw/dist/excalidraw.min.css";
import "@excalidraw/excalidraw/dist/fonts.min.css";

import "./styles.css";

export default function App() {
  const excalidrawRef = createRef();

  const onChange = (elements, state) => {
    console.log(excalidrawRef.current);
    console.log("Elements :", elements, "State : ", state);
  };

  const [dimensions, setDimensions] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  const onResize = () => {
    setDimensions({
      width: window.innerWidth,
      height: window.innerHeight,
    });
  };

  useEffect(() => {
    window.addEventListener("resize", onResize);

    return () => window.removeEventListener("resize", onResize);
  }, []);

  const updateScene = () => {
    const sceneData = {
      elements: [
        {
          type: "rectangle",
          version: 141,
          versionNonce: 361174001,
          isDeleted: false,
          id: "oDVXy8D6rom3H1-LLH2-f",
          fillStyle: "hachure",
          strokeWidth: 1,
          strokeStyle: "solid",
          roughness: 1,
          opacity: 100,
          angle: 0,
          x: 100.50390625,
          y: 93.67578125,
          strokeColor: "#c92a2a",
          backgroundColor: "transparent",
          width: 186.47265625,
          height: 141.9765625,
          seed: 1968410350,
          groupIds: [],
        },
      ],
      appState: {
        viewBackgroundColor: "#edf2ff",
      },
    };
    excalidrawRef.current.updateScene(sceneData);
  };

  const { width, height } = dimensions;
  return (
    <div className="App">
      <button className="update-scene" onClick={updateScene}>
        Update Scene
      </button>
      <button
        className="reset-scene"
        onClick={() => {
          excalidrawRef.current.resetScene();
        }}
      >
        Reset Scene
      </button>
      <div className="excalidraw-wrapper">
        <Excalidraw
          ref={excalidrawRef}
          width={width}
          height={height}
          initialData={InitialData}
          onChange={onChange}
          user={{ name: "Excalidraw User" }}
          onPointerUpdate={(payload) => console.log(payload)}
        />
      </div>
    </div>
  );
}

Edit excalidraw

Props

| Name | Type | Default | Description | | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | width | Number | window.innerWidth | The width of Excalidraw component | | height | Number | window.innerHeight | The height of Excalidraw component | | offsetLeft | Number | 0 | left position relative to which Excalidraw should be rendered | | offsetTop | Number | 0 | top position relative to which Excalidraw should render | | onChange | Function | | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw elements and the current app state. | | initialData | ExcalidrawElement[] | [] | The initial data with which app loads. | | user | { name?: string } | | User details. The name refers to the name of the user to be shown | | excalidrawRef | createRef or callbackRef or { current: { readyPromise: resolvablePromise } } | | Ref to be passed to Excalidraw | | onCollabButtonClick | Function | | Callback to be triggered when the collab button is clicked | | isCollaborating | boolean | | This implies if the app is in collaboration mode | | onPointerUpdate | Function | | Callback triggered when mouse pointer is updated. |

width

This props defines the width of the Excalidraw component. Defaults to window.innerWidth if not passed.

height

This props defines the height of the Excalidraw component. Defaults to window.innerHeight if not passed.

offsetLeft

This prop defines left position relative to which Excalidraw should be rendered. Defaults to 0 if not passed.

offsetTop

This prop defines top position relative to which Excalidraw should be rendered. Defaults to 0 if not passed.

onChange

Every time component updates, this callback if passed will get triggered and has the below signature.

(excalidrawElements, appState) => void;

1.excalidrawElements: Array of excalidrawElements in the scene.

2.appState: AppState of the scene

Here you can try saving the data to your backend or local storage for example.

initialData

This helps to load Excalidraw with initialData. It must be an object or a promise which resolves to an object containing the below optional fields.

| name | type | | -------- | --------------------------------------------------------------------------------------------------------------------------------------- | | elements | ExcalidrawElement [] | | appState | AppState |

{
  "elements": [
    {
      "type": "rectangle",
      "version": 141,
      "versionNonce": 361174001,
      "isDeleted": false,
      "id": "oDVXy8D6rom3H1-LLH2-f",
      "fillStyle": "hachure",
      "strokeWidth": 1,
      "strokeStyle": "solid",
      "roughness": 1,
      "opacity": 100,
      "angle": 0,
      "x": 100.50390625,
      "y": 93.67578125,
      "strokeColor": "#000000",
      "backgroundColor": "transparent",
      "width": 186.47265625,
      "height": 141.9765625,
      "seed": 1968410350,
      "groupIds": []
    }
  ],
  "appState": { "zenModeEnabled": true, "viewBackgroundColor": "#AFEEEE" }
}

You might want to use this when you want to load excalidraw with some initial elements and app state.

user

This is the user name which shows during collaboration. Defaults to {name: ''}.

excalidrawRef

You can pass a ref when you want to access some excalidraw API's. We expose the below API's

| API | signature | Usage | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ready | boolean | This is set to true once Excalidraw is rendered | | readyPromise | resolvablePromise | This promise will be resolved with the api once excalidraw has rendered. This will be helpful when you want do some action on the host app once this promise resolves. For this to work you will have to pass ref as shown here | | updateScene | (sceneData)) => void | updates the scene with the sceneData | | resetScene | ({ resetLoadingState: boolean }) => void | Resets the scene. If resetLoadingState is passed as true then it will also force set the loading state to false. | | getSceneElementsIncludingDeleted | () => ExcalidrawElement [] | Returns all the elements including the deleted in the scene | | getSceneElements | () => ExcalidrawElement [] | Returns all the elements excluding the deleted in the scene | | history | { clear: () => void } | This is the history API. history.clear() will clear the history | | setScrollToCenter | (ExcalidrawElement[]) => void | sets the elements to center |

readyPromise

onCollabButtonClick

This callback is triggered when clicked on the collab button in excalidraw

isCollaborating

This props implies if the app is in collaboration mode

onPointerUpdate

This callback is triggered when mouse pointer is updated

({ x, y }, button, pointersMap}) => void;

1.{x, y}: Pointer coordinates

2.button: The position of the button. This will be one of ["down", "up"]

3.pointersMap: pointers map of the scene