### Install Dependencies Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/README.md Run this command to install project dependencies. ```bash npm install ``` -------------------------------- ### Install Dependencies in Marketing App Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/README.md Navigate to the marketing app directory and install its dependencies. ```bash cd apps/marketing && npm install ``` -------------------------------- ### UIFork Version File Naming Convention Examples Source: https://context7.com/sambernhardt/uifork/llms.txt Illustrates the filename pattern and resulting keys/display names for versioned UI components. ```text ComponentName.v{major}[_{minor}].{ext} Button.v1.tsx → key "v1", displayed as "V1" Button.v2.tsx → key "v2", displayed as "V2" Button.v1_1.tsx → key "v1_1", displayed as "V1.1" Button.v1_2.tsx → key "v1_2", displayed as "V1.2" Button.v3.tsx → key "v3", displayed as "V3" ``` -------------------------------- ### Initialize a component with UIFork CLI Source: https://github.com/sambernhardt/uifork/blob/main/README.md Initializes versioning for a component by providing its path. The `-w` flag can be used to start the watch server immediately. ```bash npx uifork src/components/Dropdown.tsx ``` ```bash npx uifork init src/components/Dropdown.tsx ``` -------------------------------- ### Install UIFork Package Source: https://github.com/sambernhardt/uifork/blob/main/README.md Install the UIFork package using npm. This is the initial step for integrating UIFork into your project. ```bash npm install uifork ``` -------------------------------- ### Install Sandbox Dependencies (Root) Source: https://github.com/sambernhardt/uifork/blob/main/apps/sandbox/README.md Alternative command to install sandbox dependencies when run from the project root directory. ```bash cd apps/sandbox && npm install ``` -------------------------------- ### Start UIFork Watch Server Source: https://context7.com/sambernhardt/uifork/llms.txt Start the file-watcher and WebSocket server using `npx uifork watch`. This command scans for version files, regenerates them, and enables the widget to connect for version management. ```bash npx uifork watch # current directory, port 3030 npx uifork watch ./src # watch only src/ npx uifork watch --port 3002 # custom port npx uifork watch ./src --port 3002 # both ``` -------------------------------- ### Initialize Component Versioning (Shorthand and Watch) Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Initialize versioning for a component using the shorthand command. The -w flag starts the watch server immediately after initialization. ```bash npx uifork src/components/Dropdown.tsx ``` ```bash npx uifork src/components/Dropdown.tsx -w # Start watching after init ``` -------------------------------- ### Start UIFork Watch Server Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Start the watch server to enable communication with the UIFork widget. You can specify a directory to watch and a custom port. ```bash npx uifork watch # Watch current directory (port 3030) ``` ```bash npx uifork watch ./src # Watch specific directory ``` ```bash npx uifork watch --port 3002 # Custom port ``` ```bash npx uifork watch ./src --port 3002 # Directory + custom port ``` -------------------------------- ### UIFork File Structure Example Source: https://github.com/sambernhardt/uifork/blob/main/README.md Illustrates the typical file structure for a component managed by UIFork, including the wrapper, version config, and individual version files. ```text src/components/ ├── Button.tsx # Wrapper (import this) ├── Button.versions.ts # Version config ├── Button.v1.tsx # Original ├── Button.v2.tsx # More versions └── Button.v1_1.tsx # Sub-versions (v1.1, etc.) ``` -------------------------------- ### Start uifork Watcher Source: https://context7.com/sambernhardt/uifork/llms.txt Starts the uifork watcher process, optionally specifying the port via the PORT environment variable. ```bash PORT=3002 npx uifork watch ``` -------------------------------- ### Start the UIFork watch server Source: https://github.com/sambernhardt/uifork/blob/main/README.md Starts the watch server to enable communication between the UI widget and your codebase. It can monitor the current directory, a specific directory, or use a custom port. ```bash npx uifork watch # current directory (port 3030) ``` ```bash npx uifork watch ./src # specific directory ``` ```bash npx uifork watch --port 3002 # custom port ``` ```bash npx uifork watch ./src --port 3002 # directory + custom port ``` -------------------------------- ### Initialize Component Versioning (Explicit and Watch) Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Use the explicit 'init' command to initialize versioning, with the option to start the watch server using the -w flag. ```bash npx uifork init src/components/Dropdown.tsx ``` ```bash npx uifork init src/components/Dropdown.tsx -w # Start watching after init ``` ```bash npx uifork init src/components/Dropdown.tsx --export Button # Specify which export to fork ``` -------------------------------- ### Run Development Server in Next.js Source: https://github.com/sambernhardt/uifork/blob/main/examples/next-app-router/README.md Use these commands to start the Next.js development server. Open http://localhost:3000 in your browser to view the application. ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` -------------------------------- ### List Components via REST API Source: https://context7.com/sambernhardt/uifork/llms.txt Fetches a list of discovered components and their versions from the uifork server using a GET request. ```bash # List components via REST curl http://localhost:3030/components # { # "components": [ # { "name": "Button", "path": "/…/Button.versions.ts", "versions": ["v1","v2","v3"] }, # { "name": "ContactCard", "path": "/…/ContactCard.versions.ts", "versions": ["v1","v2"] } # ] # } ``` -------------------------------- ### Generated Wrapper Component Example Source: https://github.com/sambernhardt/uifork/blob/main/README.md This is an example of a generated wrapper component that UIFork creates. It dynamically imports and renders the currently active version of a component based on localStorage. ```tsx // Button.tsx (generated wrapper) import { getActiveVersion } from "./Button.versions"; export default function Button(props) { const Version = getActiveVersion(); return ; } ``` -------------------------------- ### Initialize Component Versioning with UIFork CLI Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Use the npx uifork command to initialize versioning for a React component. This command converts the component, generates version tracking files, and can optionally start a watch server. ```bash npx uifork src/components/Button.tsx ``` ```bash npx uifork init src/components/Button.tsx ``` -------------------------------- ### Run UIFork Watch Server Source: https://github.com/sambernhardt/uifork/blob/main/README.md Start the UIFork watch server to enable filesystem monitoring for new version files and allow the UIFork component to manage versions. You can specify a custom port via CLI arguments or the PORT environment variable. ```bash # CLI: run watch server on port 3002 npx uifork watch --port 3002 npx uifork watch ./src --port 3002 # Or use the PORT environment variable PORT=3002 npx uifork watch ``` -------------------------------- ### Watch for Component File Changes Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Starts a watch server that monitors file system changes for component versions and automatically regenerates version configuration files. ```bash npx uifork watch ``` -------------------------------- ### Integrate UIFork Component Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/README.md Example of how to import and use the UIFork component within a React application. It's conditionally rendered based on the environment mode. ```tsx import { UIFork } from "uifork"; function App() { return ( <> {import.meta.env.MODE !== "production" && } ); } ``` -------------------------------- ### Create New Component Version Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Creates a new, empty version for a component. Alternatively, it can fork an existing version to start iterating from a specific point. ```bash # Create empty version npx uifork new Button # Or fork existing version npx uifork fork Button v1 ``` -------------------------------- ### Build and Run Marketing App with Built Package Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/README.md First, build the uifork package, then run the marketing app to test against the built workspace package. This simulates consumer usage. ```bash cd ../../packages/uifork && npm run build cd ../../apps/marketing && npm run dev ``` -------------------------------- ### Initialize UIFork for a Component Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Initializes UIFork for a given component file, setting up the versioning structure. ```bash npx uifork init src/components/Button.tsx ``` -------------------------------- ### Initialize a Component for Versioning Source: https://github.com/sambernhardt/uifork/blob/main/README.md Use the npx uifork command to initialize a component for versioning. This command generates necessary scaffolding, including a `versions.ts` file, and handles both default and named exports. ```bash npx uifork {path/to/component} ``` ```bash npx uifork init src/components/Button.tsx --export Button ``` ```bash npx uifork init src/components/Button.tsx --export default ``` -------------------------------- ### Promote a version to main with UI Fork CLI Source: https://context7.com/sambernhardt/uifork/llms.txt Use the `promote` command to replace the main component file with the content of a chosen version. It then deletes all version files, the versions index, and the wrapper file, leaving a single clean component file. ```bash npx uifork promote Button v2 # ✅ Replaced Button.tsx with content from v2 # Deleted: Button.v1.tsx, Button.v2.tsx, Button.versions.ts # ✅ Promotion complete! ``` -------------------------------- ### Build and Test Built Package Source: https://github.com/sambernhardt/uifork/blob/main/apps/sandbox/README.md Commands to build the uifork package and then run the sandbox to test against the built version. This simulates consumer usage. ```bash # Build the uifork package first cd ../../packages/uifork && npm run build # Then run sandbox cd ../../apps/sandbox && npm run dev ``` -------------------------------- ### Scaffold a Component for Versioning with UIFork CLI Source: https://context7.com/sambernhardt/uifork/llms.txt Use the `npx uifork init` command to convert an existing component into a version-switchable wrapper. This command renames the original file, generates an index file, and replaces the component with a `ForkedComponent` wrapper. ```bash # Shorthand — pass the path directly npx uifork src/components/Button.tsx # Explicit form npx uifork init src/components/Button.tsx # Start watch server immediately after init npx uifork init src/components/Button.tsx -w # When the file exports multiple components, specify which one to fork npx uifork init src/components/Form.tsx --export SubmitButton npx uifork init src/components/Form.tsx --export default ``` -------------------------------- ### Preview Production Build Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/README.md Build the application and then preview it. This command is used after updating the package.json to point to a specific published version. ```bash npm run build && npm run preview ``` -------------------------------- ### Create a blank version with UI Fork CLI Source: https://context7.com/sambernhardt/uifork/llms.txt Use the `new` command to create a new empty version file pre-populated with a minimal component template. Auto-increments the version number or use an explicit ID. ```bash npx uifork new Button # auto-increments (e.g. Button.v4.tsx) npx uifork new Button v5 # explicit ID ``` ```tsx import React from 'react'; export default function ButtonV4() { return (
V4
); } ``` -------------------------------- ### Initialize UIFork for Components Source: https://context7.com/sambernhardt/uifork/llms.txt Use this command to initialize UIFork for specific components within your React project. ```bash npx uifork init ``` -------------------------------- ### Promote a component version Source: https://github.com/sambernhardt/uifork/blob/main/README.md Use this command to promote a specific version of a component to be the main component. It replaces the main component file with the specified version and removes all versioning files. ```bash npx uifork promote Button v3 ``` -------------------------------- ### Initialize Theme from Local Storage Source: https://github.com/sambernhardt/uifork/blob/main/apps/sandbox/index.html Applies the theme stored in local storage or defaults to 'system'. It removes existing theme classes and adds the appropriate one based on the stored value or system preference. ```javascript UIFork Sandbox (function () { const theme = localStorage.getItem("vite-ui-theme") || "system"; const root = document.documentElement; root.classList.remove("light", "dark"); if (theme === "system") { const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; root.classList.add(systemTheme); } else { root.classList.add(theme); } })(); ``` -------------------------------- ### npx uifork new Source: https://context7.com/sambernhardt/uifork/llms.txt Creates a new empty version file pre-populated with a minimal component template. ```APIDOC ## `npx uifork new` — Create a blank version Creates a new empty version file pre-populated with a minimal component template. ### Usage ```bash npx uifork new Button # auto-increments (e.g. Button.v4.tsx) npx uifork new Button v5 # explicit ID ``` ### Generated file content example ```tsx import React from 'react'; export default function ButtonV4() { return (
V4
); } ``` ``` -------------------------------- ### Initialize Theme from Local Storage Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/index.html This script initializes the theme of a web page based on the value stored in local storage. It supports 'light', 'dark', and 'system' themes. If 'system' is selected, it checks the user's OS preference. ```javascript (function () { const theme = localStorage.getItem("vite-ui-theme") || "system"; const root = document.documentElement; root.classList.remove("light", "dark"); if (theme === "system") { const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; root.classList.add(systemTheme); } else { root.classList.add(theme); } })(); ``` -------------------------------- ### Promote UIFork Variation Source: https://context7.com/sambernhardt/uifork/llms.txt Use this command to collapse the chosen UI variation back into a single component file after exploration. ```bash npx uifork promote ``` -------------------------------- ### Initialize Component Versioning with Specific Export Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md When a file has multiple exports, specify which one to fork using the --export flag. Use 'default' for default exports. ```bash npx uifork init src/components/Button.tsx --export Button ``` ```bash npx uifork init src/components/Button.tsx --export default ``` -------------------------------- ### npx uifork promote Source: https://context7.com/sambernhardt/uifork/llms.txt Replaces the wrapper `Button.tsx` with the content of the chosen version, then deletes all version files, the versions index, and the wrapper. ```APIDOC ## `npx uifork promote` — Promote a version to main Replaces the wrapper `Button.tsx` with the content of the chosen version, then deletes all version files (`Button.v*.tsx`), the versions index (`Button.versions.ts`), and the wrapper. The component is left as a plain single file, producing a clean diff from the original. ### Usage ```bash npx uifork promote Button v2 # ✅ Replaced Button.tsx with content from v2 # Deleted: Button.v1.tsx, Button.v2.tsx, Button.versions.ts # ✅ Promotion complete! ``` ### Before promotion ``` Button.tsx ← ForkedComponent wrapper Button.versions.ts ← generated index Button.v1.tsx ← original Button.v2.tsx ← chosen winner ``` ### After promotion ``` Button.tsx ← contents of Button.v2.tsx, renamed to "Button" ``` ``` -------------------------------- ### Create a new component version Source: https://github.com/sambernhardt/uifork/blob/main/README.md Creates a new, empty version file for a component. If no version ID is provided, it auto-increments. ```bash npx uifork new Button # auto-increment ``` ```bash npx uifork new Button v3 # explicit id ``` -------------------------------- ### Create New Component Version Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Create a new, empty version file for a component. The version ID can be auto-incremented or specified explicitly. ```bash npx uifork new Button # Auto-increment version number ``` ```bash npx uifork new Button v3 # Specify version explicitly ``` -------------------------------- ### Promote Component Version Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Promotes a specific version to become the main component, removing versioning scaffolding. This replaces the main component file with the selected version's content and deletes all version-specific files. ```bash npx uifork promote Button v2 ``` -------------------------------- ### Fork an existing version with UI Fork CLI Source: https://context7.com/sambernhardt/uifork/llms.txt Use the `fork` or `duplicate` command to create a new version file by copying an existing one. The new version auto-increments unless an explicit target ID is provided. ```bash npx uifork fork Button v1 # copies Button.v1.tsx → Button.v2.tsx (auto-increment) npx uifork fork Button v1 v3 # copies Button.v1.tsx → Button.v3.tsx npx uifork duplicate Button v2 # same as fork ``` -------------------------------- ### npx uifork fork / duplicate Source: https://context7.com/sambernhardt/uifork/llms.txt Creates a new version file by copying an existing one. The new version auto-increments unless an explicit target ID is provided. ```APIDOC ## `npx uifork fork` / `duplicate` — Fork an existing version Creates a new version file by copying an existing one. The new version auto-increments unless an explicit target ID is provided. Alias: `duplicate`. ### Usage ```bash npx uifork fork Button v1 # copies Button.v1.tsx → Button.v2.tsx (auto-increment) npx uifork fork Button v1 v3 # copies Button.v1.tsx → Button.v3.tsx npx uifork duplicate Button v2 # same as fork ``` ``` -------------------------------- ### Run Local Development with HMR Source: https://github.com/sambernhardt/uifork/blob/main/apps/marketing/README.md Use this command for active development of the uifork package with hot module replacement. Changes in the package source are reflected immediately. ```bash npm run dev:local ``` -------------------------------- ### Enable React-Specific ESLint Rules Source: https://github.com/sambernhardt/uifork/blob/main/examples/vite-react/README.md Integrate `eslint-plugin-react-x` and `eslint-plugin-react-dom` for React and React DOM specific linting. Ensure project configuration files are correctly referenced. ```javascript // eslint.config.js import reactX from 'eslint-plugin-react-x' import reactDom from 'eslint-plugin-react-dom' export default defineConfig([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'] extends: [ // Other configs... // Enable lint rules for React reactX.configs['recommended-typescript'], // Enable lint rules for React DOM reactDom.configs.recommended, ], languageOptions: { parserOptions: { project: ['./tsconfig.node.json', './tsconfig.app.json'], tsconfigRootDir: import.meta.dirname, }, // other options... }, }, ]) ``` -------------------------------- ### Open Component Version in Editor Source: https://context7.com/sambernhardt/uifork/llms.txt Opens a specific version of a component in VS Code or Cursor using a POST request to the uifork server. ```bash # Open a version file in VS Code curl -X POST http://localhost:3030/open-in-editor \ -H "Content-Type: application/json" \ -d '{"component": "Button", "version": "v2", "editor": "vscode"}' # { "success": true, "filePath": "/…/Button.v2.tsx" } ``` -------------------------------- ### Use Forked Component Source: https://github.com/sambernhardt/uifork/blob/main/README.md Import and use your forked component as you normally would. UIFork manages the active version internally, so the usage remains consistent. ```tsx // Default export (auto-detected) import Button from "./components/Button"; // Named export (auto-detected) import { Button } from "./components/Button"; // Works exactly as before - the active version is controlled by the UIFork widget ; ``` -------------------------------- ### UIFork Server Endpoints Source: https://context7.com/sambernhardt/uifork/llms.txt The UI Fork server exposes several endpoints for managing and interacting with components. ```APIDOC ## GET /components ### Description Lists all discovered components along with their available versions. ### Method GET ### Endpoint `http://localhost:3030/components` ### Response #### Success Response (200) - **components** (array) - An array of component objects, each containing `name`, `path`, and `versions`. ### Response Example ```json { "components": [ { "name": "Button", "path": "/…/Button.versions.ts", "versions": ["v1","v2","v3"] }, { "name": "ContactCard", "path": "/…/ContactCard.versions.ts", "versions": ["v1","v2"] } ] } ``` ``` ```APIDOC ## POST /open-in-editor ### Description Opens a specified version of a component file in a designated editor (e.g., VS Code, Cursor). ### Method POST ### Endpoint `http://localhost:3030/open-in-editor` ### Parameters #### Request Body - **component** (string) - Required - The name of the component. - **version** (string) - Required - The specific version of the component to open. - **editor** (string) - Required - The editor to use (e.g., "vscode", "cursor"). ### Request Example ```json { "component": "Button", "version": "v2", "editor": "vscode" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **filePath** (string) - The path to the opened file. ### Response Example ```json { "success": true, "filePath": "/…/Button.v2.tsx" } ``` ``` -------------------------------- ### Integrate UIFork with Next.js (Pages Router) Source: https://github.com/sambernhardt/uifork/blob/main/README.md Demonstrates how to include the UIFork component in a Next.js application using the Pages Router, ensuring it's only rendered in non-production environments. ```tsx // pages/_app.tsx import { UIFork } from "uifork"; export default function App({ Component, pageProps }) { return ( <> {process.env.NODE_ENV !== "production" && } ); } ``` -------------------------------- ### Add UIFork Skill via npx Source: https://github.com/sambernhardt/uifork/blob/main/README.md Add the UIFork skill to your project using the npx command. This integrates UIFork with AI agents for enhanced development workflows. ```bash npx skills add sambernhardt/uifork ``` -------------------------------- ### Conditional UIFork Widget Rendering Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Demonstrates how to conditionally render the UIFork widget based on environment variables. This is useful for enabling the widget only in development or specific staging environments. ```tsx // Enable via NEXT_PUBLIC_ENABLE_UIFORK=true or VITE_ENABLE_UIFORK=true const showUIFork = process.env.NODE_ENV !== "production" || process.env.NEXT_PUBLIC_ENABLE_UIFORK === "true"; ``` -------------------------------- ### Integrate UIFork with Next.js (App Router) Source: https://github.com/sambernhardt/uifork/blob/main/README.md Provides a client component to wrap the UIFork component, intended for use within the App Router structure of Next.js. ```tsx // components/UIForkProvider.tsx "use client"; import { UIFork } from "uifork"; export function UIForkProvider() { return ; } // app/layout.tsx — add inside ``` -------------------------------- ### Integrate UIFork with Vite Source: https://github.com/sambernhardt/uifork/blob/main/README.md Shows how to conditionally render the UIFork component in a Vite application, typically excluding it from production builds. ```tsx // src/App.tsx import { UIFork } from "uifork"; const showUIFork = import.meta.env.MODE !== "production"; function App() { return ( <> {showUIFork && } ); } ``` -------------------------------- ### Generated ForkedComponent Wrapper Source: https://context7.com/sambernhardt/uifork/llms.txt This is the structure of the generated `*.tsx` wrapper file after running `npx uifork init`. It uses `ForkedComponent` to manage versions and props. ```tsx "use client" /** * THIS FILE IS GENERATED by uifork. * Edit version files (Button.v1.tsx, Button.v2.tsx …) instead. */ import { ForkedComponent } from "uifork" import { VERSIONS } from "./Button.versions" export default function Button(props: any) { return ( ) } export { VERSIONS } ``` -------------------------------- ### Synchronous Version Switching with ForkedComponent Source: https://context7.com/sambernhardt/uifork/llms.txt Renders a component version synchronously based on a localStorage key. Use this for simple version switching without code-splitting. ```tsx import { ForkedComponent } from "uifork"; import ButtonV1 from "./Button.v1"; import ButtonV2 from "./Button.v2"; import ButtonV3 from "./Button.v3"; // The VERSIONS map — same shape as the generated Button.versions.ts const VERSIONS = { v1: { render: ButtonV1, label: "Original" }, v2: { render: ButtonV2, label: "Rounded" }, v3: { render: ButtonV3, label: "Pill shape" }, }; // Anywhere in your tree — the widget will control which version renders export function Button(props: { onClick: () => void; children: React.ReactNode }) { return ( ); } ``` -------------------------------- ### Add UIFork Component to Next.js App Router Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Set up the UIFork component in a Next.js application using the App Router. Ensure it's conditionally rendered and not included in production builds. ```tsx // components/UIForkProvider.tsx "use client"; import { UIFork } from "uifork"; export function UIForkProvider() { if (process.env.NODE_ENV === "production") return null; return ; } // app/layout.tsx import { UIForkProvider } from "@/components/UIForkProvider"; export default function RootLayout({ children }) { return ( {children} ); } ``` -------------------------------- ### Connect UIFork Component to Watch Server Source: https://github.com/sambernhardt/uifork/blob/main/README.md Configure the UIFork component to connect to a watch server running on a specific port. Ensure the port number matches the one used by the watch server. ```tsx // UIFork component: connect to watch server on port 3002 ``` -------------------------------- ### Fork an existing component version Source: https://github.com/sambernhardt/uifork/blob/main/README.md Creates a new version by duplicating an existing one. You can specify the target version to fork from and optionally a new target version ID. ```bash npx uifork fork Button v1 # auto-increment target ``` ```bash npx uifork fork Button v1 v2 # target v2 ``` -------------------------------- ### Integrate UIFork Widget in React App (Vite) Source: https://context7.com/sambernhardt/uifork/llms.txt Add the UIFork root component to your React application's root. It renders a floating widget for version switching. Gate its display to development environments. ```tsx // src/App.tsx (Vite) import { UIFork } from "uifork"; const showUIFork = import.meta.env.MODE !== "production"; function App() { return ( <> {showUIFork && } ); } ``` -------------------------------- ### Delete a version with UI Fork CLI Source: https://context7.com/sambernhardt/uifork/llms.txt Use the `delete` command to remove a version file. At least one version must remain after deletion. This also updates the Button.versions.ts file. ```bash npx uifork delete Button v3 # deletes Button.v3.tsx, updates Button.versions.ts ``` -------------------------------- ### Fork Existing Component Version Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Create a new component version by forking an existing one. You can specify the target version ID or let it auto-increment. ```bash npx uifork fork Button v1 # Fork v1 to auto-incremented version ``` ```bash npx uifork fork Button v1 v2 # Fork v1 to specific version ``` ```bash npx uifork duplicate Button v1 v2 # Alias for fork ``` -------------------------------- ### npx uifork rename Source: https://context7.com/sambernhardt/uifork/llms.txt Renames a version file and updates all internal component name references within the file. ```APIDOC ## `npx uifork rename` — Rename a version Renames a version file and updates all internal component name references within the file. ### Usage ```bash npx uifork rename Button v2 v3 # renames Button.v2.tsx → Button.v3.tsx # and updates "ButtonV2" → "ButtonV3" inside the file ``` ``` -------------------------------- ### npx uifork delete Source: https://context7.com/sambernhardt/uifork/llms.txt Deletes a version file. At least one version must remain. ```APIDOC ## `npx uifork delete` — Delete a version Deletes a version file. At least one version must remain. ### Usage ```bash npx uifork delete Button v3 # deletes Button.v3.tsx, updates Button.versions.ts ``` ``` -------------------------------- ### Rename a version with UI Fork CLI Source: https://context7.com/sambernhardt/uifork/llms.txt Use the `rename` command to rename a version file and update all internal component name references within the file. This command renames the file and modifies the component name inside. ```bash npx uifork rename Button v2 v3 # renames Button.v2.tsx → Button.v3.tsx # and updates "ButtonV2" → "ButtonV3" inside the file ``` -------------------------------- ### Enable Type-Aware ESLint Rules Source: https://github.com/sambernhardt/uifork/blob/main/examples/vite-react/README.md Configure ESLint to use type-aware lint rules for TypeScript files. Ensure `tsconfig.node.json` and `tsconfig.app.json` are correctly specified. ```javascript export default defineConfig([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'] extends: [ // Other configs... // Remove tseslint.configs.recommended and replace with this tseslint.configs.recommendedTypeChecked, // Alternatively, use this for stricter rules tseslint.configs.strictTypeChecked, // Optionally, add this for stylistic rules tseslint.configs.stylisticTypeChecked, // Other configs... ], languageOptions: { parserOptions: { project: ['./tsconfig.node.json', './tsconfig.app.json'], tsconfigRootDir: import.meta.dirname, }, // other options... }, }, ]) ``` -------------------------------- ### Use Forked Component in React Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Import and use your versioned component as you normally would. The active version is controlled by the UIFork widget. ```tsx // Default export (auto-detected) import Button from "./components/Button"; // Named export (auto-detected) import { Button } from "./components/Button"; // Works exactly as before - active version controlled by UIFork widget ; ``` -------------------------------- ### useLocalStorage Source: https://context7.com/sambernhardt/uifork/llms.txt A custom React hook for managing state persisted in localStorage with optional cross-tab synchronization. ```APIDOC ## useLocalStorage ### Description A typed `useState` replacement hook that reads and writes to `localStorage`. It can optionally synchronize state changes across browser tabs using the `storage` event. ### Signature ```ts function useLocalStorage( key: string, initialValue: T, syncAcrossTabs?: boolean, // default: false ): [T, (value: T | ((prev: T) => T)) => void] ``` ### Usage Example ```tsx import { useLocalStorage } from "uifork"; function ThemeSelector() { const [theme, setTheme] = useLocalStorage<"light" | "dark" | "system"> ("app-theme", "system", true); return ( ); } function ResetButton() { const [, setTheme] = useLocalStorage("app-theme", "system"); return ; } ``` Setting an empty string for the value removes the key from `localStorage`. ``` -------------------------------- ### Add UIFork Component to Vite App Source: https://github.com/sambernhardt/uifork/blob/main/skills/uifork/SKILL.md Integrate the UIFork component into your Vite application's root. It's typically shown only in development and preview/staging environments, not production. ```tsx import { UIFork } from "uifork"; const showUIFork = import.meta.env.MODE !== "production"; function App() { return ( <> {showUIFork && } ); } ``` -------------------------------- ### Rename a component version Source: https://github.com/sambernhardt/uifork/blob/main/README.md Renames an existing version of a component. ```bash npx uifork rename Button v1 v2 ``` -------------------------------- ### Integrate UIFork Widget in Next.js App Router Source: https://context7.com/sambernhardt/uifork/llms.txt For Next.js App Router, use a client component to render the UIFork widget. You can specify a custom watch server port if needed. ```tsx // Next.js App Router — needs "use client" // components/UIForkProvider.tsx "use client"; import { UIFork } from "uifork"; export function UIForkProvider() { // Connect to a custom watch-server port (default is 3030) return ; } // app/layout.tsx import { UIForkProvider } from "@/components/UIForkProvider"; export default function RootLayout({ children }) { return ( {children} ); } ``` -------------------------------- ### Add UIFork to React Application Source: https://github.com/sambernhardt/uifork/blob/main/README.md Integrate the UIFork component into your React application. It's recommended to add it at the root level, conditionally rendering it only in non-production environments. ```tsx import { UIFork } from "uifork"; const showUIFork = process.env.NODE_ENV !== "production"; function App() { return ( <> {showUIFork && } ); } ``` -------------------------------- ### WebSocket Protocol - Client to Server Messages Source: https://context7.com/sambernhardt/uifork/llms.txt Messages sent from the client to the UI Fork watch server to manage component versions. ```APIDOC ## WebSocket protocol — watch server messages The widget communicates with the watch server via a WebSocket connection. All messages are JSON with `{ type, payload }` shape. ### Client → Server messages #### Duplicate a version ```json { type: "duplicate_version", payload: { component: "Button", version: "v1", newVersion?: "v3" } } ``` #### Delete a version ```json { type: "delete_version", payload: { component: "Button", version: "v2" } } ``` #### Create a blank version ```json { type: "new_version", payload: { component: "Button", version?: "v4" } } ``` #### Rename a version file ```json { type: "rename_version", payload: { component: "Button", version: "v2", newVersion: "v3" } } ``` #### Update the display label (persisted in versions.ts) ```json { type: "rename_label", payload: { component: "Button", version: "v2", newLabel: "Rounded corners" } } ``` #### Promote a version to main ```json { type: "promote_version", payload: { component: "Button", version: "v2" } } ``` #### Run an AI edit via Claude Code or Cursor ```json { type: "prompt_version", payload: { component: "Button", sourceVersion: "v1", prompt: "Make the button pill-shaped with a gradient background", aiEditingTool: "claude-code", // "claude-code" | "cursor" forkFirst: true, // fork v1 → v2 before editing } } ``` ``` -------------------------------- ### WebSocket Protocol - Server to Client Messages Source: https://context7.com/sambernhardt/uifork/llms.txt Messages sent from the UI Fork watch server to the client, providing status updates and data. ```APIDOC ### Server → Client messages #### Initial connection ack ```json { type: "ack", payload: { message: "Connected to uifork watch server" } } ``` #### Full component list (sent on connect and after every change) ```json { type: "components", payload: { components: [{ name: "Button", path: "…", versions: ["v1", "v2"] }], activePrompts: ["Button:v2"] } } ``` #### File change notification ```json { type: "file_changed", payload: { message: "Versions file updated", component: "Button" } } ``` #### AI edit lifecycle ```json { type: "prompt_started", payload: { component: "Button", version: "v2", message: "…" } } { type: "prompt_completed", payload: { component: "Button", version: "v2", message: "…" } } { type: "prompt_failed", payload: { component: "Button", version: "v2", message: "error" } } ``` #### Operation acknowledgement (all CRUD ops) ```json { type: "ack", payload: { message: "Successfully duplicated v1 → v2", version: "v2" } } ``` #### Error ```json { type: "error", payload: { message: "Version file not found: v9" } } ``` ``` -------------------------------- ### Code-Split Version Switching with LazyForkedComponent Source: https://context7.com/sambernhardt/uifork/llms.txt Provides a drop-in replacement for ForkedComponent that uses React.lazy() and Suspense for code-splitting. Ideal for large version files to enable on-demand loading. ```tsx import { lazy } from "react"; import { LazyForkedComponent } from "uifork"; // Lazy-loaded version map — pass dynamic imports instead of static imports const VERSIONS = { v1: { render: () => import("./HeavyChart.v1"), // loaded only when v1 is active label: "Bar chart", }, v2: { render: () => import("./HeavyChart.v2"), // loaded only when v2 is active label: "Line chart", }, }; export function HeavyChart(props: { data: number[] }) { return ( ); } ``` -------------------------------- ### WebSocket Client → Server Messages for UI Fork Source: https://context7.com/sambernhardt/uifork/llms.txt These JSON messages are sent from the client to the UI Fork watch server to perform version management operations. They include types for duplicating, deleting, creating, renaming, updating labels, promoting versions, and running AI edits. ```json { type: "duplicate_version", payload: { component: "Button", version: "v1", newVersion?: "v3" } } ``` ```json { type: "delete_version", payload: { component: "Button", version: "v2" } } ``` ```json { type: "new_version", payload: { component: "Button", version?: "v4" } } ``` ```json { type: "rename_version", payload: { component: "Button", version: "v2", newVersion: "v3" } } ``` ```json { type: "rename_label", payload: { component: "Button", version: "v2", newLabel: "Rounded corners" } } ``` ```json { type: "promote_version", payload: { component: "Button", version: "v2" } } ``` ```json { type: "prompt_version", payload: { component: "Button", sourceVersion: "v1", prompt: "Make the button pill-shaped with a gradient background", aiEditingTool: "claude-code", // "claude-code" | "cursor" forkFirst: true, // fork v1 → v2 before editing } } ``` -------------------------------- ### Delete a component version Source: https://github.com/sambernhardt/uifork/blob/main/README.md Deletes a specified version of a component. At least one version must remain after deletion. ```bash npx uifork delete Button v2 ``` -------------------------------- ### WebSocket Server → Client Messages for UI Fork Source: https://context7.com/sambernhardt/uifork/llms.txt These JSON messages are sent from the UI Fork watch server to the client, providing status updates and notifications. They include acknowledgements, component lists, file change notifications, AI edit lifecycle events, and error messages. ```json { type: "ack", payload: { message: "Connected to uifork watch server" } } ``` ```json { type: "components", payload: { components: [{ name: "Button", path: "…", versions: ["v1", "v2"] }], activePrompts: ["Button:v2"] } } ``` ```json { type: "file_changed", payload: { message: "Versions file updated", component: "Button" } } ``` ```json { type: "prompt_started", payload: { component: "Button", version: "v2", message: "…" } } ``` ```json { type: "prompt_completed", payload: { component: "Button", version: "v2", message: "…" } } ``` ```json { type: "prompt_failed", payload: { component: "Button", version: "v2", message: "error" } } ``` ```json { type: "ack", payload: { message: "Successfully duplicated v1 → v2", version: "v2" } } ``` ```json { type: "error", payload: { message: "Version file not found: v9" } } ``` -------------------------------- ### Persistent State Hook with useLocalStorage Source: https://context7.com/sambernhardt/uifork/llms.txt A typed useState replacement that persists state to localStorage and optionally synchronizes it across browser tabs using the storage event. ```tsx import { useLocalStorage } from "uifork"; function ThemeSelector() { // Persists "light" | "dark" | "system" in localStorage under the key "app-theme" const [theme, setTheme] = useLocalStorage<"light" | "dark" | "system"> ( "app-theme", "system", true, // syncAcrossTabs: changing the value in one tab updates all open tabs ); return ( ); } // Setting an empty string removes the key from localStorage entirely function ResetButton() { const [, setTheme] = useLocalStorage("app-theme", "system"); return ; } ``` ```ts function useLocalStorage( key: string, initialValue: T, syncAcrossTabs?: boolean, // default: false ): [T, (value: T | ((prev: T) => T)) => void] ``` -------------------------------- ### ForkedComponent Source: https://context7.com/sambernhardt/uifork/llms.txt A low-level React component that synchronously switches between component versions based on localStorage. ```APIDOC ## ForkedComponent ### Description Synchronously switches between component versions based on a unique ID and localStorage. It reads the active version from `localStorage` and renders the corresponding component. ### Props | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | ✓ | Unique component identifier (used as localStorage key) | | `versions` | `VersionsType` | ✓ | Map of version key → `{ render, label?, description? }` | | `props` | `object` | ✓ | Props passed through to the active version component | | `defaultVersion` | `string` | — | Version key to use when no localStorage entry exists | ### Usage Example ```tsx import { ForkedComponent } from "uifork"; const VERSIONS = { v1: { render: ButtonV1, label: "Original" }, v2: { render: ButtonV2, label: "Rounded" }, v3: { render: ButtonV3, label: "Pill shape" }, }; export function Button(props: { onClick: () => void; children: React.ReactNode }) { return ( ); } ``` ``` -------------------------------- ### LazyForkedComponent Source: https://context7.com/sambernhardt/uifork/llms.txt A code-splitting React component that lazily loads component versions. ```APIDOC ## LazyForkedComponent ### Description A drop-in replacement for `ForkedComponent` that uses `React.lazy()` and `` for code-splitting. It loads version files on demand, improving initial load times. ### Usage Example ```tsx import { lazy } from "react"; import { LazyForkedComponent } from "uifork"; const VERSIONS = { v1: { render: () => import("./HeavyChart.v1"), label: "Bar chart", }, v2: { render: () => import("./HeavyChart.v2"), label: "Line chart", }, }; export function HeavyChart(props: { data: number[] }) { return ( ); } ``` The component renders `null` until the lazy module loads and then re-renders with the correct version. Switching versions triggers a new lazy load for the incoming version on first activation. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.