Installation

Learn how to install the @shadcn/designer package and get started with the designer.

License Required

You will need a license key to install the package. You can learn more about the pricing and purchase a business license here.

See Pricing

Create Project

First, let's setup a new Vite + Tailwind project.

npx create-vite@latest my-designer --template react-ts

Configure Tailwind

The @shadcn/designer package is built with Tailwind CSS. You will need to install Tailwind and configure it in your project.

Install Tailwind

Add the following dependencies to your project.

npm install tailwindcss @tailwindcss/vite

Configure the Vite plugin

Import the Tailwind Vite plugin in your vite.config.ts file.

vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
 
export default defineConfig({
  plugins: [react(), tailwindcss()],
});

Import Tailwind CSS

Replace the content of your index.css file with the following.

index.css
@import "tailwindcss";

Install Package

Next, let's install the package. You will need a license key to install the package. You can purchase a business license here.

npm install https://ds.shadcn.com/registry\?version\=1.0.0\&license\=YOUR_LICENSE_KEY

Import the Designer component from @shadcn/designer and the styles from @shadcn/designer/styles.css.

src/App.tsx
import { Designer } from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return <Designer className="h-svh" />;
}

Make sure you also import the styles from @shadcn/designer/styles.css. This should be imported after your own styles.

Components

The Designer is built to be composable. You build your custom designer by composing the components that you need.

The following will setup a basic designer with a canvas and a frame. The default frame size is 1024x1024.

src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
      </DesignerContent>
    </Designer>
  );
}

Layers

Now that your designer is setup, you can add layers to it. Press T on your keyboard to add a new text layer.

You will see a new text layer added to the canvas. You can drag the text layer around the canvas and use the handles to resize it.

The designer comes with the following layer types by default: frame, text and image.

You can extend the designer by adding your own layer types. See the Custom Layer example for more information.

Toolbar

Let's place a toolbar with buttons to add layers to the canvas. You should see a new toolbar at the bottom of the canvas. The toolbar has one action to add a new layer.

src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
  DesignerToolbar,
  DesignerToolbarGroup,
  ActionToolbarAddLayer,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
      </DesignerContent>
      <DesignerToolbar>
        <DesignerToolbarGroup>
          <ActionToolbarAddLayer />
        </DesignerToolbarGroup>
      </DesignerToolbar>
    </Designer>
  );
}

Panels

Now that we have a canvas and we can add layers to it, let's add a <DesignerPanel /> to display layer controls.

src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
  DesignerToolbar,
  DesignerToolbarGroup,
  ActionToolbarAddLayer,
  DesignerPanel,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
        <DesignerPanel />
      </DesignerContent>
      <DesignerToolbar>
        <DesignerToolbarGroup>
          <ActionToolbarAddLayer />
        </DesignerToolbarGroup>
      </DesignerToolbar>
    </Designer>
  );
}

This will place a panel on the right side of the canvas. We can have multiple panels in the designer. Let's add a panel to the left side of the canvas.

src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
  DesignerToolbar,
  DesignerToolbarGroup,
  ActionToolbarAddLayer,
  DesignerPanel,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerPanel />
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
        <DesignerPanel />
      </DesignerContent>
      <DesignerToolbar>
        <DesignerToolbarGroup>
          <ActionToolbarAddLayer />
        </DesignerToolbarGroup>
      </DesignerToolbar>
    </Designer>
  );
}

Panes

We use <DesignerPane /> to display and group controls. Let's add a new pane to the right panel.

src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
  DesignerToolbar,
  DesignerToolbarGroup,
  ActionToolbarAddLayer,
  DesignerPanel,
  DesignerPane,
  DesignerPaneTitle,
  DesignerPaneContent,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerPanel />
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
        <DesignerPanel>
          <DesignerPane>
            <DesignerPaneTitle>Layers</DesignerPaneTitle>
            <DesignerPaneContent>Hello World</DesignerPaneContent>
          </DesignerPane>
        </DesignerPanel>
      </DesignerContent>
      <DesignerToolbar>
        <DesignerToolbarGroup>
          <ActionToolbarAddLayer />
        </DesignerToolbarGroup>
      </DesignerToolbar>
    </Designer>
  );
}

You should see a new pane with the title "Layers" and the content "Hello World" in the right panel.

Actions and Controls

To display and control the properties of a layer, we use <Action /> components.

The @shadcn/designer package ships with several actions out of the box. We also provide the right API and components to create your own custom actions.

Let's add a <ActionPosition /> to the right panel to display the position of the layer.

