UI Framework Used in the Web Directory of Makeplane/Plane: React, Tailwind, and @plane/ui

The web directory in makeplane/plane uses a React-based UI framework consisting of React Router for client-side routing, Tailwind CSS for styling, and an internal component library called @plane/ui built on Headless UI.

The makeplane/plane repository powers Plane, an open-source project management platform. Its web directory contains the main client application, which implements a modern React-centric UI framework. This stack leverages Vite as the build tool and integrates several core technologies to deliver a polished, accessible user interface.

Core Technologies of the Web UI Framework

React as the Foundation

The application is fundamentally built on React. In apps/web/package.json, the core dependencies include react and react-dom, establishing React as the primary UI library. Throughout the codebase, components explicitly import React, such as in apps/web/core/components/workspace/sidebar/workspace-menu.tsx where you will see standard React imports managing component state and lifecycle.

React Router for Client-Side Navigation

Navigation is handled by React Router, distinguishing this from meta-frameworks like Next.js. The configuration in apps/web/vite.config.ts registers the React Router Vite plugin, confirming this architectural choice. This setup enables dynamic client-side routing without server-side rendering, maintaining the application as a single-page application (SPA).

Tailwind CSS for Styling

Tailwind CSS drives the styling layer. The codebase uses tailwind-merge for safe class composition, as evidenced in packages/propel/src/utils/classname.tsx. Utility classes are applied directly to JSX elements, allowing for rapid UI development without leaving the component files.

The @plane/ui Component Library

The project maintains an internal package called @plane/ui that provides reusable components. This library is built on top of React and Headless UI, offering unstyled, accessible primitive components that are styled with Tailwind CSS. You can examine the implementation in packages/ui/src/tooltip/tooltip.tsx, which demonstrates how these composite components extend Headless UI patterns with custom Tailwind styling.

Configuration and Build Setup

The framework configuration is centralized in two key files that confirm the React-centric architecture:

  • apps/web/package.json: Lists all dependencies including react, react-router, and tailwind-merge
  • apps/web/vite.config.ts: Configures the Vite build tool with the React Router plugin, optimizing the development experience for this specific React SPA setup

This configuration leverages Vite's fast HMR (Hot Module Replacement) capabilities rather than adopting a server-side rendering framework.

Practical Code Examples

Using the Internal UI Library

Components in the web directory import from the internal @plane/ui package:

import React from "react";
import { Button } from "@plane/ui";

export const HelloWorld = () => (
  <div className="flex items-center justify-center min-h-screen">
    <Button onClick={() => alert("Hello, Plane!")}>Say Hi</Button>
  </div>
);

This example shows how the Button component from @plane/ui is used within Tailwind-styled containers.

Routing Implementation

React Router handles navigation throughout the application:

import { BrowserRouter, Routes, Route } from "react-router";

export const App = () => (
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<HomePage />} />
      <Route path="/projects/:id" element={<ProjectPage />} />
    </Routes>
  </BrowserRouter>
);

The Vite configuration processes these routes at build time, as configured in vite.config.ts.

Tailwind-Styled Components

Direct utility class usage is standard throughout the web directory:

export const Card = ({ title, children }: { title: string; children: React.ReactNode }) => (
  <div className="rounded-lg border border-gray-200 p-4 shadow-sm bg-white">
    <h2 className="text-lg font-medium">{title}</h2>
    <div className="mt-2">{children}</div>
  </div>
);

The tailwind-merge utility, imported from packages/propel/src/utils/classname.tsx, helps resolve conflicting Tailwind classes when composing components dynamically.

Key Source Files That Define the Stack

Understanding the UI framework requires examining these specific files in the repository:

Summary

  • The makeplane/plane web directory uses React as the foundational UI library
  • React Router handles all client-side routing, configured through the Vite plugin in vite.config.ts
  • Tailwind CSS provides the styling system, with tailwind-merge managing class compositions in packages/propel/src/utils/classname.tsx
  • The @plane/ui package offers internal reusable components built on React and Headless UI
  • The architecture is configured as a Vite-based SPA rather than using Next.js or a similar meta-framework

Frequently Asked Questions

Does the Plane web app use Next.js?

No, the Plane web app does not use Next.js. According to the source code in apps/web/vite.config.ts, the application uses Vite with the React Router plugin configured for client-side rendering. This creates a single-page application architecture rather than a server-rendered Next.js application.

What is the @plane/ui package based on?

The @plane/ui package is built on top of React and Headless UI. Headless UI provides unstyled, accessible component primitives (like tooltips, buttons, and dialogs), which the Plane team styles with Tailwind CSS. You can see this pattern in packages/ui/src/tooltip/tooltip.tsx where Headless UI patterns are implemented with custom Tailwind styling.

How is Tailwind CSS integrated into the Plane web components?

Tailwind CSS is integrated through utility classes applied directly to JSX elements. The codebase uses tailwind-merge (utilized in packages/propel/src/utils/classname.tsx) to safely combine and conditionalize Tailwind classes. This approach allows developers to write styling logic inline without separate CSS files.

Where can I find example React components in the Plane web directory?

Example React components are located throughout apps/web/core/components/. Specifically, apps/web/core/components/workspace/sidebar/workspace-menu.tsx provides a clear example of how components import React and utilize the internal UI library. These files demonstrate the standard patterns for building UIs within the Plane codebase.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →