xiaohongshu
xiaohongshu
electron-fsd
This skill should be used when developing Electron applications with Feature-Sliced Design (FSD) architecture and React 19. Triggers on requests to create components, features, entities, widgets, or pages following FSD layer structure. Also applies when setting up Electron main/preload/renderer p...
Full skill instructions
This skill provides guidance for developing Electron applications using Feature-Sliced Design (FSD) architecture with React 19. It covers the three-process model (Main, Preload, Renderer) and FSD layer organization for the Renderer process.
┌─────────────────────────────────────────────────────────────┐
│ Main Process (Node.js) │
│ ├─ app/main.ts - App lifecycle, BrowserWindow │
│ ├─ app/ipc-handler.ts - IPC routing to services │
│ ├─ services/ - Business logic (PdfMergeService) │
│ └─ workers/ - CPU-intensive tasks │
├─────────────────────────────────────────────────────────────┤
│ Preload (Isolated) │
│ └─ index.ts - ContextBridge (window.api) │
├─────────────────────────────────────────────────────────────┤
│ Renderer (React + FSD) │
│ ├─ shared/ - Common utilities, UI, types │
│ ├─ entities/ - READ (data display) │
│ ├─ features/ - CUD (user actions) │
│ ├─ widgets/ - Feature composition │
│ └─ pages/ - Route entry points │
└─────────────────────────────────────────────────────────────┘
| Layer | Responsibility | IPC Direction | Example |
|---|---|---|---|
entities | Data display only | READ | document-card.tsx, page-thumbnail.tsx |
features | User actions | CUD | use-merge-command.ts, merge-toolbar.tsx |
widgets | Feature composition | - | merge-workspace.tsx |
shared | Cross-cutting concerns | - | ipc-client.ts, types, UI components |
To create a new entity for displaying data:
src/renderer/entities/{entity-name}/entities/pdf-document/
├─ ui/
│ └─ document-card.tsx # Display component
└─ model/
└─ use-pdf-metadata.ts # Data fetching hook (READ)
To create a new feature for user actions:
src/renderer/features/{feature-name}/features/pdf-merge/
├─ ui/
│ ├─ merge-toolbar.tsx # Action UI
│ └─ merge-file-grid.tsx # Interactive grid with DnD
└─ model/
└─ use-merge-command.ts # IPC command hook
To compose features and entities into workspace:
src/renderer/widgets/{widget-name}/widgets/merge-workspace/
└─ merge-workspace.tsx
// merge-workspace.tsx
export function MergeWorkspace() {
const { files, addFiles, removeFile } = useMergeContext();
return (
<>
<MergeToolbar onAddFiles={addFiles} />
<MergeFileGrid files={files} onRemove={removeFile} />
</>
);
}
| Element | Convention | Example |
|---|---|---|
| Folders & files | kebab-case | pdf-merge-service.ts |
| React components | PascalCase | MergeWorkspace |
| Hooks | camelCase with use prefix | useMergeCommand |
| Types/interfaces | PascalCase | MergeRequest |
| Services | PascalCase + Service | PdfMergeService |
| Workers | kebab-case + worker | merge-worker.ts |
// ❌ React 18 (forwardRef)
const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => (
<input ref={ref} {...props} />
));
// ✅ React 19 (ref as regular prop)
interface InputProps {
ref?: React.Ref<HTMLInputElement>;
placeholder?: string;
}
function Input({ ref, ...props }: InputProps) {
return <input ref={ref} {...props} />;
}
// ❌ React 18
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
// ✅ React 19
<ThemeContext value={theme}>
{children}
</ThemeContext>
// ✅ React 19: use() for Promise (requires Suspense)
import { use, Suspense } from 'react';
function FileList({ filesPromise }: { filesPromise: Promise<PdfFile[]> }) {
const files = use(filesPromise);
return files.map(f => <FileCard key={f.id} file={f} />);
}
// Usage with Suspense
<Suspense fallback={<Loading />}>
<FileList filesPromise={fetchFiles()} />
</Suspense>
// ✅ React 19: use() for Context (conditional allowed)
function ConditionalTheme({ show }: { show: boolean }) {
if (show) {
const theme = use(ThemeContext);
return <div className={theme}>Themed</div>;
}
return null;
}
// ✅ React 19: Form action with state
import { useActionState } from 'react';
function MergeForm() {
const [state, submitAction, isPending] = useActionState(
async (prev, formData) => {
const files = formData.getAll('files');
const result = await window.api.merge(files);
return result;
},
null
);
return (
<form action={submitAction}>
<input type="file" name="files" multiple disabled={isPending} />
<button disabled={isPending}>
{isPending ? 'Merging...' : 'Merge PDFs'}
</button>
</form>
);
}
// ✅ React 19: Optimistic updates
import { useOptimistic } from 'react';
function FileList({ files }: { files: PdfFile[] }) {
const [optimisticFiles, addOptimistic] = useOptimistic(
files,
(state, newFile: PdfFile) => [...state, { ...newFile, pending: true }]
);
async function handleAdd(file: File) {
const tempFile = { id: 'temp', name: file.name, pending: true };
addOptimistic(tempFile);
await window.api.addFile(file);
}
return (
<div>
{optimisticFiles.map(f => (
<FileCard key={f.id} file={f} opacity={f.pending ? 0.5 : 1} />
))}
</div>
);
}
// ✅ React 19: ref cleanup function
function AutoFocusInput() {
return (
<input
ref={(el) => {
if (el) el.focus();
return () => {
// cleanup when element removed
console.log('Input unmounted');
};
}}
/>
);
}
// ❌ Avoid
function process(data: { id: string; name: string }) {}
// ✅ Preferred
interface ProcessData { id: string; name: string }
function process(data: ProcessData) {}
// Define constants
export const MERGE_STATUS = {
IDLE: 'idle',
PENDING: 'pending',
COMPLETE: 'complete',
} as const;
// Create union type
type ValueOf<T> = T[keyof T];
type MergeStatus = ValueOf<typeof MERGE_STATUS>;
// Usage
const status: MergeStatus = MERGE_STATUS.PENDING;
fsd-layers.md - Detailed FSD layer documentationelectron-patterns.md - Electron-specific patternsTo delete unused example files in scripts/ and assets/ directories as this skill focuses on architectural guidance.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience