├── .eslintrc.cjs ├── .gitignore ├── LICENSE ├── README.md ├── components.json ├── index.html ├── jsconfig.json ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── public ├── ligtning.svg └── vite.svg ├── src ├── App.css ├── App.jsx ├── ArtifactCode.jsx ├── assets │ └── react.svg ├── components │ └── ui │ │ ├── accordion.jsx │ │ ├── alert-dialog.jsx │ │ ├── alert.jsx │ │ ├── aspect-ratio.jsx │ │ ├── avatar.jsx │ │ ├── badge.jsx │ │ ├── breadcrumb.jsx │ │ ├── button.jsx │ │ ├── calendar.jsx │ │ ├── card.jsx │ │ ├── carousel.jsx │ │ ├── checkbox.jsx │ │ ├── collapsible.jsx │ │ ├── command.jsx │ │ ├── context-menu.jsx │ │ ├── dialog.jsx │ │ ├── drawer.jsx │ │ ├── dropdown-menu.jsx │ │ ├── form.jsx │ │ ├── hover-card.jsx │ │ ├── input-otp.jsx │ │ ├── input.jsx │ │ ├── label.jsx │ │ ├── menubar.jsx │ │ ├── navigation-menu.jsx │ │ ├── pagination.jsx │ │ ├── popover.jsx │ │ ├── progress.jsx │ │ ├── radio-group.jsx │ │ ├── resizable.jsx │ │ ├── scroll-area.jsx │ │ ├── select.jsx │ │ ├── separator.jsx │ │ ├── sheet.jsx │ │ ├── skeleton.jsx │ │ ├── slider.jsx │ │ ├── sonner.jsx │ │ ├── switch.jsx │ │ ├── table.jsx │ │ ├── tabs.jsx │ │ ├── textarea.jsx │ │ ├── toast.jsx │ │ ├── toaster.jsx │ │ ├── toggle-group.jsx │ │ ├── toggle.jsx │ │ ├── tooltip.jsx │ │ └── use-toast.js ├── index.css ├── lib │ └── utils.js └── main.jsx ├── tailwind.config.js └── vite.config.js /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | "eslint:recommended", 6 | "plugin:react/recommended", 7 | "plugin:react/jsx-runtime", 8 | "plugin:react-hooks/recommended", 9 | ], 10 | ignorePatterns: ["dist", ".eslintrc.cjs"], 11 | parserOptions: { ecmaVersion: "latest", sourceType: "module" }, 12 | settings: { react: { version: "18.2" } }, 13 | plugins: ["react-refresh"], 14 | rules: { 15 | "react/jsx-no-target-blank": "off", 16 | "react-refresh/only-export-components": [ 17 | "warn", 18 | { allowConstantExport: true }, 19 | ], 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Rison Simon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Claude Artifacts React - Deploy Claude Artifact code easily 2 | 3 | Claude Artifacts React is an open-source tool that simplifies the process of deploying React code snippets to Vercel or Cloudflare Pages. This project allows you to quickly test and share React code generated by Claude Artifacts without the need for complex setup or configuration. 4 | 5 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Frisonsimon%2Fclaude-artifacts-react) 6 | [![Deploy to Cloudflare Pages](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/risonsimon/claude-artifacts-react) 7 | 8 | ## Quick Start 9 | 10 | 1. Click on either the "Deploy with Vercel" or "Deploy to Cloudflare Pages" button above. 11 | 2. This will fork the repository to your account and start the deployment process. 12 | 3. Once deployed, you can edit the `src/ArtifactCode.jsx` file in your forked repository with the React code output from Claude. 13 | 4. Commit your changes, and your deployment will automatically update with the new code. 14 | 15 | ## Features 16 | 17 | - One-click deployment to Vercel or Cloudflare Pages 18 | - Easy editing of React code through `ArtifactCode.jsx` 19 | - Supports React code snippets and components from Claude 20 | - Minimal configuration required 21 | - All dependencies of Claude artifacts are already installed 22 | - Ideal for prototyping, sharing code examples, or quickly testing ideas 23 | 24 | ## Editing Your Code 25 | 26 | After deploying, follow these steps to update your React code: 27 | 28 | 1. Navigate to the `ArtifactCode.jsx` file in your forked repository. 29 | 2. Click on the edit button (pencil icon). 30 | 3. Paste the React code output from Claude into this file. 31 | 4. Commit your changes. 32 | 5. Your deployment will automatically update with the new code. 33 | 34 | ## Manual Setup 35 | 36 | If you prefer to set up the project manually: 37 | 38 | 1. Clone the repository: 39 | 40 | ``` 41 | git clone https://github.com/risonsimon/claude-artifacts-react.git 42 | cd claude-artifacts-react 43 | ``` 44 | 45 | 2. Install dependencies: 46 | 47 | ``` 48 | pnpm install 49 | ``` 50 | 51 | 3. Edit the `ArtifactCode.tsx` file with your React code. 52 | 53 | 4. Deploy to your preferred platform. 54 | 55 | ## License 56 | 57 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 58 | 59 | ## Support 60 | 61 | If you encounter any issues or have questions, please file an issue on the GitHub repository. 62 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": false, 5 | "tsx": false, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/index.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 14 | Claude Artifacts React 15 | 16 | 17 |
18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "claude-artifacts-react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@hookform/resolvers": "^3.6.0", 14 | "@radix-ui/react-accordion": "^1.2.0", 15 | "@radix-ui/react-alert-dialog": "^1.1.1", 16 | "@radix-ui/react-aspect-ratio": "^1.1.0", 17 | "@radix-ui/react-avatar": "^1.1.0", 18 | "@radix-ui/react-checkbox": "^1.1.1", 19 | "@radix-ui/react-collapsible": "^1.1.0", 20 | "@radix-ui/react-context-menu": "^2.2.1", 21 | "@radix-ui/react-dialog": "^1.1.1", 22 | "@radix-ui/react-dropdown-menu": "^2.1.1", 23 | "@radix-ui/react-hover-card": "^1.1.1", 24 | "@radix-ui/react-label": "^2.1.0", 25 | "@radix-ui/react-menubar": "^1.1.1", 26 | "@radix-ui/react-navigation-menu": "^1.2.0", 27 | "@radix-ui/react-popover": "^1.1.1", 28 | "@radix-ui/react-progress": "^1.1.0", 29 | "@radix-ui/react-radio-group": "^1.2.0", 30 | "@radix-ui/react-scroll-area": "^1.1.0", 31 | "@radix-ui/react-select": "^2.1.1", 32 | "@radix-ui/react-separator": "^1.1.0", 33 | "@radix-ui/react-slider": "^1.2.0", 34 | "@radix-ui/react-slot": "^1.1.0", 35 | "@radix-ui/react-switch": "^1.1.0", 36 | "@radix-ui/react-tabs": "^1.1.0", 37 | "@radix-ui/react-toast": "^1.2.1", 38 | "@radix-ui/react-toggle": "^1.1.0", 39 | "@radix-ui/react-toggle-group": "^1.1.0", 40 | "@radix-ui/react-tooltip": "^1.1.2", 41 | "class-variance-authority": "^0.7.0", 42 | "clsx": "^2.1.1", 43 | "cmdk": "^1.0.0", 44 | "date-fns": "^3.6.0", 45 | "embla-carousel-react": "^8.1.6", 46 | "input-otp": "^1.2.4", 47 | "lucide-react": "^0.400.0", 48 | "next-themes": "^0.3.0", 49 | "react": "^18.3.1", 50 | "react-day-picker": "^8.10.1", 51 | "react-dom": "^18.3.1", 52 | "react-hook-form": "^7.52.1", 53 | "react-resizable-panels": "^2.0.19", 54 | "recharts": "^2.12.7", 55 | "sonner": "^1.5.0", 56 | "tailwind-merge": "^2.3.0", 57 | "tailwindcss-animate": "^1.0.7", 58 | "vaul": "^0.9.1", 59 | "zod": "^3.23.8" 60 | }, 61 | "devDependencies": { 62 | "@types/react": "^18.3.3", 63 | "@types/react-dom": "^18.3.0", 64 | "@vitejs/plugin-react": "^4.3.1", 65 | "autoprefixer": "^10.4.19", 66 | "eslint": "^8.57.0", 67 | "eslint-plugin-react": "^7.34.2", 68 | "eslint-plugin-react-hooks": "^4.6.2", 69 | "eslint-plugin-react-refresh": "^0.4.7", 70 | "postcss": "^8.4.39", 71 | "tailwindcss": "^3.4.4", 72 | "vite": "^5.3.1" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/ligtning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import ArtifactCode from "./ArtifactCode"; 3 | 4 | function App() { 5 | return ( 6 | <> 7 | 8 | 9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /src/ArtifactCode.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Button } from "@/components/ui/button"; 3 | 4 | const App = () => { 5 | const [count, setCount] = useState(0); 6 | 7 | const handleClick = () => { 8 | setCount(count + 1); 9 | }; 10 | 11 | return ( 12 |
13 |
14 |

Claude Artifacts React

15 | 21 |

Said Hi {count} times

22 |
23 |
24 | ); 25 | }; 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/ui/accordion.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as AccordionPrimitive from "@radix-ui/react-accordion" 3 | import { ChevronDown } from "lucide-react" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const Accordion = AccordionPrimitive.Root 8 | 9 | const AccordionItem = React.forwardRef(({ className, ...props }, ref) => ( 10 | 11 | )) 12 | AccordionItem.displayName = "AccordionItem" 13 | 14 | const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => ( 15 | 16 | svg]:rotate-180", 20 | className 21 | )} 22 | {...props}> 23 | {children} 24 | 25 | 26 | 27 | )) 28 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName 29 | 30 | const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => ( 31 | 35 |
{children}
36 |
37 | )) 38 | 39 | AccordionContent.displayName = AccordionPrimitive.Content.displayName 40 | 41 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } 42 | -------------------------------------------------------------------------------- /src/components/ui/alert-dialog.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" 3 | 4 | import { cn } from "@/lib/utils" 5 | import { buttonVariants } from "@/components/ui/button" 6 | 7 | const AlertDialog = AlertDialogPrimitive.Root 8 | 9 | const AlertDialogTrigger = AlertDialogPrimitive.Trigger 10 | 11 | const AlertDialogPortal = AlertDialogPrimitive.Portal 12 | 13 | const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => ( 14 | 21 | )) 22 | AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName 23 | 24 | const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => ( 25 | 26 | 27 | 34 | 35 | )) 36 | AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName 37 | 38 | const AlertDialogHeader = ({ 39 | className, 40 | ...props 41 | }) => ( 42 |
45 | ) 46 | AlertDialogHeader.displayName = "AlertDialogHeader" 47 | 48 | const AlertDialogFooter = ({ 49 | className, 50 | ...props 51 | }) => ( 52 |
55 | ) 56 | AlertDialogFooter.displayName = "AlertDialogFooter" 57 | 58 | const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => ( 59 | 60 | )) 61 | AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName 62 | 63 | const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => ( 64 | 68 | )) 69 | AlertDialogDescription.displayName = 70 | AlertDialogPrimitive.Description.displayName 71 | 72 | const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => ( 73 | 74 | )) 75 | AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName 76 | 77 | const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => ( 78 | 82 | )) 83 | AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName 84 | 85 | export { 86 | AlertDialog, 87 | AlertDialogPortal, 88 | AlertDialogOverlay, 89 | AlertDialogTrigger, 90 | AlertDialogContent, 91 | AlertDialogHeader, 92 | AlertDialogFooter, 93 | AlertDialogTitle, 94 | AlertDialogDescription, 95 | AlertDialogAction, 96 | AlertDialogCancel, 97 | } 98 | -------------------------------------------------------------------------------- /src/components/ui/alert.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva } from "class-variance-authority"; 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const alertVariants = cva( 7 | "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", 8 | { 9 | variants: { 10 | variant: { 11 | default: "bg-background text-foreground", 12 | destructive: 13 | "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", 14 | }, 15 | }, 16 | defaultVariants: { 17 | variant: "default", 18 | }, 19 | } 20 | ) 21 | 22 | const Alert = React.forwardRef(({ className, variant, ...props }, ref) => ( 23 |
28 | )) 29 | Alert.displayName = "Alert" 30 | 31 | const AlertTitle = React.forwardRef(({ className, ...props }, ref) => ( 32 |
36 | )) 37 | AlertTitle.displayName = "AlertTitle" 38 | 39 | const AlertDescription = React.forwardRef(({ className, ...props }, ref) => ( 40 |
44 | )) 45 | AlertDescription.displayName = "AlertDescription" 46 | 47 | export { Alert, AlertTitle, AlertDescription } 48 | -------------------------------------------------------------------------------- /src/components/ui/aspect-ratio.jsx: -------------------------------------------------------------------------------- 1 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 2 | 3 | const AspectRatio = AspectRatioPrimitive.Root 4 | 5 | export { AspectRatio } 6 | -------------------------------------------------------------------------------- /src/components/ui/avatar.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as AvatarPrimitive from "@radix-ui/react-avatar" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const Avatar = React.forwardRef(({ className, ...props }, ref) => ( 7 | 11 | )) 12 | Avatar.displayName = AvatarPrimitive.Root.displayName 13 | 14 | const AvatarImage = React.forwardRef(({ className, ...props }, ref) => ( 15 | 19 | )) 20 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 21 | 22 | const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => ( 23 | 30 | )) 31 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 32 | 33 | export { Avatar, AvatarImage, AvatarFallback } 34 | -------------------------------------------------------------------------------- /src/components/ui/badge.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva } from "class-variance-authority"; 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ) 25 | 26 | function Badge({ 27 | className, 28 | variant, 29 | ...props 30 | }) { 31 | return (
); 32 | } 33 | 34 | export { Badge, badgeVariants } 35 | -------------------------------------------------------------------------------- /src/components/ui/breadcrumb.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { ChevronRight, MoreHorizontal } from "lucide-react" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const Breadcrumb = React.forwardRef( 8 | ({ ...props }, ref) =>