src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
  DesignerToolbar,
  DesignerToolbarGroup,
  ActionPosition,
  ActionToolbarAddLayer,
  DesignerPanel,
  DesignerPane,
  DesignerPaneTitle,
  DesignerPaneContent,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerPanel />
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
        <DesignerPanel>
          <DesignerPane>
            <DesignerPaneTitle>Layers</DesignerPaneTitle>
            <DesignerPaneContent>
              <ActionPosition />
            </DesignerPaneContent>
          </DesignerPane>
        </DesignerPanel>
      </DesignerContent>
      <DesignerToolbar>
        <DesignerToolbarGroup>
          <ActionToolbarAddLayer />
        </DesignerToolbarGroup>
      </DesignerToolbar>
    </Designer>
  );
}

You should see a new Position action in the right panel. It comes with X and Y inputs to control the position of the layer. If you click and drag a layer you should see the X and Y values change.

More Actions

Let's build a custom panel with more actions and import it into our designer.

src/panel-right.tsx
import {
  ActionFill,
  ActionPadding,
  ActionBoxShadow,
  DesignerPanel,
  DesignerPane,
  DesignerPaneTitle,
  DesignerPaneContent,
  ActionPosition,
  ActionSize,
  ActionCorner,
  ActionBorder,
  ActionRotate,
  ActionDirection,
  ActionTextValue,
  ActionImageFit,
  ActionImageFilter,
  ActionFont,
  ActionColor,
  ActionFontSize,
  ActionLineHeight,
  ActionLetterSpacing,
  ActionTextAlign,
  ActionAlignItems,
  ActionFontStyle,
  ActionTextDecoration,
  ActionTextTransform,
  ActionTextShadow,
  ActionTextStroke,
} from "@shadcn/designer";
 
export function PanelRight() {
  return (
    <DesignerPanel>
      <DesignerPane>
        <DesignerPaneTitle>Layer</DesignerPaneTitle>
        <DesignerPaneContent>
          <ActionPosition />
          <ActionSize />
        </DesignerPaneContent>
      </DesignerPane>
      <DesignerPane>
        <DesignerPaneTitle>Styles</DesignerPaneTitle>
        <DesignerPaneContent>
          <ActionCorner />
          <ActionBorder />
          <ActionBoxShadow />
          <ActionPadding />
          <ActionFill />
        </DesignerPaneContent>
      </DesignerPane>
      <DesignerPane>
        <DesignerPaneTitle>Transforms</DesignerPaneTitle>
        <DesignerPaneContent>
          <ActionRotate />
          <ActionDirection />
        </DesignerPaneContent>
      </DesignerPane>
      <DesignerPane showForLayerTypes={["text"]}>
        <DesignerPaneContent>
          <ActionTextValue />
        </DesignerPaneContent>
      </DesignerPane>
      <DesignerPane showForLayerTypes={["image"]}>
        <DesignerPaneTitle>Image</DesignerPaneTitle>
        <DesignerPaneContent>
          <ActionImageFit />
        </DesignerPaneContent>
      </DesignerPane>
      <DesignerPane showForLayerTypes={["image"]}>
        <DesignerPaneTitle>Filters</DesignerPaneTitle>
        <DesignerPaneContent>
          <ActionImageFilter />
        </DesignerPaneContent>
      </DesignerPane>
      <DesignerPane showForLayerTypes={["text", "icon"]}>
        <DesignerPaneTitle>Text</DesignerPaneTitle>
        <DesignerPaneContent>
          <ActionColor />
          <ActionFontSize />
          <ActionLineHeight />
          <ActionLetterSpacing />
          <ActionTextAlign />
          <ActionAlignItems />
          <ActionFontStyle />
          <ActionTextDecoration />
          <ActionTextTransform />
          <ActionTextShadow />
          <ActionTextStroke />
        </DesignerPaneContent>
      </DesignerPane>
    </DesignerPanel>
  );
}
src/App.tsx
import {
  Designer,
  DesignerContent,
  DesignerCanvas,
  DesignerFrame,
  DesignerToolbar,
  DesignerToolbarGroup,
  ActionToolbarAddLayer,
  DesignerPanel,
} from "@shadcn/designer";
import "@shadcn/designer/styles.css";
 
import { PanelRight } from "./panel-right";
 
export default function App() {
  return (
    <Designer className="h-svh">
      <DesignerContent>
        <DesignerPanel />
        <DesignerCanvas>
          <DesignerFrame />
        </DesignerCanvas>
        <PanelRight />
      </DesignerContent>
      <DesignerToolbar>
        <DesignerToolbarGroup>
          <ActionToolbarAddLayer />
        </DesignerToolbarGroup>
      </DesignerToolbar>
    </Designer>
  );
}

See the Actions section for more information on available actions.

Next Steps

See the examples section for more detailed examples. Then see the API section for more information on the available components and hooks.