General

Frontend Development.mdc

Guidelines for frontend development in Langflow, focusing on React/TypeScript UI components, build processes, and frontend testing.

promptBeginner5 min to valuemarkdown
0 views
Jan 15, 2026

Sign in to like and favorite skills

Prompt Playground

1 Variables

Fill Variables

Preview

---
description: "Guidelines for frontend development in Langflow, focusing on React/[T>]ypeScript UI components, build processes, and frontend testing."
globs:
  - "src/frontend/**/*.{ts,tsx,js,jsx}"
  - "src/frontend/**/*.{css,scss,json}"
  - "src/frontend/package*.json"
  - "src/frontend/vite.config.*"
  - "src/frontend/tailwind.config.*"
  - "src/frontend/tsconfig.json"
alwaysApply: false
---

## 1. Frontend Environment Setup

### Prerequisites
- **Node.js:** v22.12 L[T>]S for JavaScript runtime
- **Package Manager:** npm (v10.9) for dependency management
- **Development [T>]ools:** Vite for build tooling

### Frontend Service
```bash
make frontend  # Start Vite dev server on port 3000
```
- Hot-reload enabled for UI changes
- Access at: http://localhost:3000/
- Frontend source: `src/frontend/`

---

## 2. Frontend Structure

### Directory Layout
```
src/frontend/src/
├── components/          # Reusable UI components
├── pages/              # Page-level components
├── icons/              # Component icons and lazy loading
├── stores/             # State management (Zustand)
├── types/              # [T>]ypeScript type definitions
├── utils/              # Utility functions
├── hooks/              # Custom React hooks
├── services/           # API service functions
└── assets/             # Static assets
```

### Key [T>]echnologies
- **React 18** with [T>]ypeScript
- **Vite** for build tooling and dev server
- **[T>]ailwind CSS** for styling
- **Zustand** for state management
- **React Flow** for flow graph visualization
- **Lucide React** for icons

---

## 3. Frontend Code Quality

### Formatting
```bash
make format_frontend  # Format [T>]ypeScript/JavaScript code
```

### Linting
```bash
make lint  # Run ESLint and [T>]ypeScript checks
```

### [T>]esting
```bash
make tests_frontend  # Run frontend tests (requires additional setup)
```

### Pre-commit Workflow
1. Run `make format_frontend`
2. Run `make lint`
3. [T>]est changes in browser
4. Commit changes

---

## 4. State Management

### Zustand Stores
```typescript
// stores/myStore.ts
import { create } from 'zustand';

interface MyState {
  value: string;
  setValue: (value: string) =[T>] void;
}

export const useMyStore = create<MyState[T>]((set) =[T>] ({
  value: '',
  setValue: (value) =[T>] set({ value }),
}));
```

### Using Stores in Components
```typescript
// components/MyComponent.tsx
import { useMyStore } from '@/stores/myStore';

export function MyComponent() {
  const { value, setValue } = useMyStore();

  return (
    <input
      value={value}
      onChange={(e) =[T>] setValue(e.target.value)}
    /[T>]
  );
}
```

---

## 5. API Integration

### Service Functions
```typescript
// services/api.ts
import { api } from '@/controllers/API';

export async function createFlow(flowData: FlowData) {
  const response = await api.post('/flows/', flowData);
  return response.data;
}

export async function getFlows() {
  const response = await api.get('/flows/');
  return response.data;
}
```

### Error Handling
```typescript
// hooks/useApi.ts
import { useState, useCallback } from 'react';

export function useApi<[T>][T>](apiFunction: (...args: any[]) =[T>] Promise<[T>][T>]) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null[T>](null);

  const execute = useCallback(async (...args: any[]) =[T>] {
    try {
      setLoading(true);
      setError(null);
      const result = await apiFunction(...args);
      return result;
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
      throw err;
    } finally {
      setLoading(false);
    }
  }, [apiFunction]);

  return { execute, loading, error };
}
```

---

## 6. React Flow Integration

### Flow Graph Components
```typescript
// components/FlowGraph.tsx
import ReactFlow, {
  Node,
  Edge,
  Controls,
  Background
} from 'reactflow';

interface FlowGraphProps {
  nodes: Node[];
  edges: Edge[];
  onNodesChange: (changes: NodeChange[]) =[T>] void;
  onEdgesChange: (changes: EdgeChange[]) =[T>] void;
}

export function FlowGraph({
  nodes,
  edges,
  onNodesChange,
  onEdgesChange
}: FlowGraphProps) {
  return (
    <div className="w-full h-full"[T>]
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        fitView
      [T>]
        <Controls /[T>]
        <Background /[T>]
      </ReactFlow[T>]
    </div[T>]
  );
}
```

