### Project Setup and Commands
Source: https://context7.com/feature-sliced/examples/llms.txt
Provides essential commands for setting up and running the example project, including installation, development server, linting, and dependency analysis.
```bash
# SolidJS with layout
cd examples/solidjs-with-layout
pnpm install
pnpm dev # starts Vite dev server on port 3000
pnpm lint:fsd # runs steiger to validate FSD layer rules
pnpm dep-cruiser:preview # generates dependency-graph-preview.svg
```
--------------------------------
### Install and Run Example
Source: https://github.com/feature-sliced/examples/blob/master/examples/solidjs-with-layout/README.md
Instructions for setting up and running the SolidJS example using npm, Yarn, or pnpm.
```bash
npm run dev
yarn dev
pnpm dev
```
--------------------------------
### Install and Run Electron Example
Source: https://context7.com/feature-sliced/examples/llms.txt
Navigate to the Electron example directory, install dependencies, and run the development or build scripts.
```bash
cd examples/electron
npm install
npm run dev
npm run build
npm run build:win
```
--------------------------------
### Router and Page Registration in SolidJS (app/App.tsx)
Source: https://context7.com/feature-sliced/examples/llms.txt
This example demonstrates configuring the router in the `app` layer using `@solidjs/router`. The `BaseLayout` is passed as the `root` prop, ensuring all routes are automatically wrapped by the shared layout.
```tsx
// src/app/App.tsx
import { Route, Router } from '@solidjs/router'
import { BaseLayout } from './layouts'
import { HomePage } from '@/pages/home'
import { AboutPage } from '@/pages/about'
import { NotFound } from '@/pages/404'
export default function App() {
return (
// BaseLayout wraps all routes — injected at the router root level
)
}
// src/app/entry.tsx — application bootstrap
import { render } from 'solid-js/web'
import './entry.css'
import App from './App'
const root = document.getElementById('root')
render(() => , root!)
```
--------------------------------
### Electron Main Process Entry and Window Creation
Source: https://context7.com/feature-sliced/examples/llms.txt
Sets up the main process entry point, registers IPC handlers, and creates the primary browser window. Ensures IPC handlers are registered before the window is shown.
```typescript
// src/app/main/index.ts
import { app, BrowserWindow } from 'electron'
import { createWindow } from './create-window'
import { ipcHandlers } from './ipc-handlers'
;(async () => {
await app.whenReady()
ipcHandlers() // register IPC before window opens
createWindow()
app.on('activate', () => {
if (!BrowserWindow.getAllWindows().length) createWindow()
})
})()
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
```
```typescript
// src/app/main/create-window.ts
import { join } from 'path'
import { BrowserWindow } from 'electron'
export const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 640,
height: 320,
show: false,
title: 'Feature-Sliced Design',
resizable: false,
autoHideMenuBar: true,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
},
})
mainWindow.on('ready-to-show', () => mainWindow.show())
if (process.env['ELECTRON_RENDERER_URL']) {
void mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
void mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
```
--------------------------------
### Vite Configuration for SolidJS
Source: https://context7.com/feature-sliced/examples/llms.txt
Configures Vite for SolidJS projects, enabling Hot Module Replacement and path aliases for FSD layer imports.
```ts
// vite.config.mts
import { defineConfig } from 'vite'
import solidPlugin from 'vite-plugin-solid'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [
solidPlugin(),
tsconfigPaths(), // enables @/* path aliases from tsconfig.json
],
server: { port: 3000 },
build: { target: 'esnext' },
})
```
```json
// tsconfig.json — path alias for FSD layer imports
// "@/*": ["*"] maps @/shared/ui → src/shared/ui, etc.
```
--------------------------------
### Smart Layout Composition in SolidJS (app/layouts)
Source: https://context7.com/feature-sliced/examples/llms.txt
This 'smart' component, located in the `app` layer, composes concrete widgets into the dumb `` shell. This pattern adheres to FSD by preventing higher-layer widgets from being imported into the `shared` layer.
```tsx
// src/app/layouts/BaseLayout.tsx
import type { RouteSectionProps } from '@solidjs/router'
import { Layout } from '@/shared/ui' // lower layer → allowed
import { Header } from '@/widgets/header' // widget layer → allowed from app
type Props = RouteSectionProps
/**
* FSD Best practice:
* (1) Dumb layout grid lives in shared/ui/Layout
* (2) Smart layout with widget composition lives here (app layer)
*/
export function BaseLayout(props: Props) {
return (
}>
{props.children}
)
}
// src/app/layouts/index.ts
export { BaseLayout } from './BaseLayout'
```
--------------------------------
### Dumb Layout Component in SolidJS (shared/ui)
Source: https://context7.com/feature-sliced/examples/llms.txt
This component serves as a reusable presentational shell for layout grids. It resides in the `shared` layer and accepts a `headerSlot` render prop to remain decoupled from specific widgets.
```tsx
// src/shared/ui/Layout/Layout.tsx
import { MetaProvider, Title } from '@solidjs/meta'
import type { JSXElement } from 'solid-js'
import { Suspense } from 'solid-js'
import css from './Layout.module.css'
type Props = {
headerSlot: JSXElement
children: JSXElement
}
export function Layout(props: Props) {
return (
solidjs-with-layout
{props.children}
)
}
// src/shared/ui/index.ts — public API barrel
export { Layout } from './Layout/Layout'
```
--------------------------------
### Global Window Type Extension for Electron API
Source: https://context7.com/feature-sliced/examples/llms.txt
Augments the global Window interface to include the 'electron' property, providing type safety for Electron APIs exposed via the preload script.
```typescript
// src/shared/ipc/ipc.d.ts — augments the global Window interface
import { TElectronAPI } from './preload'
declare global {
interface Window {
electron: TElectronAPI
// Provides full TypeScript autocomplete for window.electron.*
}
}
```
--------------------------------
### Electron Preload Script for IPC Exposure
Source: https://context7.com/feature-sliced/examples/llms.txt
Safely exposes a typed IPC API to the renderer process using `contextBridge`, preventing direct Node.js access.
```ts
// src/app/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron'
import { CHANNELS, type TElectronAPI } from 'shared/ipc'
const API: TElectronAPI = {
// Synchronous call — returns user data immediately
[CHANNELS.GET_USER_DATA]: () =>
ipcRenderer.sendSync(CHANNELS.GET_USER_DATA),
// Async call — sends user data to main process
[CHANNELS.SAVE_USER]: args =>
ipcRenderer.invoke(CHANNELS.SAVE_USER, args),
} as const
contextBridge.exposeInMainWorld('electron', API)
// Renderer can now call: window.electron.GET_USER_DATA()
// or: window.electron.SAVE_USER({ name: 'Alice' })
```
--------------------------------
### Renderer-Side IPC Calls for User Data
Source: https://context7.com/feature-sliced/examples/llms.txt
Provides wrapper functions in the renderer process to interact with main process IPC handlers. Uses 'window.electron' exposed by the preload script.
```typescript
// src/renderer/pages/user/ipc/get-user.ts
import { CHANNELS } from 'shared/ipc'
export const getUser = () => {
// Synchronous IPC — blocks until main process responds
const user = window.electron[CHANNELS.GET_USER_DATA]()
// Fallback if main returns nothing
return user ?? { name: 'John Donte', email: 'john.donte@example.com' }
}
```
```typescript
// src/renderer/pages/user/ipc/save-user.ts
import { CHANNELS } from 'shared/ipc'
export const saveUser = (name: string) => {
// Async IPC — fire-and-forget to main process
window.electron[CHANNELS.SAVE_USER]({ name })
}
```
--------------------------------
### Main Process IPC Handlers for User Feature
Source: https://context7.com/feature-sliced/examples/llms.txt
Defines synchronous and asynchronous IPC handlers for user data within a feature slice. Requires 'shared/ipc' for channel definitions.
```typescript
// src/main/features/user/ipc/send-user.ts
// Handles GET_USER_DATA — responds synchronously via ev.returnValue
import { ipcMain } from 'electron'
import { CHANNELS } from 'shared/ipc'
export const sendUser = () => {
ipcMain.on(CHANNELS.GET_USER_DATA, ev => {
ev.returnValue = {
name: 'John Doe',
email: 'john.doe@example.com',
}
})
}
```
```typescript
// src/main/features/user/ipc/get-user.ts
// Handles SAVE_USER — receives and processes user data asynchronously
import { ipcMain } from 'electron'
import { CHANNELS, IEvents } from 'shared/ipc'
export const getUser = () => {
ipcMain.handle(
CHANNELS.SAVE_USER,
(_, args: IEvents[typeof CHANNELS.SAVE_USER]['args']) => {
console.log('Saving user:', args) // { name: 'Alice' }
}
)
}
```
```typescript
// src/app/main/ipc-handlers.ts — registers all handlers at startup
import { getUser, sendUser } from '#/features/user'
export const ipcHandlers = () => {
getUser()
sendUser()
}
```
--------------------------------
### React Component for User Interaction
Source: https://context7.com/feature-sliced/examples/llms.txt
A React component that fetches user data using synchronous IPC and allows saving user input via asynchronous IPC. It utilizes local state for input management.
```typescript
// src/renderer/pages/user/ui/user.tsx — React component using the IPC wrappers
import { ChangeEvent, useState } from 'react'
import { saveUser } from '../ipc/save-user'
import { getUser } from '../ipc/get-user'
export const User = () => {
const user = getUser() // { name: 'John Doe', email: 'john.doe@example.com' }
const [value, setValue] = useState('')
return (
<>
{JSON.stringify(user)}
>
)
}
```
--------------------------------
### Header Widget in SolidJS (widgets/header)
Source: https://context7.com/feature-sliced/examples/llms.txt
The `Header` widget encapsulates navigation elements and resides in the `widgets` layer. It is composed into the application layout via `BaseLayout` and is not directly imported by pages or features.
```tsx
// src/widgets/header/ui/Header.tsx
import css from './Header.module.css'
export function Header() {
return (
)
}
// src/widgets/header/index.ts — public API
export { Header } from './ui/Header'
```
--------------------------------
### SolidJS Page Components
Source: https://context7.com/feature-sliced/examples/llms.txt
Defines self-contained page components that import only from lower layers like shared, entities, and features.
```tsx
// src/pages/home.tsx
import { Title } from '@solidjs/meta'
export function HomePage() {
return (
Home
examples/solidjs-with-layout
Split layout to dumb component (shared) and smart component (app layer).
)
}
```
```tsx
// src/pages/about.tsx
import { Title } from '@solidjs/meta'
export function AboutPage() {
return (
About
About
Visit feature-sliced/examples for more examples.
)
}
```
```tsx
// src/pages/404.tsx
import { Title } from '@solidjs/meta'
import { A } from '@solidjs/router'
export function NotFound() {
return (
Not Found
Page Not Found
Return to main page
)
}
```
--------------------------------
### Shared IPC Contract for Electron
Source: https://context7.com/feature-sliced/examples/llms.txt
Defines typed IPC channel names and event shapes for consistent communication between Electron's main and renderer processes.
```ts
// src/shared/ipc/channels.ts
export const CHANNELS = {
GET_USER_DATA: 'GET_USER_DATA',
SAVE_USER: 'SAVE_USER',
} as const
export type TChannelKeys = keyof typeof CHANNELS
```
```ts
// src/shared/ipc/events.ts — typed argument/response shapes per channel
import { CHANNELS } from './channels'
export interface IEvents {
[CHANNELS.GET_USER_DATA]: {
args: void
response?: { name: string; email: string }
}
[CHANNELS.SAVE_USER]: {
args: { name: string }
response: void
}
}
```
```ts
// src/shared/ipc/preload.ts — type-safe API surface exposed to renderer
import { CHANNELS } from './channels'
import type { IEvents } from './events'
type TOptionalArgs = T extends void ? [] : [args: T]
export type TElectronAPI = {
[K in keyof typeof CHANNELS]: (
...args: TOptionalArgs
) => IEvents[typeof CHANNELS[K]]['response']
}
```
```ts
// src/shared/ipc/index.ts — barrel export
export { CHANNELS } from './channels'
export type { TElectronAPI } from './preload'
export type { IEvents } from './events'
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.