Package Installation
Install via npm, yarn, or pnpm
Excalidraw requires React and React DOM as peer dependencies. Install the package using your preferred package manager: npm install react react-dom @excalidraw/excalidraw
React Version Support : Excalidraw supports React 17, 18, and 19. The package is compatible with react@^17.0.2 || ^18.2.0 || ^19.0.0.
Import Excalidraw and styles
Import the Excalidraw component and its required CSS file in your application: import { Excalidraw } from "@excalidraw/excalidraw" ;
import "@excalidraw/excalidraw/index.css" ;
Add the component to your app
Add Excalidraw to your component. Make sure the parent container has explicit dimensions: export default function App () {
return (
< div style = { { height: "500px" , width: "100%" } } >
< Excalidraw />
</ div >
);
}
Container Dimensions Required : Excalidraw takes 100% of the width and height of its containing block. Ensure the parent element has non-zero dimensions, or the canvas will not be visible.
Framework-Specific Setup
Next.js
Next.js requires dynamic imports with SSR disabled to avoid hydration issues.
Create a wrapper component
Create a client component that imports Excalidraw: "use client" ;
import { Excalidraw } from "@excalidraw/excalidraw" ;
import "@excalidraw/excalidraw/index.css" ;
const ExcalidrawWrapper = () => {
return < Excalidraw /> ;
};
export default ExcalidrawWrapper ;
Import with dynamic loading
In your page component, use Next.js dynamic imports with ssr: false: import dynamic from "next/dynamic" ;
import Script from "next/script" ;
const ExcalidrawWithClientOnly = dynamic (
async () => ( await import ( "../excalidrawWrapper" )). default ,
{
ssr: false ,
},
);
export default function Page () {
return (
<>
< Script id = "load-env-variables" strategy = "beforeInteractive" >
{ `window["EXCALIDRAW_ASSET_PATH"] = window.origin;` }
</ Script >
< div style = { { height: "100vh" } } >
< ExcalidrawWithClientOnly />
</ div >
</>
);
}
import dynamic from "next/dynamic" ;
import Script from "next/script" ;
const Excalidraw = dynamic (
() => import ( "@excalidraw/excalidraw" ). then (( mod ) => mod . Excalidraw ),
{ ssr: false }
);
export default function ExcalidrawPage () {
return (
<>
< Script id = "load-env-variables" strategy = "beforeInteractive" >
{ `window["EXCALIDRAW_ASSET_PATH"] = window.origin;` }
</ Script >
< div style = { { height: "100vh" } } >
< Excalidraw />
</ div >
</>
);
}
Vite
Vite works out of the box with Excalidraw. Simply import and use:
import { Excalidraw } from "@excalidraw/excalidraw" ;
import "@excalidraw/excalidraw/index.css" ;
function App () {
return (
< div style = { { height: "100vh" } } >
< Excalidraw />
</ div >
);
}
export default App ;
Create React App
Create React App also works without additional configuration:
import React from "react" ;
import { Excalidraw } from "@excalidraw/excalidraw" ;
import "@excalidraw/excalidraw/index.css" ;
function App () {
return (
< div style = { { height: "100vh" } } >
< Excalidraw />
</ div >
);
}
export default App ;
Self-Hosting Fonts
For production deployments, you should self-host Excalidraw fonts instead of loading them from a CDN.
Copy font files to your public directory
Copy the fonts from node_modules/@excalidraw/excalidraw/dist/prod/fonts to your public directory: cp -r node_modules/@excalidraw/excalidraw/dist/prod/fonts public/fonts
The fonts directory includes all font families used by Excalidraw: Virgil (hand-drawn style), Cascadia, Assistant, and more.
Set the asset path
Configure window.EXCALIDRAW_ASSET_PATH to point to your public directory where fonts are hosted: In HTML: < script >
window . EXCALIDRAW_ASSET_PATH = "/" ;
</ script >
In Next.js: import Script from "next/script" ;
export default function Page () {
return (
<>
< Script id = "load-env-variables" strategy = "beforeInteractive" >
{ `window.EXCALIDRAW_ASSET_PATH = window.origin;` }
</ Script >
{ /* Your Excalidraw component */ }
</>
);
}
In React: useEffect (() => {
window . EXCALIDRAW_ASSET_PATH = "/" ;
}, []);
If you don’t set EXCALIDRAW_ASSET_PATH, Excalidraw will attempt to load fonts from the CDN at https://esm.run/@excalidraw/excalidraw/dist/prod/. This works fine for development but may cause issues in production or offline environments.
Browser Compatibility
Excalidraw supports modern browsers with the following minimum versions:
Mobile Browsers Safari iOS 12+, Chrome Android
Not supported:
Internet Explorer (any version)
Opera Mini
UC Browser < 13
Samsung Internet < 10
KaiOS ≤ 2.5
TypeScript Support
Excalidraw is written in TypeScript and includes full type definitions. No additional @types packages are needed.
import type {
ExcalidrawImperativeAPI ,
ExcalidrawProps ,
NonDeletedExcalidrawElement ,
AppState ,
} from "@excalidraw/excalidraw/types" ;
const MyComponent = () => {
const [ excalidrawAPI , setExcalidrawAPI ] =
useState < ExcalidrawImperativeAPI | null >( null );
return (
< Excalidraw
excalidrawAPI = { ( api ) => setExcalidrawAPI ( api ) }
onChange = { ( elements : readonly NonDeletedExcalidrawElement [], state : AppState ) => {
console . log ( "Elements:" , elements );
} }
/>
);
};
Available Type Exports
Import types from the appropriate subpackages:
// Core types
import type { ExcalidrawProps , AppState } from "@excalidraw/excalidraw/types" ;
// Element types
import type {
ExcalidrawElement ,
NonDeletedExcalidrawElement ,
FileId
} from "@excalidraw/excalidraw/element/types" ;
// Data types
import type { ImportedLibraryData } from "@excalidraw/excalidraw/data/types" ;
Additional Packages
Excalidraw exports additional utility packages for advanced use cases:
Common utilities and constants: import { THEME , MIME_TYPES , normalizeLink } from "@excalidraw/common" ;
Element manipulation utilities: import {
mutateElement ,
newElementWith ,
getSceneVersion ,
getNonDeletedElements
} from "@excalidraw/element" ;
Mathematical utilities for geometry calculations: import { rotatePoint , getDistance } from "@excalidraw/math" ;
Export and utility functions: import { exportToCanvas , exportToSvg , exportToBlob } from "@excalidraw/utils/export" ;
Using the Latest (Unreleased) Version
To try unreleased features and bug fixes before the next stable release:
npm install @excalidraw/excalidraw@next
The @next tag includes unreleased changes that may be unstable. Only use this in development or if you need a specific fix that hasn’t been released yet.
Next Steps