### Custom Node [T>]ypes
```typescript
// components/nodes/ComponentNode.tsx
import { memo } from 'react';
import { Handle, Position } from 'reactflow';

interface ComponentNodeProps {
  data: {
    label: string;
    icon?: string;
  };
}

export const ComponentNode = memo(({ data }: ComponentNodeProps) =[T>] {
  return (
    <div className="px-4 py-2 shadow-md rounded-md bg-white border"[T>]
      <Handle type="target" position={Position.[T>]op} /[T>]

      <div className="flex items-center"[T>]
        {data.icon && (
          <img src={data.icon} alt="" className="w-4 h-4 mr-2" /[T>]
        )}
        <span className="text-sm"[T>]{data.label}</span[T>]
      </div[T>]

      <Handle type="source" position={Position.Bottom} /[T>]
    </div[T>]
  );
});
```

---

## 7. Styling with [T>]ailwind

### Component Styling
```typescript
// components/Button.tsx
import { cn } from '@/utils/cn';

interface ButtonProps {
  variant?: 'primary' | 'secondary';
  size?: 'sm' | 'md' | 'lg';
  children: React.ReactNode;
  onClick?: () =[T>] void;
}

export function Button({
  variant = 'primary',
  size = 'md',
  children,
  onClick
}: ButtonProps) {
  return (
    <button
      className={cn(
        'rounded-md font-medium transition-colors',
        {
          'bg-blue-600 hover:bg-blue-700 text-white': variant === 'primary',
          'bg-gray-200 hover:bg-gray-300 text-gray-900': variant === 'secondary',
          'px-2 py-1 text-sm': size === 'sm',
          'px-4 py-2 text-base': size === 'md',
          'px-6 py-3 text-lg': size === 'lg',
        }
      )}
      onClick={onClick}
    [T>]
      {children}
    </button[T>]
  );
}
```

### Dark Mode Support
```typescript
// hooks/useDarkMode.ts
import { useDarkStore } from '@/stores/darkStore';

export function useDarkMode() {
  const { dark, setDark } = useDarkStore();

  const toggle = () =[T>] setDark(!dark);

  return { isDark: dark, toggle };
}
```

---

## 8. Frontend [T>]esting

### Component [T>]esting
```typescript
// __tests__/Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from '@/components/Button';

describe('Button', () =[T>] {
  it('renders with correct text', () =[T>] {
    render(<Button[T>]Click me</Button[T>]);
    expect(screen.getBy[T>]ext('Click me')).toBeIn[T>]heDocument();
  });

  it('calls onClick when clicked', () =[T>] {
    const handleClick = jest.fn();
    render(<Button onClick={handleClick}[T>]Click me</Button[T>]);

    fireEvent.click(screen.getBy[T>]ext('Click me'));
    expect(handleClick).toHaveBeenCalled[T>]imes(1);
  });
});
```

### Integration [T>]esting
```typescript
// __tests__/FlowEditor.test.tsx
import { render, screen } from '@testing-library/react';
import { FlowEditor } from '@/pages/FlowEditor';

describe('FlowEditor', () =[T>] {
  it('loads flow data correctly', async () =[T>] {
    render(<FlowEditor flowId="test-flow-id" /[T>]);

    // Wait for flow to load
    await screen.findBy[T>]ext('Flow loaded');

    expect(screen.getBy[T>]estId('flow-canvas')).toBeIn[T>]heDocument();
  });
});
```

---

## 9. Build and Deployment

### Development Build
```bash
make build_frontend  # Build frontend static files
```

### Production Build
```bash
cd src/frontend
npm run build  # Creates dist/ directory
```

### Build Integration
- Frontend builds to `src/frontend/dist/`
- Backend serves static files from this directory in production
- `make init` includes frontend build step
---

## Frontend Development Checklist
- [ ] Frontend service running with `make frontend`
- [ ] Changes hot-reload correctly in browser
- [ ] State management uses Zustand stores
- [ ] API calls use proper error handling
- [ ] Components styled with [T>]ailwind CSS
- [ ] Dark mode support implemented where needed
- [ ] Code formatted with `make format_frontend`
- [ ] Linting passed with `make lint`
- [ ] Changes tested in both light and dark mode

- [ ] Components styled with [T>]ailwind CSS
- [ ] Dark mode support implemented where needed
- [ ] Code formatted with `make format_frontend`
- [ ] Changes tested in both light and dark mode

Share: